Skip to content

Commit

Permalink
Create anchor patterns story
Browse files Browse the repository at this point in the history
  • Loading branch information
mollykreis committed Mar 14, 2024
1 parent aeaa29b commit 0885406
Show file tree
Hide file tree
Showing 2 changed files with 149 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { Controls, Canvas, Meta, Title } from '@storybook/blocks';
import * as anchorPatternStories from './anchor-patterns.stories';

<Meta of={anchorPatternStories} />
<Title of={anchorPatternStories} />

Anchor components in nimble should behave like native anchors in a number of different ways that are difficult to unit test in an automated manner.
Therefore, this story contains a native anchor element along with all of the nimble components that are anchors or contain anchors.
The following behaviors should be true of the nimble components:

- Dragging the nimble component should behave like the native anchor
- CTRL + CLICK opens in a new tab
- Right clicking should open the link menu
- Focusing via tab should show the URL preview at the bottom of the browser window
- Hovering over the component should show the URL preview at the bottom of the browser window
- The hover state of the component and mouse pointer should match the area of the component that navigates when clicked (i.e. clicking the white space around the control should not navigate)
- Pressing ENTER or SPACE when focused should activate the link
- Pressing the MENU KEY on the keyboard should open the same link menu as a right click
- Copying the link through the right-click link menu should result in the expected string to be copied to the clipboard

<Canvas of={anchorPatternStories.anchorPatterns} />
<Controls of={anchorPatternStories.anchorPatterns} />
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
import type { Meta, StoryObj } from '@storybook/html';
import { html, ref } from '@microsoft/fast-element';
import { createUserSelectedThemeStory } from '../../../utilities/tests/storybook';
import { controlLabelFont, controlLabelFontColor, mediumPadding, standardPadding } from '../../../theme-provider/design-tokens';
import { anchorTag } from '../../../anchor';
import { anchorButtonTag } from '../../../anchor-button';
import { anchorTabsTag } from '../../../anchor-tabs';
import { anchorTabTag } from '../../../anchor-tab';
import { breadcrumbTag } from '../../../breadcrumb';
import { breadcrumbItemTag } from '../../../breadcrumb-item';
import { RichTextViewer, richTextViewerTag } from '../../../rich-text/viewer';
import { anchorTreeItemTag } from '../../../anchor-tree-item';
import { treeViewTag } from '../../../tree-view';
import { anchorMenuItemTag } from '../../../anchor-menu-item';
import { menuTag } from '../../../menu';

const hrefDescription = 'To disable the control, remove the `href` attribute.';

interface AnchorPatternsArgs {
label: string;
href: string;
richTextViewerRef: RichTextViewer;
setRichTextViewerData: (args: AnchorPatternsArgs) => void;
}

const metadata: Meta<AnchorPatternsArgs> = {
title: 'Tests/Anchor Patterns',
parameters: {
actions: {}
},
// prettier-ignore
render: createUserSelectedThemeStory(html`
<style class='code-hide'>
.control-container {
margin: var(${standardPadding.cssCustomProperty});
}
.label {
font: var(${controlLabelFont.cssCustomProperty});
color: var(${controlLabelFontColor.cssCustomProperty});
margin-bottom: var(${mediumPadding.cssCustomProperty});
}
</style>
<div class="control-container">
<div class="label">Native anchor</div>
<a href="${x => x.href}">${x => x.label}</a>
</div>
<div class="control-container">
<div class="label">${anchorTag}</div>
<${anchorTag} href="${x => x.href}">${x => x.label}</${anchorTag}>
</div>
<div class="control-container">
<div class="label">${anchorButtonTag}</div>
<${anchorButtonTag} href="${x => x.href}">${x => x.label}</${anchorButtonTag}>
</div>
<div class="control-container">
<div class="label">${anchorTabsTag}</div>
<${anchorTabsTag}>
<${anchorTabTag} href="${x => x.href}">${x => x.label} - 1</${anchorTabTag}>
<${anchorTabTag} href="${x => x.href}">${x => x.label} - 2</${anchorTabTag}>
</${anchorTabsTag}>
</div>
<div class="control-container">
<div class="label">${breadcrumbTag}</div>
<${breadcrumbTag}>
<${breadcrumbItemTag} href="${x => x.href}">${x => x.label}</${breadcrumbItemTag}>
<${breadcrumbItemTag}>Current page (no link)</${breadcrumbItemTag}>
</${breadcrumbTag}>
</div>
<div class="control-container">
<div class="label">${anchorTreeItemTag}</div>
<${treeViewTag}>
<${anchorTreeItemTag} href="${x => x.href}">${x => x.label}</${anchorTreeItemTag}>
</${treeViewTag}>
</div>
<div class="control-container">
<div class="label">${anchorMenuItemTag}</div>
<${menuTag}>
<${anchorMenuItemTag} href="${x => x.href}">${x => x.label}</${anchorMenuItemTag}>
</${menuTag}>
</div>
<div class="control-container">
<div class="label">${richTextViewerTag}</div>
<${richTextViewerTag} ${ref('richTextViewerRef')}
href="${x => x.href}"
data-unused="${x => x.setRichTextViewerData(x)}"
>
${x => x.label}
</${richTextViewerTag}>
</div>
`),
argTypes: {
href: {
description: hrefDescription
},
richTextViewerRef: {
table: { disable: true }
},
setRichTextViewerData: {
table: { disable: true }
}
},
args: {
label: 'link',
href: 'https://nimble.ni.dev',
setRichTextViewerData: x => {
void (async () => {
// Safari workaround: the nimble-rich-text-viewer element instance is made at this point
// but doesn't seem to be upgraded to a custom element yet
await customElements.whenDefined('nimble-rich-text-viewer');
const data = `Absolute link: <${x.href}>`;
x.richTextViewerRef.markdown = data;
})();
},
}
};

export default metadata;

export const anchorPatterns: StoryObj<AnchorPatternsArgs> = {};

0 comments on commit 0885406

Please sign in to comment.