Cross Framework Components
❤️
What / why
Building
Using
Profit
❓
🏗
👩💻
🎉
Setting the scene
Component based development
Reusability
My team uses React
My team uses Vue
😢
Web Components
What are Web Components?
- Based on existing web standards
- A set of 'new' standards
- Recommended W3C Standards
Standards
- Custom Elements
- Shadow DOM
- ES Modules
- HTML Template
Custom Elements
Shadow DOM
ES Modules
HTML Templates
So...
Building a
Web Component
Build the component
function getStyles() { /*...*/ }
function getTemplate(styles) { /*...*/ }
class SocialShareNative extends HTMLElement {
constructor() {
this._shadowRoot = this.attachShadow({ mode: 'open' })
this._shadowRoot.innerHTML = getTemplate(getStyles())
}
connectedCallback() { /*...*/ }
get show() {
return this.hasAttribute('show')
}
set show(val) {
val
? this.setAttribute('show', '')
: this.removeAttribute('show')
}
}
customElements.define('social-share-native', SocialShareNative);
function getTemplate(styles) {
return`
${styles}
<div class="wrapper">
<strong class="platform">JS</strong>
<button class="toggle"><img src="/images/share.svg" alt="share"/></button>
<ul class="list">
<li class="list-item">
<button data-platform="facebook">
<img src="/images/facebook.svg" alt="facebook"/>
</button>
</li>
<li class="list-item">
<button data-platform="twitter">
<img src="/images/twitter.svg" alt="twitter"/>
</button>
</li>
<li class="list-item">
<button data-platform="whatsapp">
<img src="/images/whatsapp.svg" alt="whatsapp"/>
</button>
</li>
</ul>
</div>
`
}
connectedCallback() {
const wrapper = this._shadowRoot.querySelector('.wrapper')
const toggle = this._shadowRoot.querySelector('.toggle')
const listItemButtons = Array.from(this._shadowRoot.querySelectorAll('.list-item button'))
wrapper.addEventListener('click', event => {
if (event.target === toggle) {
this.show = !this.show
}
if (listItemButtons.indexOf(event.target) !== -1) {
this.dispatchEvent(
new CustomEvent('share-to', {
detail: event.target.dataset.platform,
bubbles: true,
})
)
this.show = false
}
})
}
function getStyles() {
return `
<style>
/* A lot more css code */
:host([show]) .toggle {
background-color: blue;
}
:host(:not([show])) .list-item {
transform: translate(0) !important;
opacity: 0;
}
</style>
`
}
Use the
Web Component
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Social Share Native</title>
</head>
<body>
<social-share-native></social-share-native>
<script type="module" src="native/social-share-native.js"></script>
</body>
</html>
Plain HTML
import 'path/to/social-share-native.js'
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
open: undefined
}
}
render() {
return <social-share-native show={this.state.open}/>;
}
}
React
<template>
<social-share-native :show="open"></social-share-native>
</template>
<script>
import 'path/to/social-share-native'
export default {
data: () => ({
open: false
})
}
</script>
Vue
🎉
"But... But... But...
I know React!
Their tooling is way superior!!1!11!"
Stencil JS
- Uses JSX
- Uses classes
- Full TypeScript support
- React devs will feel right at home
import { Component, Prop, State, Event, EventEmitter } from '@stencil/core';
@Component({
tag: 'social-share-stencil',
styleUrl: 'social-share-stencil.css',
shadow: true
})
export class SocialShareStencil {
@Prop({ mutable: true, reflectToAttr: true}) show: boolean;
@Event({ eventName: 'share-to', bubbles: true }) shareTo: EventEmitter
@State() platforms = ['facebook', 'twitter', 'linkedin', 'whatsapp']
render() {
return (
<div class="wrapper">
{/* All template code */}
</div>
);
}
}
Svelte JS
- Syntax very close to Vue
- Focus on HTML, CSS and JS
"Svelte turns your templates into tiny,
framework-less vanilla JavaScript"
<div class="wrapper">
<!-- Rest of template code -->
</div>
<style>
.wrapper {
position: relative;
}
/* Rest of css code */
</style>
<script>
export default {
tag: 'social-share-svelte',
props: ['show'],
data: () => ({ show: false }),
oncreate() { /* .. */ },
methods: {
choosePlatform(platform) { /* Dispatch event */ }
}
};
</script>
VueJS
- Use a familiar framework
- All baked into Vue-cli 3
⚠️ I'd advise agains it... ⚠️
React JS
Creating web components in frameworks you are familiar with
The X in
Cross Framework Components
Use natively
Use in React
Use in Vue
Usecases
From now on
Web Components all the way?
Stateless components
Web Components
⬇️
Thank you!
cross-framework-components
By Peter Goes
cross-framework-components
- 1,530