Skip to content

Commit

Permalink
Drop fast react wrapper (#100)
Browse files Browse the repository at this point in the history
* Add metadata for generating react components

* New react components

* First partial fix

* Prettify

* Improve typing

* Simplify component types

* Fix reference to custom element

* Package custom elements definitions

* Keep event naming

* Build dynamically custom-element def

* Remove dist file exception

* Restore datefield react component

* Lint the code

---------

Co-authored-by: Frédéric Collonval <[email protected]>
  • Loading branch information
fcollonval and fcollonval authored Jun 12, 2024
1 parent 68d98ff commit 7b55d5f
Show file tree
Hide file tree
Showing 199 changed files with 5,924 additions and 1,485 deletions.
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
*.bundle.*
lib/
!packages/react-components/lib/
node_modules/
*.log
.eslintcache
Expand Down Expand Up @@ -30,11 +31,10 @@ __pycache__/
.Python
build/
develop-eggs/
dist/
**/dist/*
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
Expand Down
2 changes: 2 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,5 @@ npm-debug.log*
yarn-debug.log*
yarn-error.log*
tests-out/

!packages/react-components/lib
18 changes: 18 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,24 @@ cd packages/components
yarn start
```

### React components

The react components wrapper are initialized using [custom-element-react-wrappers](https://github.com/break-stuff/cem-tools/tree/main/packages/react-wrappers).
The initialization can be reproduced by running in `packages/components` the script `yarn run build:react`.
Unfortunately the initial code needs lots of changes to be usable in this case:

- Changing the typing to inherit from `React.AllHTMLAttributes` - minus some event handlers that needs to be overridden.
- Changing `useImperativeHandle` to expose the full HTMLElement using:

```js
useImperativeHandle(forwardedRef, () => ref.current, [ref.current]);
```

- Remove internal fast-specific properties like `$presentation`, `styles` and `template`.
- The tag name, the properties and the events are extracted from the doc string of
the element class definition in `packages/components`. You may need to add some
new doc tags to get all the properties and events.

### JupyterLab demo extension

To test locally the JupyterLab demo extension, using `conda` package manager:
Expand Down
43 changes: 43 additions & 0 deletions packages/components/custom-elements-manifest.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/* global process */
import { customElementReactWrapperPlugin } from 'custom-element-react-wrappers';

/**
* Custom element manifest plugin to remove the
* Jupyter prefix in the element class name to
* get a better naming for the generated react components.
*/
function renameClassElement() {
return {
name: 'rename-class-element-plugin',
packageLinkPhase({ customElementsManifest, context }) {
customElementsManifest.modules.forEach(module => {
module.declarations.forEach(declaration => {
// Remove the prefix `Jupyter` for simpler naming
if (declaration.tagName && declaration.name.startsWith('Jupyter')) {
declaration.name = declaration.name.slice(7);
}
});
});
}
};
}

const plugins = [renameClassElement()];

if (process.env.BUILD_REACT) {
plugins.push(
customElementReactWrapperPlugin({
outdir: '../react-components/lib',
modulePath: (className, tagName) => '@jupyter/web-components'
})
);
}

export default {
fast: true,
outdir: 'dist',
dependencies: true,
globs: ['src/**/index.ts'],
exclude: ['src/index.ts', 'src/styles', 'src/utilities'],
plugins
};
8 changes: 6 additions & 2 deletions packages/components/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,9 @@
"scripts": {
"start": "storybook dev -p 6006",
"start:ci": "storybook dev -p 6006 --ci --quiet",
"build": "rollup -c && tsc -p ./tsconfig.json",
"build": "rollup -c && tsc -p ./tsconfig.json && custom-elements-manifest analyze",
"build:docs": "storybook build",
"build:react": "BUILD_REACT=1 custom-elements-manifest analyze",
"clean": "yarn clean:lib && yarn clean:test",
"clean:lib": "rimraf dist",
"clean:test": "rimraf test-results tests-out/**/*.js tests-out/**/*.js.map tsconfig.playwright.tsbuildinfo",
Expand All @@ -49,6 +50,7 @@
"devDependencies": {
"@babel/core": "^7.22.5",
"@babel/preset-env": "^7.22.5",
"@custom-elements-manifest/analyzer": "^0.10.2",
"@fortawesome/fontawesome-svg-core": "^1.2.36",
"@fortawesome/free-solid-svg-icons": "^5.15.4",
"@microsoft/api-extractor": "^7.36.0",
Expand All @@ -69,6 +71,7 @@
"@types/node": "^18.0.0",
"@types/webpack-env": "^1.15.2",
"@typescript-eslint/eslint-plugin": "^5.60.1",
"custom-element-react-wrappers": "^1.6.0",
"eslint": "^8.43.0",
"eslint-config-prettier": "^8.8.0",
"eslint-plugin-import": "^2.25.2",
Expand Down Expand Up @@ -98,5 +101,6 @@
},
"publishConfig": {
"access": "public"
}
},
"customElements": "dist/custom-elements.json"
}
30 changes: 18 additions & 12 deletions packages/components/src/accordion-item/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,14 @@ import {
} from '@microsoft/fast-foundation';
import { accordionItemStyles as styles } from './accordion-item.styles.js';

