-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Create storybook page for link components (#1945)
# Pull Request ## 🤨 Rationale There are a number of browser interactions that are expected to work in certain ways for link components that are difficult to test in an automated manner. Therefore, we decided that we should have a storybook page that contains all of nimble's link components next to a native anchor element to facilitate manual testing of link behaviors. This is follow-on work from #1910, specifically [this comment](#1910 (comment)). ## 👩💻 Implementation Create storybook page that includes the following elements: - native anchor - nimble-anchor - nimble-anchor-button - nimble-anchor-tabs - nimble-breadcrumb - nimble-anchor-tree-item - nimble-anchor-menu-item - nimble-table-column-anchor - nimble-rich-text-viewer ## 🧪 Testing Manually verified that the storybook page rendered as expected. ## ✅ Checklist <!--- Review the list and put an x in the boxes that apply or ~~strike through~~ around items that don't (along with an explanation). --> - [ ] I have updated the project documentation to reflect my changes or determined no changes are needed. --------- Co-authored-by: Jesse Attas <jattasNI@users.noreply.github.com> Co-authored-by: Milan Raj <rajsite@users.noreply.github.com>
- Loading branch information
1 parent
8bb2c33
commit 517e945
Showing
5 changed files
with
216 additions
and
0 deletions.
There are no files selected for viewing
7 changes: 7 additions & 0 deletions
7
change/@ni-nimble-components-80f0d7d1-04a3-456f-85b8-c96cf8c59b93.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
{ | ||
"type": "none", | ||
"comment": "Create anchor patterns story", | ||
"packageName": "@ni/nimble-components", | ||
"email": "20542556+mollykreis@users.noreply.github.com", | ||
"dependentChangeType": "none" | ||
} |
38 changes: 38 additions & 0 deletions
38
packages/nimble-components/src/patterns/anchor/tests/anchor-patterns.mdx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
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: | ||
|
||
Mouse interactions: | ||
|
||
- Dragging the nimble component should behave like the native anchor | ||
- Known behavior exceptions: | ||
- Chromium - The drag preview contains the href only, not the label of the anchor. See [chromium issue 329489154](https://issues.chromium.org/issues/329489154). | ||
- Firefox - The drag preview does not contain the label, and in most cases, is blank. See [mozilla bug 1589364](https://bugzilla.mozilla.org/show_bug.cgi?id=1589364). | ||
- Safari - The drag preview contains the href only, not the label of the anchor. | ||
- CTRL + CLICK opens in a new tab (⌘ + CLICK on macOS) | ||
- Right clicking should open the link menu | ||
- Hovering over the component should show the URL preview at the bottom of the browser window | ||
- Copying the link through the right-click link menu should result in the expected string to be copied to the clipboard | ||
- 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) | ||
|
||
Keyboard interactions: | ||
|
||
- Focusing via tab should show the URL preview at the bottom of the browser window | ||
- Known behavior exceptions: | ||
- Firefox on macOS - Links are not focusable via tab by default. [See this stackoverflow page for how to allow tab focus of links](https://stackoverflow.com/questions/11704828/how-to-allow-keyboard-focus-of-links-in-firefox). | ||
- Safari - Focusing via tab does not show the URL preview at the bottom of the browser, which matches the behavior of native anchors. | ||
- Pressing ENTER when focused should activate the link | ||
- Pressing the MENU KEY on the keyboard while the link is focused should open the same link menu as a right click | ||
|
||
Interactions specific to anchors visualized as text: | ||
|
||
- Selecting the link through click and drag and then copying it should result in the expected string being copied to the clipboard | ||
|
||
<Canvas of={anchorPatternStories.anchorPatterns} /> | ||
<Controls of={anchorPatternStories.anchorPatterns} /> |
169 changes: 169 additions & 0 deletions
169
packages/nimble-components/src/patterns/anchor/tests/anchor-patterns.stories.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,169 @@ | ||
import type { Meta, StoryObj } from '@storybook/html'; | ||
import { html, ref } from '@microsoft/fast-element'; | ||
import { createUserSelectedThemeStory } from '../../../utilities/tests/storybook'; | ||
import { | ||
bodyFont, | ||
bodyFontColor, | ||
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'; | ||
import { Table, tableTag } from '../../../table'; | ||
import { tableColumnAnchorTag } from '../../../table-column/anchor'; | ||
|
||
interface AnchorPatternsArgs { | ||
label: string; | ||
disabled: boolean; | ||
tableRef: Table; | ||
setTableData: (args: AnchorPatternsArgs) => void; | ||
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}); | ||
} | ||
.text { | ||
font: var(${bodyFont.cssCustomProperty}); | ||
color: var(${bodyFontColor.cssCustomProperty}); | ||
margin-top: var(${mediumPadding.cssCustomProperty}); | ||
} | ||
</style> | ||
<div class="control-container"> | ||
<div class="label">Native anchor</div> | ||
<a href="${x => (x.disabled ? undefined : 'https://nimble.ni.dev?type=native-anchor-1')}">${x => x.label}</a> | ||
<div class="text">Text that contains a <a href="${x => (x.disabled ? undefined : 'https://nimble.ni.dev?type=native-anchor-2')}">native anchor element</a>.</div> | ||
</div> | ||
<div class="control-container"> | ||
<div class="label">${anchorTag}</div> | ||
<${anchorTag} href="${x => (x.disabled ? undefined : 'https://nimble.ni.dev?type=nimble-anchor-1')}">${x => x.label}</${anchorTag}> | ||
<div class="text">Text that contains a <${anchorTag} href="${x => (x.disabled ? undefined : 'https://nimble.ni.dev?type=nimble-anchor-2')}">nimble anchor element</${anchorTag}>.</div> | ||
</div> | ||
<div class="control-container"> | ||
<div class="label">${anchorButtonTag}</div> | ||
<${anchorButtonTag} href="https://nimble.ni.dev?type=nimble-anchor-button" ?disabled="${x => x.disabled}">${x => x.label}</${anchorButtonTag}> | ||
</div> | ||
<div class="control-container"> | ||
<div class="label">${anchorTabsTag}</div> | ||
<${anchorTabsTag}> | ||
<${anchorTabTag} href="https://nimble.ni.dev?type=nimble-anchor-tab-1" ?disabled="${x => x.disabled}">${x => x.label} - 1</${anchorTabTag}> | ||
<${anchorTabTag} href="https://nimble.ni.dev?type=nimble-anchor-tab-2" ?disabled="${x => x.disabled}">${x => x.label} - 2</${anchorTabTag}> | ||
</${anchorTabsTag}> | ||
</div> | ||
<div class="control-container"> | ||
<div class="label">${breadcrumbTag}</div> | ||
<${breadcrumbTag}> | ||
<${breadcrumbItemTag} href="${x => (x.disabled ? undefined : 'https://nimble.ni.dev?type=nimble-breadcrumb-item')}">${x => x.label}</${breadcrumbItemTag}> | ||
<${breadcrumbItemTag}>Current page (no link)</${breadcrumbItemTag}> | ||
</${breadcrumbTag}> | ||
</div> | ||
<div class="control-container"> | ||
<div class="label">${anchorTreeItemTag}</div> | ||
<${treeViewTag}> | ||
<${anchorTreeItemTag} href="https://nimble.ni.dev?type=nimble-anchor-tree-item" ?disabled="${x => x.disabled}">${x => x.label}</${anchorTreeItemTag}> | ||
</${treeViewTag}> | ||
</div> | ||
<div class="control-container"> | ||
<div class="label">${anchorMenuItemTag}</div> | ||
<${menuTag}> | ||
<${anchorMenuItemTag} href="https://nimble.ni.dev?type=nimble-anchor-menu-item" ?disabled="${x => x.disabled}">${x => x.label}</${anchorMenuItemTag}> | ||
</${menuTag}> | ||
</div> | ||
<div class="control-container"> | ||
<div class="label">${tableColumnAnchorTag}</div> | ||
<${tableTag} ${ref('tableRef')} data-unused="${x => x.setTableData(x)}" style="height: 100px;"> | ||
<${tableColumnAnchorTag} label-field-name="label" href-field-name="href">Anchor</${tableColumnAnchorTag}> | ||
</${tableTag}> | ||
</div> | ||
<div class="control-container"> | ||
<div class="label">${richTextViewerTag}</div> | ||
<${richTextViewerTag} ${ref('richTextViewerRef')} | ||
data-unused="${x => x.setRichTextViewerData(x)}" | ||
> | ||
${x => x.label} | ||
</${richTextViewerTag}> | ||
</div> | ||
`), | ||
argTypes: { | ||
tableRef: { | ||
table: { disable: true } | ||
}, | ||
setTableData: { | ||
table: { disable: true } | ||
}, | ||
richTextViewerRef: { | ||
table: { disable: true } | ||
}, | ||
setRichTextViewerData: { | ||
table: { disable: true } | ||
} | ||
}, | ||
args: { | ||
label: 'link', | ||
disabled: false, | ||
setTableData: x => { | ||
void (async () => { | ||
// Safari workaround: the nimble-table element instance is made at this point | ||
// but doesn't seem to be upgraded to a custom element yet | ||
await customElements.whenDefined('nimble-table'); | ||
const data = [ | ||
{ | ||
label: x.label, | ||
href: x.disabled | ||
? undefined | ||
: 'https://nimble.ni.dev?type=nimble-table-column-anchor' | ||
} | ||
]; | ||
void x.tableRef.setData(data); | ||
})(); | ||
}, | ||
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.disabled ? '' : 'https://nimble.ni.dev?type=nimble-rich-text-viewer'}>`; | ||
x.richTextViewerRef.markdown = data; | ||
})(); | ||
} | ||
} | ||
}; | ||
|
||
export default metadata; | ||
|
||
export const anchorPatterns: StoryObj<AnchorPatternsArgs> = {}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters