This repo is exploring translating components from native web components (Stencil.js) into front end frameworks, documentation tools, and design tools.
The goal is to show how patterns and components can be shared and reused through every step of the web publishing process. Designers, developers, and content authors can all leverage the same shared components as they work.
Components are written as web components using Stencil JS. These web components can then be easily translated into a number of frameworks and front-end environments. This repo shows how to use these components in the following contexts:
- A React app
- A Vue app
- An Angular app
- An Ember app
- A vanilla JS Express app
These same components can be used in design tools allowing you to design with our prebuilt components. Currently components have only been translated to two tools:
- Framer
- UXPin Merge
These components can also be used to give content authors high fidelity previews of the content they're editing from within their CMS. Currently this has only been set up for Storyblok.
All of these different stakeholders can also find information about these components in a single source of truth. The raw web components are documented in a Storybook instance.
This monorepo houses code showing how to enable all the integrations mentioned above. Most code is written using various front-end frameworks, JS, HTML, and CSS.
In the long run we'll likely want to publish a number of packages to a package registry:
- Vanilla Web Components
- React Components
- Vue Components
- FramerX Components
Individual projects can then easily install and reference the relevant components. However, this approach would slow down local development. For now, all files are referenced locally in between directories. A few hacks are required to make this work, but it should speed up local development.
The core of the project is a stencil.js directory. To develop these components run the following command:
# Navigate to the `stencil-components` directory
cd stencil-components
# Run and watch a stencil JS server
npm start
Most of our stencil component CSS is defined within our custom elements but a few CSS files are provided to improve the styling and allow theming of these components.
- document-styles.css — This file applies some base styles to your document so its styles will match our component styles
- custom-props.css — This file defines custom props which are referenced within the shadow DOM CSS of our custom elements.
- theme-example.css — This file is an (ugly) example of overriding the custom props defined above to theme our components.
- utilities.css — Coming soon...
- fonts.css — This file loads our brand fonts. It loads a variable version as well as a non-variable fallback. Omit this file if you're using an alternate font or font loading strategy.
For our font CSS to work our font files will need to be in the correct location in relation to the font CSS:
├─ css
| └── fonts.css
└ fonts
└── source-sans-pro-latin-extendeed
└── font files...
If you would like to load different fonts, or locate your fonts in a different location, you should omit fonts.css and add your own font loading strategy.
We recommend preloading the variable fonts. (Browsers that don't support variable fonts mostly don't support preloading so won't be affected.):
<link
rel="preload"
href="/assets/fonts/source-sans-pro-latin-extended/variable-italic.woff2"
as="font"
type="font/woff2"
/>
<link
rel="preload"
href="/assets/fonts/source-sans-pro-latin-extended/variable-regular.woff2"
as="font"
type="font/woff2"
/>
This repo is set up to export Stencil components to a variety of output targets
This project uses Stencil's @stencil/react-output-target
plugin to generate React wrappers for components. Building these components is a two step process:
- Building the output of our
stencil-components
directory which adds files to ourreact-components
directory - Building the output of our
react-components
directory with the new files fromstencil-components
This project uses Stencil's @stencil/angular-output-target
plugin to generate Angular wrappers for components. Building these components is a two step process:
- Building the output of our
stencil-components
directory which adds files to ourangular-components
directory - Building the output of our
angular-components
directory with the new files fromstencil-components
This project uses Stencil's @stencil/vue-output-target
plugin to generate Vue wrappers for components. Building these components is a two step process:
- Building the output of our
stencil-components
directory which adds files to ourvue-components
directory - Building the output of our
vue-components
directory with the new files fromstencil-components
Before building components you'll need to install all the component dependencies by running npm run install:components
from the project root.(/
). Then you can build Stencil components, convert them to React components, and populate our various apps in a single command: npm run build:components
.
After running npm run build:components
you can develop the Express app by running the following commands:
# Navigate to the `express-app` directory
cd express-app
# Install dependencies
npm ci
# Run and watch a Express server
npm start
There's currently an issue where the app doesn't report the URL for you to visit. This should generally be http://localhost:3000/
Our React components are consumed by a simple React app. After building our React components you can develop this site by running the following commands:
# Navigate to the `react-app` directory
cd react-app
# Install dependencies
npm ci
# Run and watch a React server
npm start
Our Angular components are consumed by a simple Angular app. After building our Angular components you can develop this site by running the following commands:
# Navigate to the `angular-app` directory
cd angular-app
# Install dependencies
npm ci
# Run and watch an Angular server
npm start
Our Vue components are consumed by a simple Vue app. After building our Vue components you can develop this site by running the following commands:
# Navigate to the `vue-app` directory
cd vue-app
# Install dependencies
npm ci
# Run and watch a Vue server
npm start
We're able to use the ember-cli-stencil to pull Stencil components into the Ember app. However, they're still using the native component API and syntax. If you want the Ember syntax you'll need to manually wrap your web components as Ember components.
Luckily, Ember works well with web components, so it doesn't take a ton of work to create wrappers. You can see some examples in our Ember app. To run the Ember app, run the following commands:
# Navigate to the `ember-app` directory
cd ember-app
# Install dependencies
npm ci
# Run and watch a Ember server
npm start
We currently don't have an example of a Svelte site, but Stencil recently added a Svelte output target so it would be easy to automatically generate the components.
Framer X allows us to import these same React components and use them in a graphical editor.
Each component we want to use needs a special Framer X wrapper to allow us to import the component and interact with its props.
Unfortunately there's currently an additional manual step to allow our react components to be used in Framer X.
After building our React components, navigate to react-components/dist/components.js
and update the following import statement:
../../stencil-components/loader
--> ../../stencil-components/loader/index.cjs.js
I think there's a disconnect between TypeScript and JavaScript imports here. I'm sure there's a solution, but I haven't dug into it yet.
After building the components and making that change you should be able to open the components.framerfx
file in Framer X and begin designing with components.
For this to work you'll need access to UXPin Merge which is in early access. Then you'll need to make the same change mentioned for Framer:
../../stencil-components/loader
--> ../../stencil-components/loader/index.cjs.js
Then you should be able to UXPin merge:
# Navigate to the `uxpin` directory
cd uxpin
# Install dependencies
npm ci
# Run UXPin merge
npm start
In the long term we'll explore pushing up components using CI but this works for now.
The web components are also documented in storybook. After running the stencil-components
project, or running npm run build:components
Storybook should
be ready to document these components. To launch storybook run the following
commands
# Navigate to the `storybook` directory
cd storybook
# Install dependencies
npm ci
# Run and watch a Storybook server
npm run storybook
These components have been hooked up to a Storyblok CMS instance. These components are used to show a high fidelity preview of the rendered pages as they edit content.
In order to actually test this out you'll need to have an account with access to our Storyblok instance. You'll then add your API key to the .env
file in the Storyblok directory, run npm start
and load the editor at storyblok.com