/**
* Accordion item class
*
* @public
* @tagname jp-accordion-item
*/
class JupyterAccordionItem extends AccordionItem {}

/**
* A function that returns a {@link @microsoft/fast-foundation#AccordionItem} registration for configuring the component with a DesignSystem.
* Implements {@link @microsoft/fast-foundation#accordionItemTemplate}
Expand All @@ -18,11 +26,13 @@ import { accordionItemStyles as styles } from './accordion-item.styles.js';
* @remarks
* Generates HTML Element: `<jp-accordion-item>`
*/
export const jpAccordionItem = AccordionItem.compose<AccordionItemOptions>({
baseName: 'accordion-item',
template,
styles,
collapsedIcon: /* html */ `
export const jpAccordionItem =
JupyterAccordionItem.compose<AccordionItemOptions>({
baseName: 'accordion-item',
baseClass: AccordionItem,
template,
styles,
collapsedIcon: /* html */ `
<svg
width="20"
height="20"
Expand All @@ -36,7 +46,7 @@ export const jpAccordionItem = AccordionItem.compose<AccordionItemOptions>({
/>
</svg>
`,
expandedIcon: /* html */ `
expandedIcon: /* html */ `
<svg
width="20"
height="20"
Expand All @@ -51,12 +61,8 @@ export const jpAccordionItem = AccordionItem.compose<AccordionItemOptions>({
/>
</svg>
`
});
});

/**
* Base class for Accordion item
* @public
*/
export { AccordionItem };
export { JupyterAccordionItem as AccordionItem };

export { styles as accordionItemStyles };
17 changes: 11 additions & 6 deletions packages/components/src/accordion/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,14 @@ import { accordionStyles as styles } from './accordion.styles.js';

export * from '../accordion-item/index.js';

/**
* Accordion class
*
* @public
* @tagname jp-accordion
*/
class JupyterAccordion extends Accordion {}

/**
* A function that returns a {@link @microsoft/fast-foundation#Accordion} registration for configuring the component with a DesignSystem.
* Implements {@link @microsoft/fast-foundation#accordionTemplate}
Expand All @@ -19,16 +27,13 @@ export * from '../accordion-item/index.js';
* @remarks
* Generates HTML Element: `<jp-accordion>`
*/
export const jpAccordion = Accordion.compose({
export const jpAccordion = JupyterAccordion.compose({
baseName: 'accordion',
baseClass: Accordion,
template,
styles
});

/**
* Base class for Accordion
* @public
*/
export { Accordion };
export { JupyterAccordion as Accordion };

export { styles as accordionStyles };
16 changes: 8 additions & 8 deletions packages/components/src/anchor/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,7 @@
// Distributed under the terms of the Modified BSD License.

import { attr } from '@microsoft/fast-element';
import {
Anchor as FoundationAnchor,
anchorTemplate as template
} from '@microsoft/fast-foundation';
import { Anchor, anchorTemplate as template } from '@microsoft/fast-foundation';
import { ButtonAppearance } from '../button/index.js';
import { anchorStyles as styles } from './anchor.styles.js';

Expand All @@ -17,10 +14,11 @@ import { anchorStyles as styles } from './anchor.styles.js';
export type AnchorAppearance = ButtonAppearance | 'hypertext';

/**
* Base class for Anchor
* Anchor class
* @public
* @tagname jp-anchor
*/
export class Anchor extends FoundationAnchor {
class JupyterAnchor extends Anchor {
/**
* The appearance the anchor should have.
*
Expand Down Expand Up @@ -80,14 +78,16 @@ export class Anchor extends FoundationAnchor {
*
* {@link https://developer.mozilla.org/en-US/docs/Web/API/ShadowRoot/delegatesFocus | delegatesFocus}
*/
export const jpAnchor = Anchor.compose({
export const jpAnchor = JupyterAnchor.compose({
baseName: 'anchor',
baseClass: FoundationAnchor,
baseClass: Anchor,
template,
styles,
shadowOptions: {
delegatesFocus: true
}
});

export { JupyterAnchor as Anchor };

export { styles as anchorStyles };
17 changes: 11 additions & 6 deletions packages/components/src/anchored-region/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,14 @@ import {
} from '@microsoft/fast-foundation';
import { anchoredRegionStyles as styles } from './anchored-region.styles.js';

/**
* Anchored region class
*
* @public
* @tagname jp-anchored-region
*/
class JupyterAnchoredRegion extends AnchoredRegion {}

/**
* A function that returns a {@link @microsoft/fast-foundation#AnchoredRegion} registration for configuring the component with a DesignSystem.
* Implements {@link @microsoft/fast-foundation#anchoredRegionTemplate}
Expand All @@ -17,16 +25,13 @@ import { anchoredRegionStyles as styles } from './anchored-region.styles.js';
* @remarks
* Generates HTML Element: `<jp-anchored-region>`
*/
export const jpAnchoredRegion = AnchoredRegion.compose({
export const jpAnchoredRegion = JupyterAnchoredRegion.compose({
baseName: 'anchored-region',
baseClass: AnchoredRegion,
template,
styles
});

/**
* Base class for AnchoredRegion
* @public
*/
export { AnchoredRegion };
export { JupyterAnchoredRegion as AnchoredRegion };

export { styles as anchoredRegionStyles };
17 changes: 10 additions & 7 deletions packages/components/src/avatar/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,18 @@
import { attr, html, when } from '@microsoft/fast-element';
import {
AvatarOptions,
Avatar as FoundationAvatar,
Avatar,
avatarTemplate as template
} from '@microsoft/fast-foundation';
import { avatarStyles as styles } from './avatar.styles.js';

/**
* The Jupyter Avatar Class
* @public
* Jupyter Avatar Class
*
* @public
* @tagname jp-avatar
*/
export class Avatar extends FoundationAvatar {
class JupyterAvatar extends Avatar {
/**
* Indicates the Avatar should have an image source
*
Expand All @@ -41,7 +42,7 @@ export class Avatar extends FoundationAvatar {
* @public
*
*/
export const imgTemplate = html<Avatar>`
export const imgTemplate = html<JupyterAvatar>`
${when(
x => x.imgSrc,
html`
Expand All @@ -65,9 +66,9 @@ export const imgTemplate = html<Avatar>`
* @remarks
* Generates HTML Element: `<jp-avatar>`
*/
export const jpAvatar = Avatar.compose<AvatarOptions>({
export const jpAvatar = JupyterAvatar.compose<AvatarOptions>({
baseName: 'avatar',
baseClass: FoundationAvatar,
baseClass: Avatar,
template,
styles,
media: imgTemplate,
Expand All @@ -76,4 +77,6 @@ export const jpAvatar = Avatar.compose<AvatarOptions>({
}
});

export { JupyterAvatar as Avatar };

export { styles as avatarStyles };
17 changes: 11 additions & 6 deletions packages/components/src/badge/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@
import { Badge, badgeTemplate as template } from '@microsoft/fast-foundation';
import { badgeStyles as styles } from './badge.styles.js';

/**
* Badge class
*
* @public
* @tagname jp-badge
*/
class JupyterBadge extends Badge {}

/**
* A function that returns a {@link @microsoft/fast-foundation#Badge} registration for configuring the component with a DesignSystem.
* Implements {@link @microsoft/fast-foundation#badgeTemplate}
Expand All @@ -14,16 +22,13 @@ import { badgeStyles as styles } from './badge.styles.js';
* @remarks
* Generates HTML Element: `<jp-badge>`
*/
export const jpBadge = Badge.compose({
export const jpBadge = JupyterBadge.compose({
baseName: 'badge',
baseClass: Badge,
template,
styles
});

/**
* Base class for Badge
* @public
*/
export { Badge };
export { JupyterBadge as Badge };

export { styles as badgeStyles };
Loading

0 comments on commit 7b55d5f

Please sign in to comment.