走鹃 3 rokov pred
rodič
commit
73dfbdd744

+ 1 - 1
packages/semi-ui/anchor/_story/anchor.stories.js

@@ -15,7 +15,7 @@ const Link = Anchor.Link;
 export const Size = () => (
   <div>
     <div>小号尺寸</div>
-    <Anchor size={'small'}>
+    <Anchor ariaLabel="小号尺寸" size={'small'}>
       <Link href="#welcome" title="welcome" />
       <Link href="#api" title="api too much to show" />
       <Link href="#contact" title="contact" />

+ 4 - 2
packages/semi-ui/anchor/index.tsx

@@ -31,6 +31,7 @@ export interface AnchorProps {
     targetOffset?: number;
     onChange?: (currentLink: string, previousLink: string) => void;
     onClick?: (e: React.MouseEvent<HTMLElement>, currentLink: string) => void;
+    ariaLabel?: string;
 }
 
 export interface AnchorState {
@@ -250,6 +251,7 @@ class Anchor extends BaseComponent<AnchorProps, AnchorState> {
             showTooltip,
             position,
             autoCollapse,
+            ariaLabel
         } = this.props;
         const { activeLink, scrollHeight, slideBarTop } = this.state;
         const wrapperCls = cls(prefixCls, className, {
@@ -282,8 +284,8 @@ class Anchor extends BaseComponent<AnchorProps, AnchorState> {
                     removeLink: this.removeLink,
                 }}
             >
-                <div className={wrapperCls} style={wrapperStyle} id={this.anchorID}>
-                    <div className={slideCls} style={{ height: scrollHeight }}>
+                <div role="navigation" aria-label={ ariaLabel || 'Side navigation'} className={wrapperCls} style={wrapperStyle} id={this.anchorID}>
+                    <div aria-hidden className={slideCls} style={{ height: scrollHeight }}>
                         <span className={slideBarCls} style={{ top: slideBarTop }} />
                     </div>
                     <div className={anchorWrapper}>{children}</div>

+ 29 - 4
packages/semi-ui/anchor/link.tsx

@@ -4,7 +4,7 @@ import PropTypes from 'prop-types';
 import BaseComponent from '../_base/baseComponent';
 import { cssClasses } from '@douyinfe/semi-foundation/anchor/constants';
 import LinkFoundation, { LinkAdapter } from '@douyinfe/semi-foundation/anchor/linkFoundation';
-import AnchorContext from './anchor-context';
+import AnchorContext, { AnchorContextType } from './anchor-context';
 import Typography from '../typography/index';
 
 const prefixCls = cssClasses.PREFIX;
@@ -36,9 +36,11 @@ export default class Link extends BaseComponent<LinkProps, {}> {
 
     foundation: LinkFoundation;
 
+    context!: AnchorContextType;
     constructor(props: LinkProps) {
         super(props);
         this.foundation = new LinkFoundation(this.adapter);
+        this.handleClick = this.handleClick.bind(this);
     }
 
     get adapter(): LinkAdapter {
@@ -65,6 +67,12 @@ export default class Link extends BaseComponent<LinkProps, {}> {
         this.foundation.handleUpdateLink(href, prevHref);
     }
 
+    handleClick(e: React.KeyboardEvent | React.MouseEvent) {
+        const { disabled, href } = this.props;
+        const { onClick } = this.context;
+        !disabled && onClick(e as any, href);
+    }
+
     componentDidMount() {
         this.handleAddLink();
     }
@@ -115,18 +123,35 @@ export default class Link extends BaseComponent<LinkProps, {}> {
     };
 
     render() {
-        const { href, className, style, disabled = false } = this.props;
-        const { activeLink, onClick } = this.context;
+        const { href, className, style, disabled = false, title } = this.props;
+        const { activeLink, showTooltip } = this.context;
         const active = activeLink === href;
         const linkCls = cls(`${prefixCls}-link`, className);
         const linkTitleCls = cls(`${prefixCls}-link-title`, {
             [`${prefixCls}-link-title-active`]: active,
             [`${prefixCls}-link-title-disabled`]: disabled,
         });
+        const ariaProps = {
+            'aria-disabled': disabled,
+            'aria-label': href,
+        };
+        if (active) {
+            ariaProps['aria-details'] = 'active';
+        }
+        if (!showTooltip && typeof title === 'string') {
+            ariaProps['title'] = title;
+        }
 
         return (
             <div className={linkCls} style={style}>
-                <div className={linkTitleCls} onClick={e => !disabled && onClick(e, href)}>
+                <div
+                    role="link"
+                    tabIndex={0}
+                    {...ariaProps}
+                    className={linkTitleCls}
+                    onClick={e => this.handleClick(e)}
+                    onKeyPress={e => this.handleClick(e)}
+                >
                     {this.renderTitle()}
                 </div>
                 {this.renderChildren()}