Skip to content

Commit 58d1a7d

Browse files
authored
Add anchor component (#64)
* Add anchor component * Fix CI * Fix anchor react component props
1 parent e6dba47 commit 58d1a7d

File tree

11 files changed

+134
-0
lines changed

11 files changed

+134
-0
lines changed
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// Copyright (c) Jupyter Development Team.
2+
// Distributed under the terms of the Modified BSD License.
3+
import type { StoryFn, Meta, StoryObj } from '@storybook/html';
4+
import { getFaIcon, setTheme } from '../utilities/storybook';
5+
6+
export default {
7+
title: 'Components/Anchor',
8+
argTypes: {
9+
label: { control: 'text' },
10+
appearance: {
11+
control: 'select',
12+
options: [
13+
'Accent',
14+
'Lightweight',
15+
'Neutral',
16+
'Outline',
17+
'Stealth',
18+
'Hypertext'
19+
]
20+
},
21+
startIcon: { control: 'boolean' },
22+
endIcon: { control: 'boolean' }
23+
}
24+
} as Meta;
25+
26+
const Template: StoryFn = (args, context): string => {
27+
const {
28+
globals: { backgrounds, accent },
29+
parameters
30+
} = context;
31+
setTheme(accent, parameters.backgrounds, backgrounds);
32+
33+
return `<jp-anchor
34+
href="#"
35+
${args.appearance ? `appearance="${args.appearance.toLowerCase()}` : ''}">
36+
${args.startIcon ? getFaIcon('plus', 'start') : ''}${args.label ?? 'Link'}
37+
${args.endIcon ? getFaIcon('plus', 'end') : ''}
38+
</jp-anchor>`;
39+
};
40+
41+
export const Default: StoryObj = { render: Template.bind({}) };
42+
Default.args = {
43+
label: 'Link',
44+
appearance: 'Neutral',
45+
startIcon: false,
46+
endIcon: false
47+
};
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// Copyright (c) Jupyter Development Team.
2+
// Distributed under the terms of the Modified BSD License.
3+
4+
import { test, expect } from '@playwright/test';
5+
6+
test('Default', async ({ page }) => {
7+
await page.goto('/iframe.html?id=components-anchor--default');
8+
9+
expect(await page.locator('jp-anchor').screenshot()).toMatchSnapshot(
10+
'anchor-default.png'
11+
);
12+
});
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Copyright (c) Jupyter Development Team.
2+
// Distributed under the terms of the Modified BSD License.
3+
4+
import {
5+
Anchor as FoundationAnchor,
6+
anchorTemplate as template
7+
} from '@microsoft/fast-foundation';
8+
import { Anchor, anchorStyles as styles } from '@microsoft/fast-components';
9+
10+
/**
11+
* A function that returns a Anchor registration for configuration with a DesignSystem.
12+
* Implements {@link @microsoft/fast-foundation#anchorTemplate}
13+
*
14+
* @public
15+
* @remarks
16+
* Generates HTML Element: `<jp-anchor>`
17+
*/
18+
export const jpAnchor = Anchor.compose({
19+
baseName: 'anchor',
20+
baseClass: FoundationAnchor,
21+
template,
22+
styles
23+
});
24+
25+
/**
26+
* Base class for Anchor
27+
* @public
28+
*/
29+
export { Anchor };
30+
31+
export { styles as anchorStyles };

packages/components/src/custom-elements.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import type { Container } from '@microsoft/fast-foundation';
55
import { jpAccordion } from './accordion/index';
66
import { jpAccordionItem } from './accordion-item/index';
7+
import { jpAnchor } from './anchor/index';
78
import { jpAnchoredRegion } from './anchored-region/index';
89
import { jpAvatar } from './avatar/index';
910
import { jpBadge } from './badge/index';
@@ -44,6 +45,7 @@ import { jpTreeView } from './tree-view/index';
4445
/* eslint-disable @typescript-eslint/no-unused-vars */
4546
import type { Accordion } from './accordion/index';
4647
import type { AccordionItem } from './accordion-item/index';
48+
import type { Anchor } from './anchor/index';
4749
import type { AnchoredRegion } from './anchored-region/index';
4850
import type { Avatar } from './avatar/index';
4951
import type { Badge } from './badge/index';
@@ -83,6 +85,7 @@ import type { TreeView } from './tree-view/index';
8385
export {
8486
jpAccordion,
8587
jpAccordionItem,
88+
jpAnchor,
8689
jpAnchoredRegion,
8790
jpAvatar,
8891
jpBadge,
@@ -131,6 +134,7 @@ export {
131134
export const allComponents = {
132135
jpAccordion,
133136
jpAccordionItem,
137+
jpAnchor,
134138
jpAnchoredRegion,
135139
jpAvatar,
136140
jpBadge,

packages/components/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export * from './custom-elements';
1111
// Export components and classes
1212
export * from './accordion/index';
1313
export * from './accordion-item/index';
14+
export * from './anchor/index';
1415
export * from './anchored-region/index';
1516
export * from './avatar/index';
1617
export * from './badge/index';
Loading
Loading
Loading

packages/lab-example/src/index.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import {
55
Accordion,
66
AccordionItem,
7+
Anchor,
78
Avatar,
89
Badge,
910
Breadcrumb,
@@ -254,6 +255,9 @@ function Artwork(props: { dataRef: React.Ref<WebDataGrid> }): JSX.Element {
254255
<span className="fa fa-cog"></span>
255256
</Button>
256257
</div>
258+
<Anchor appearance="outline" href="#">
259+
Anchor element
260+
</Anchor>
257261
<Search
258262
value="Dummy search text"
259263
onChange={onChange}
@@ -454,6 +458,9 @@ function createNode(): HTMLElement {
454458
<jp-button appearance="neutral">Button</jp-button>
455459
<jp-button appearance="stealth" aria-label="Confirm"><span class="fa fa-cog"></span></jp-button>
456460
</div>
461+
<jp-anchor appearance="outline" href="#">
462+
Anchor element
463+
</jp-anchor>
457464
<jp-search value="Dummy search text">Search Label</jp-search>
458465
<jp-text-field value="Populated text">Text Field Label</jp-text-field>
459466
<jp-number-field value="30">Number Field Label</jp-number-field>
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Copyright (c) Jupyter Development Team.
2+
// Distributed under the terms of the Modified BSD License.
3+
4+
import { provideJupyterDesignSystem, jpAnchor } from '@jupyter/web-components';
5+
import { provideReactWrapper } from '@microsoft/fast-react-wrapper';
6+
import React from 'react';
7+
8+
const { wrap } = provideReactWrapper(React, provideJupyterDesignSystem());
9+
10+
export const Anchor: React.DetailedHTMLFactory<
11+
React.HTMLAttributes<HTMLElement> & {
12+
appearance?:
13+
| 'accent'
14+
| 'lightweight'
15+
| 'neutral'
16+
| 'outline'
17+
| 'stealth'
18+
| 'hypertext';
19+
download?: string;
20+
href?: string;
21+
hreflang?: string;
22+
ping?: string;
23+
referrerpolicy?: string;
24+
rel?: string;
25+
target?: '_self' | '_blank' | '_parent' | '_top';
26+
type?: string;
27+
},
28+
HTMLElement
29+
> = wrap(jpAnchor()) as any;
30+
// @ts-expect-error unknown property
31+
Anchor.displayName = 'Jupyter.Anchor';

packages/react-components/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
export * from './accordion';
55
export * from './accordion-item';
6+
export * from './anchor';
67
export * from './anchored-region';
78
export * from './avatar';
89
export * from './badge';

0 commit comments

Comments
 (0)