Skip to content

Commit

Permalink
✨ dsd article
Browse files Browse the repository at this point in the history
  • Loading branch information
scottnath authored Feb 21, 2024
1 parent 9f772e3 commit e4dead2
Show file tree
Hide file tree
Showing 8 changed files with 22,771 additions and 20,478 deletions.
43,019 changes: 22,584 additions & 20,435 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,6 @@
"workspaces/*"
],
"devDependencies": {
"astro": "^4.0.3"
"astro": "^4.4.2"
}
}
4 changes: 2 additions & 2 deletions workspaces/components/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"author": "scottnath",
"license": "MIT",
"devDependencies": {
"storydocker-storybook": "^0.0.18",
"storydocker-utilities": "^0.0.13"
"storydocker-storybook": "^0.0.22",
"storydocker-utilities": "^0.0.16"
}
}
28 changes: 14 additions & 14 deletions workspaces/website/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,29 +14,29 @@
"site-files": "npm run 404file && npm run jekyllfile && npm run cname"
},
"dependencies": {
"@astrojs/mdx": "^2.0.0",
"@astrojs/react": "^3.0.7",
"@astrojs/rss": "^4.0.1",
"@astrojs/sitemap": "^3.0.3",
"@types/react": "^18.2.42",
"@types/react-dom": "^18.2.17",
"@astrojs/mdx": "^2.1.1",
"@astrojs/react": "^3.0.10",
"@astrojs/rss": "^4.0.5",
"@astrojs/sitemap": "^3.1.1",
"@types/react": "^18.2.57",
"@types/react-dom": "^18.2.19",
"@webcomponents/template-shadowroot": "^0.2.1",
"airtable": "^0.12.2",
"astro": "^4.0.3",
"marked": "^11.0.1",
"profile-components": "^0.2.5",
"astro": "^4.4.2",
"marked": "^12.0.0",
"profile-components": "^0.3.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"typescript": "^5.3.3"
},
"devDependencies": {
"@astrojs/partytown": "^2.0.2",
"@astrojs/partytown": "^2.0.4",
"@storybook/testing-library": "^0.2.2",
"@testing-library/react": "^14.1.2",
"astro-icon": "^0.8.2",
"@testing-library/react": "^14.2.1",
"astro-icon": "^1.1.0",
"postcss-nested": "^6.0.1",
"prop-types": "^15.8.1",
"sass": "^1.69.5",
"vite": "^5.0.7"
"sass": "^1.71.1",
"vite": "^5.1.4"
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
15 changes: 3 additions & 12 deletions workspaces/website/src/components/DevToUser.astro
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
---
// @todo: vite, via astro, doesn't support dynamic imports yet
// @see https://github.com/withastro/astro/issues/8660
// @future-feature: import { user } from 'profile-components/devto-utils';
import devto from 'profile-components/devto-utils';
import {dsd} from 'profile-components/devto-utils';
import profilePic from '~/assets/scott-nath-profile-photo.jpeg';
const user = devto.user;
const popularPost = {
"title": "Running a local multi-framework composition Storybook",
Expand All @@ -13,17 +9,12 @@ const popularPost = {
"social_image": "https://res.cloudinary.com/practicaldev/image/fetch/s--HJA-rw9l--/c_imagga_scale,f_auto,fl_progressive,h_500,q_auto,w_1000/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jv4luam96ya9sxsjotjx.png",
}
const userContent = await user.generateContent({
const declaredDOM = dsd({
username: 'scottnath',
profile_image: profilePic.src,
popular_post: popularPost,
},true);
let userHTML = '<style>' + user.styles + '</style>';
userHTML += user.html(userContent);
---

<devto-user data-theme="dark">
<template shadowrootmode="open" set:html={userHTML}>
</template>
</devto-user>
<devto-user data-theme="dark" set:html={declaredDOM}></devto-user>

19 changes: 5 additions & 14 deletions workspaces/website/src/components/GitHubUser.astro
Original file line number Diff line number Diff line change
@@ -1,23 +1,14 @@
---
// @todo: vite, via astro, doesn't support dynamic imports yet
// @see https://github.com/withastro/astro/issues/8660
// @future-feature: import { user } from 'profile-components/github-utils';
import github from 'profile-components/github-utils';
import {dsd} from 'profile-components/github-utils';
import profilePic from '~/assets/scott-nath-profile-photo.jpeg';
const user = github.user;
const repos = JSON.stringify(['scottnath/profile-components', 'storydocker/storydocker']);
const userContent = await user.generateContent({
const declaredDOM = await dsd({
login: 'scottnath',
avatar_url: profilePic.src,
repos
},true);
let userHTML = '<style>' + user.styles + '</style>';
userHTML += user.html(userContent);
---
},true)
<github-user data-theme="light_high_contrast">
<template shadowrootmode="open" set:html={userHTML}>
</template>
</github-user>
---

<github-user data-theme="light_high_contrast" set:html={declaredDOM}></github-user>
162 changes: 162 additions & 0 deletions workspaces/website/src/content/blahg/profile-components--dsd.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
---
title: "Profile Components: SSR with Declarative Shadow DOM"
description: "Enhancing Profile Components with Declarative Shadow DOM and showing examples for Server Side Rendering"
pubDate: "2024-02-21"
heroImage: "/profile-components-blahg/profile-components-dsd-header.png"
---


With the [official release of `shadowrootmode`-supporting Firefox v123](https://developer.mozilla.org/en-US/docs/Mozilla/Firefox/Releases/123#html), it's time to upgrade the profile components with Declarative Shadow DOM functionality!

## tl;dr

* [DSD docs for GitHub profile components][docs-github]
* [DSD docs for dev.to profile components][docs-devto]
* [See the Stackblitz client-side example][stackblitz-page]

---

## What is this?

Four new methods have been added to allow generating a `template` tag with `shadowrootmode` containing the generated HTML and styles of a profile component. This was fairly trivial to add due to the Javascript, HTML and CSS living in separate files. (see [👷 DX: Separate files for Javascript, HTML, and CSS][profile-components-article-dx]).

Each of the four components now have a `dsd` method which can be used to generate something like this:

```html
<template shadowrootmode="open">
<styles>(...css styles for GitHub component)</styles>
<section (...rest of generated HTML)</section>
</template>
```

This generated `template` can be used server-side when generating HTML output, or client-side after page load. Although...doing this client-side is weird frankly...like...they're web components, just use them as they were written...who knows though, maybe someone has a use for that feature 🤷.

## How to use the Declarative Shadow DOM methods

Below are some examples of usage of the GitHub component ([see GitHub DSD docs][docs-github]). Usage of the DEV components is pretty much the same - [check out the dev.to DSD docs][docs-devto] for DEV usage examples.

The main value of these is when create HTML _before_ it is rendered by the browser. Then when the browser renders it, the browser converts the DSD into actual Shadow DOM. These components are only presentational and do not have functionality added by the customElement - so DSD or regular web component usage results in the same thing!


### SSR (Server Side Rendering) HTML in Node.js

```javascript
// import from npm module
import { dsd } from 'profile-components/github-utils';

const repos = JSON.stringify([
'scottnath/profile-components',
'storydocker/storydocker'
]);

const generatedTemplate = await dsd({
login: 'scottnath',
avatar_url: profilePic.src,
repos
},true);

/**
generatedTemplate contains:
<template shadowrootmode="open">
<styles>(...css styles for GitHub component)</styles>
<section (...rest of generated HTML)</section>
</template>
*/

// use this variable in a file pre-render to have a DSD-pre-populated element
const componentHTML = `<github-user>${generatedTemplate}</github-user>`;
```

### Server side render in an Astro component

```javascript
---
import {dsd} from 'profile-components/github-utils';

const repos = JSON.stringify(['scottnath/profile-components', 'storydocker/storydocker']);
const declaredDOM = await dsd({
login: 'scottnath',
repos
},true)
---

<github-user
data-theme="light_high_contrast"
set:html={declaredDOM}>
</github-user>
```

### Client side rendering via unpkg

```html
<!-- add empty elements to HTML -->
<github-repository></github-repository>
<hr />
<github-user></github-user>

<script type="module">
// import from unpkg
import {
user,
repo,
} from 'https://unpkg.com/profile-components/dist/github-utils.js';
// repo has it's own DSD method:
const dsdRepo = repo.dsd;
/**
* Polyfill for Declarative Shadow DOM which, when triggered, converts
* the template element into actual shadow DOM.
* This is only needed when injecting _after_ page is loaded
* @see https://developer.chrome.com/docs/css-ui/declarative-shadow-dom#polyfill
*/
const triggerAttachShadowRoots = () => {
(function attachShadowRoots(root) {
root
.querySelectorAll('template[shadowrootmode]')
.forEach((template) => {
const mode = template.getAttribute('shadowrootmode');
const shadowRoot = template.parentNode.attachShadow({ mode });
shadowRoot.appendChild(template.content);
template.remove();
attachShadowRoots(shadowRoot);
});
})(document);
};
/**
* Uses the "dsd" method to generate DSD, add the string of DSD content
* to the element, then trigger the polyfill to convert the template
*/
const injectDSD = async () => {
const dsdHTML = await dsd({ username: 'scottnath' }, true);
document.querySelector('github-user').innerHTML = dsdHTML;
// now that the HTML is async-created, the polyfill can convert it
triggerAttachShadowRoots();
};
injectDSD();
/**
* Uses the "dsdRepo" method to generate DSD, add the string of DSD content
* to the element, then trigger the polyfill to convert the template
*/
const injectRepoDSD = async () => {
const dsdHTML = await dsdRepo(
{ full_name: 'scottnath/profile-components' },
true
);
document.querySelector('github-repository').innerHTML = dsdHTML;
// now that the HTML is async-created, the polyfill can convert it
triggerAttachShadowRoots();
};
injectRepoDSD();
</script>
```

<iframe width="100%" height="500" src="https://stackblitz.com/edit/profile-components?embed=1&file=github-dsd.html&view=preview&initialpath=github-dsd.html"></iframe>


[profile-components-article-dx]: /blahg/profile-components/#👷
[stackblitz-page]:https://stackblitz.com/edit/profile-components?file=github-dsd.html&initialpath=github-dsd.html&view=preview
[docs-devto]:https://scottnath.com/profile-components/?path=/docs/devto-declarative-shadow-dom--docs
[docs-github]:https://scottnath.com/profile-components/?path=/docs/github-declarative-shadow-dom--docs

0 comments on commit e4dead2

Please sign in to comment.