diff --git a/packages/opendesign/src/anchor/OAnchorItem.vue b/packages/opendesign/src/anchor/OAnchorItem.vue
index 2e91f7912bddf152596b70d1f408e3126137d9f3..c069fb20885bdb074570cbb54ce3f93065cefbb5 100644
--- a/packages/opendesign/src/anchor/OAnchorItem.vue
+++ b/packages/opendesign/src/anchor/OAnchorItem.vue
@@ -1,9 +1,23 @@
-
-
- {{ props.title }}
-
+
diff --git a/packages/opendesign/src/anchor/__demo__/AnchorBasic.vue b/packages/opendesign/src/anchor/__demo__/AnchorBasic.vue
index b6759a68c92dd9ae05e07a3a828d56e4a0079c9f..c08f01d9c41194f85c27c492e4ade61140244e3e 100644
--- a/packages/opendesign/src/anchor/__demo__/AnchorBasic.vue
+++ b/packages/opendesign/src/anchor/__demo__/AnchorBasic.vue
@@ -10,17 +10,46 @@ import { OAnchor, OAnchorItem } from '../index';
block2
block3
block3-1
+
block3-2
block4
-
-
-
-
-
-
-
-
+
+
medium:
+
+
+
+
+
+
+
+
+
+
+
+
small:
+
+
+
+
+
+
+
+
+
+
+
+
menu:
+
+
+
+
+
+
+
+
+
+
@@ -51,5 +80,6 @@ import { OAnchor, OAnchorItem } from '../index';
position: fixed;
top: 200px;
right: 60px;
+ display: flex;
}
diff --git a/packages/opendesign/src/anchor/provide.ts b/packages/opendesign/src/anchor/provide.ts
index 10a0eccb0b46a357522bd72af00d42f020594f22..ad455de9af626dbeed09df13dc89a16f9bb16d4a 100644
--- a/packages/opendesign/src/anchor/provide.ts
+++ b/packages/opendesign/src/anchor/provide.ts
@@ -3,8 +3,13 @@ import { InjectionKey, Ref } from 'vue';
export const anchorInjectKey: InjectionKey<{
addLink: (link: string) => void;
removeLink: (link: string) => void;
- handleClick: (ev: MouseEvent, link?: string) => void;
+ /**
+ * @deprecated 兼容旧版本,计划1.2.0移除
+ */
+ onItemClick: (options: { event: MouseEvent; link?: string }) => void;
activeLink: Ref
;
+ scrollIntoView: (link: string) => void;
+ getChangeHash: () => boolean;
}> = Symbol('provide-anchor');
export const anchorItemInjectKey: InjectionKey<{
diff --git a/packages/opendesign/src/anchor/style/index.scss b/packages/opendesign/src/anchor/style/index.scss
index 504d59c44eea7243e3faa4e454b7675ea8b98768..8bb47c5840ef5591b0176e882570a9878c439b64 100644
--- a/packages/opendesign/src/anchor/style/index.scss
+++ b/packages/opendesign/src/anchor/style/index.scss
@@ -1,2 +1,3 @@
@use './style.scss' as *;
+@use './var.scss' as *;
@use './media.scss' as *;
diff --git a/packages/opendesign/src/anchor/style/media.scss b/packages/opendesign/src/anchor/style/media.scss
index f415089a72379f537e904f06a5668e095fa1b0f7..d2af976972e4f83ab97cbf556a5d2cbb402a0c66 100644
--- a/packages/opendesign/src/anchor/style/media.scss
+++ b/packages/opendesign/src/anchor/style/media.scss
@@ -1,8 +1,25 @@
@use '../../_styles/mixin.scss' as *;
-@include respond-to('<=laptop') {
- .o-anchor-item {
- --anchor-item-link-text-size: var(--o-font_size-tip1);
- --anchor-item-link-text-height: var(--o-line_height-tip1);
+@include respond-to('<=pc_s') {
+ .o-anchor:not(.o-anchor-menu) {
+ .o-anchor-item {
+ --anchor-item-link-text-size: var(--o-font_size-tip1);
+ --anchor-item-link-text-height: var(--o-line_height-tip1);
+
+ --anchor-item-sub-link-text-size: var(--o-font_size-tip2);
+ --anchor-item-sub-link-text-height: var(--o-line_height-tip2);
+
+ --anchor-item-link-padding-v: 5px;
+ --anchor-item-sub-link-padding-v: 5px;
+ }
}
}
+
+@include respond-to('<=pad_v') {
+ .o-anchor-menu {
+ .o-anchor-item {
+ --anchor-item-sub-link-text-size: var(--o-font_size-tip2);
+ --anchor-item-sub-link-text-height: var(--o-line_height-tip2);
+ }
+ }
+}
\ No newline at end of file
diff --git a/packages/opendesign/src/anchor/style/style.scss b/packages/opendesign/src/anchor/style/style.scss
index daf4883e26556eaf42cef987e415e9acac5fb7c8..3b61f21e76d2fbd6e52b8db26e10788d64b8bdfc 100644
--- a/packages/opendesign/src/anchor/style/style.scss
+++ b/packages/opendesign/src/anchor/style/style.scss
@@ -1,5 +1,4 @@
@use '../../_styles/mixin.scss' as *;
-@use './var.scss';
.o-anchor {
position: relative;
@@ -8,11 +7,12 @@
}
.o-anchor-line {
+ flex-shrink: 0;
position: relative;
width: var(--anchor-line-width);
border-radius: var(--anchor-line-width);
- background-color: var(--anchor-line-bg-color);
- margin-right: 4px;
+ margin-right: var(--anchor-line-gap);
+ margin-left: calc(var(--anchor-circle-size) / 2);
}
.o-anchor-indicator {
@@ -22,7 +22,7 @@
width: var(--anchor-indicator-width);
background-color: transparent;
opacity: 0;
- transition: all var(--o-easing-standard-in) var(--o-duration-m1);
+ transition: top var(--o-easing-standard-in) var(--o-duration-m1);
&::after {
content: '';
@@ -39,36 +39,121 @@
}
.o-anchor-item-link {
+ --anchor-item-link-left-extra-indent: calc(var(--anchor-item-text-indent) * var(--anchor-item-depth));
+ --anchor-circle-top: calc(
+ var(--anchor-item-link-padding-v) + var(--anchor-item-link-text-height) / 2 - var(--anchor-circle-size) / 2 + var(--anchor-indicator-adjust)
+ );
cursor: pointer;
display: inline-flex;
- color: inherit;
text-decoration: none;
width: 100%;
- color: var(--anchor-item-link-color);
+ color: var(--anchor-item-link-color, inherit);
font-size: var(--anchor-item-link-text-size);
line-height: var(--anchor-item-link-text-height);
- background-color: var(--anchor-item-link-bg-color);
- padding: var(--anchor-item-link-padding);
+ padding: var(--anchor-item-link-padding-v) var(--anchor-item-link-padding-h);
+ padding-left: calc(var(--anchor-item-link-left-extra-indent) + var(--anchor-item-link-padding-h));
border-radius: var(--anchor-item-link-radius);
transition: background-color var(--o-duration-s) var(--o-easing-standard);
+ word-break: break-word;
+ position: relative;
@include hover {
- background-color: var(--anchor-item-link-bg-color-hover);
+ color: var(--anchor-item-link-color-hover);
+ }
+
+ &:active {
+ color: var(--anchor-item-link-color-press);
}
- &.is-active {
- font-weight: 500;
+ &.disabled {
+ color: var(--anchor-item-link-color-disabled);
+ @include hover {
+ cursor: not-allowed;
+ }
+ }
+}
+
+.o-anchor-item:has(.o-anchor-item-link.is-active) > .o-anchor-item-link,
+.o-anchor-item-link.is-active {
+ &:not(.disabled) {
+ font-weight: 600;
color: var(--anchor-item-link-color-active);
- background-color: var(--anchor-item-link-bg-color-active);
}
}
-.o-anchor-item + .o-anchor-item {
- margin-top: var(--anchor-item-link-gap);
+.o-anchor-item-title {
+ max-height: calc(var(--anchor-item-max-row) * var(--anchor-item-link-text-height));
+ overflow: hidden;
+ text-overflow: ellipsis;
+ display: -webkit-box;
+ -webkit-box-orient: vertical;
+ -webkit-line-clamp: var(--anchor-item-max-row);
}
-.o-anchor-item {
- .o-anchor-item {
- margin-top: var(--anchor-item-link-gap);
+.o-anchor-item-sub-link {
+ font-size: var(--anchor-item-sub-link-text-size);
+ line-height: var(--anchor-item-sub-link-text-height);
+ padding-top: var(--anchor-item-sub-link-padding-v);
+ padding-bottom: var(--anchor-item-sub-link-padding-v);
+}
+
+.o-anchor-item-lines {
+ width: var(--anchor-line-width);
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ left: calc(0px - var(--anchor-line-gap) - var(--anchor-line-width));
+}
+
+.o-anchor-item-top-line,
+.o-anchor-item-bottom-line {
+ background-color: var(--anchor-line-bg-color);
+ position: absolute;
+ left: 0;
+ right: 0;
+}
+
+.o-anchor-item-top-line {
+ top: 0;
+ bottom: 50%;
+}
+
+.o-anchor-item-bottom-line {
+ top: 50%;
+ bottom: 0;
+}
+
+.o-anchor-item-link:not(.o-anchor-item-sub-link) {
+ > .o-anchor-item-lines {
+ .o-anchor-item-circle {
+ position: absolute;
+ height: var(--anchor-circle-size);
+ width: var(--anchor-circle-size);
+ top: var(--anchor-circle-top);
+ left: 50%;
+ transform: translateX(-50%);
+ border: var(--anchor-circle-ring-width) solid currentColor;
+ border-radius: 50%;
+ }
+ .o-anchor-item-top-line {
+ bottom: unset;
+ height: calc(var(--anchor-circle-top) - var(--anchor-circle-gap));
+ }
+ .o-anchor-item-bottom-line {
+ top: calc(var(--anchor-circle-top) + var(--anchor-circle-size) + var(--anchor-circle-gap));
+ }
+ }
+}
+
+.o-anchor-items > .o-anchor-item {
+ &:first-child > .o-anchor-item-link .o-anchor-item-top-line {
+ display: none;
}
+ &:last-child:not(.with-children) > .o-anchor-item-link .o-anchor-item-bottom-line {
+ display: none;
+ }
+}
+
+.o-anchor-link-popover-wrapper {
+ max-width: var(--anchor-popover-max-width);
}
diff --git a/packages/opendesign/src/anchor/style/theme-ascend.index.ts b/packages/opendesign/src/anchor/style/theme-ascend.index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..b0049a088358468a6b9185cfea3d656b4f1faaf9
--- /dev/null
+++ b/packages/opendesign/src/anchor/style/theme-ascend.index.ts
@@ -0,0 +1,4 @@
+import '../../_styles';
+import '../../select/style/theme-ascend.index';
+import './index.scss';
+import './theme-ascend.scss';
diff --git a/packages/opendesign/src/anchor/style/theme-ascend.scss b/packages/opendesign/src/anchor/style/theme-ascend.scss
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/packages/opendesign/src/anchor/style/theme-kunpeng.index.ts b/packages/opendesign/src/anchor/style/theme-kunpeng.index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..08f1ffe5704754a7322de7adff8f64b9f43f7379
--- /dev/null
+++ b/packages/opendesign/src/anchor/style/theme-kunpeng.index.ts
@@ -0,0 +1,4 @@
+import '../../_styles';
+import '../../select/style/theme-kunpeng.index';
+import './index.scss';
+import './theme-kunpeng.scss';
diff --git a/packages/opendesign/src/anchor/style/theme-kunpeng.scss b/packages/opendesign/src/anchor/style/theme-kunpeng.scss
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/packages/opendesign/src/anchor/style/theme-openeuler.index.ts b/packages/opendesign/src/anchor/style/theme-openeuler.index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..93ba6509e35367f9c7ca12d2142dcb65d50c0b55
--- /dev/null
+++ b/packages/opendesign/src/anchor/style/theme-openeuler.index.ts
@@ -0,0 +1,4 @@
+import '../../_styles';
+import '../../select/style/theme-openeuler.index';
+import './index.scss';
+import './theme-openeuler.scss';
diff --git a/packages/opendesign/src/anchor/style/theme-openeuler.scss b/packages/opendesign/src/anchor/style/theme-openeuler.scss
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/packages/opendesign/src/anchor/style/var.scss b/packages/opendesign/src/anchor/style/var.scss
index 8d13c1f8acc1be9755c6982d73712f274890cfa3..1b66aaec7d501d7a2a425c8e016fca1c5f7c34e3 100644
--- a/packages/opendesign/src/anchor/style/var.scss
+++ b/packages/opendesign/src/anchor/style/var.scss
@@ -1,10 +1,16 @@
.o-anchor {
- --anchor-line-width: 2px;
+ --anchor-line-width: 1px;
--anchor-line-bg-color: var(--o-color-control4);
+ --anchor-line-gap: var(--o-gap-2);
--anchor-indicator-width: 2px;
- --anchor-indicator-height: 16px;
+ --anchor-indicator-height: 12px;
--anchor-indicator-bg-color: var(--o-color-primary1);
+ --anchor-indicator-adjust: 0.12em;
+
+ --anchor-circle-size: 8px;
+ --anchor-circle-ring-width: 1.5px;
+ --anchor-circle-gap: 8px;
}
.o-anchor-item {
@@ -12,16 +18,54 @@
--anchor-item-link-color: var(--o-color-info2);
--anchor-item-link-color-active: var(--o-color-primary1);
+ --anchor-item-link-color-hover: var(--o-color-primary2);
+ --anchor-item-link-color-press: var(--o-color-primary3);
+ --anchor-item-link-color-disabled: var(--o-color-info4);
+
+ --anchor-item-max-row: 2;
--anchor-item-link-text-size: var(--o-font_size-text1);
--anchor-item-link-text-height: var(--o-line_height-text1);
- --anchor-item-link-bg-color: transparent;
- --anchor-item-link-bg-color-hover: var(--o-color-control2-light);
- --anchor-item-link-bg-color-active: var(--o-color-control3-light);
+ --anchor-item-sub-link-text-size: var(--o-font_size-tip1);
+ --anchor-item-sub-link-text-height: var(--o-line_height-tip1);
- --anchor-item-link-padding: 7px 8px;
+ --anchor-item-link-padding-h: 8px;
+ --anchor-item-link-padding-v: 8px;
+ --anchor-item-sub-link-padding-v: 5px;
--anchor-item-link-radius: var(--o-radius_control-s);
- --anchor-item-link-gap: 2px;
+ --anchor-item-text-indent: 12px;
+}
+
+.o-anchor-small {
+ .o-anchor-item {
+ --anchor-item-link-text-size: var(--o-font_size-tip1);
+ --anchor-item-link-text-height: var(--o-line_height-tip1);
+
+ --anchor-item-sub-link-text-size: var(--o-font_size-tip2);
+ --anchor-item-sub-link-text-height: var(--o-line_height-tip2);
+
+ --anchor-item-link-padding-v: 5px;
+ --anchor-item-sub-link-padding-v: 5px;
+ }
+}
+
+.o-anchor-menu {
+ .o-anchor-item {
+ --anchor-item-link-text-size: var(--o-font_size-tip1);
+ --anchor-item-link-text-height: var(--o-line_height-tip1);
+
+ --anchor-item-sub-link-text-size: var(--o-font_size-tip1);
+ --anchor-item-sub-link-text-height: var(--o-line_height-tip1);
+
+ --anchor-item-link-padding-v: 5px;
+ --anchor-item-sub-link-padding-v: 5px;
+
+ --anchor-item-text-indent: 20px;
+ }
+}
+
+.o-anchor-link-popover-wrapper {
+ --anchor-popover-max-width: 200px;
}
diff --git a/packages/opendesign/src/anchor/types.ts b/packages/opendesign/src/anchor/types.ts
index 063c1ce0ccfe0c8093c3008990c5058caf625efc..862fb67f31251dcbae9e7d1cd60fb093d18e747f 100644
--- a/packages/opendesign/src/anchor/types.ts
+++ b/packages/opendesign/src/anchor/types.ts
@@ -1,7 +1,20 @@
import type { ExtractPropTypes, PropType } from 'vue';
+export const AnchorSizeTypes = ['medium', 'small', 'menu'] as const;
+export type AnchorSizeT = (typeof AnchorSizeTypes)[number];
+export type AnchorTargetT = '_blank' | '_parent' | '_self' | '_top';
+
export const anchorProps = {
- /**
+ /**
+ * @zh-CN 锚点的尺寸, menu为左侧菜单或移动端菜单混合使用
+ * @en-US Anchor size, 'menu' for aside menu-mixed or mobile menu mode
+ * @default 'medium'
+ */
+ size: {
+ type: String as PropType,
+ default: 'medium',
+ },
+ /**
* @zh-CN 监测容器
* @en-US Scroll container to monitor
* @default window
@@ -9,7 +22,7 @@ export const anchorProps = {
container: {
type: [String, Object] as PropType,
},
- /**
+ /**
* @zh-CN 锚点激活的边界范围
* @en-US Boundary for anchor activation
* @default 5
@@ -18,7 +31,7 @@ export const anchorProps = {
type: Number,
default: 5,
},
- /**
+ /**
* @zh-CN 锚点激活的判定边界
* @en-US Boundary for anchor activation
* @default 0
@@ -31,7 +44,7 @@ export const anchorProps = {
* @zh-CN 点击锚点时是否改变浏览器地址栏的 hash 值
* @en-US Whether to change the browser's address bar hash value when clicking the anchor
* @default true
- */
+ */
changeHash: {
type: Boolean,
default: true,
@@ -42,15 +55,15 @@ export const anchorItemProps = {
/**
* @zh-CN 锚点标题
* @en-US Anchor title
- */
+ */
title: {
type: String,
default: '',
},
/**
- * @zh-CN 锚点跳转的目标元素(带#前缀)
+ * @zh-CN 锚点监听、跳转的目标元素(带#前缀)
* @en-US Target element for anchor navigation (with # prefix)
- */
+ */
href: {
type: String,
required: true,
@@ -59,11 +72,20 @@ export const anchorItemProps = {
* @zh-CN 锚点跳转方式
* @en-US Anchor navigation method
* @default '_self'
- */
+ */
target: {
- type: String as PropType<'_blank' | '_parent' | '_self' | '_top'>,
+ type: String as PropType,
default: '_self',
},
+ /**
+ * @zh-CN 锚点是否禁用
+ * @en-US Anchor disable status
+ * @default false
+ */
+ disabled: {
+ type: Boolean as PropType,
+ default: false,
+ },
};
export type AnchorContainerT = HTMLElement | Window;