mirror of
https://github.com/modernweb-dev/rocket.git
synced 2026-03-21 08:51:18 +00:00
Compare commits
20 Commits
@mdjs/mdjs
...
@mdjs/mdjs
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
22393dd172 | ||
|
|
a6fdb31f1e | ||
|
|
dd15d4fc65 | ||
|
|
edb1abf82b | ||
|
|
0b6411661e | ||
|
|
604a80e6cb | ||
|
|
fe6a929f1e | ||
|
|
2267e728cf | ||
|
|
abc8a02b72 | ||
|
|
2270887faf | ||
|
|
bad4686506 | ||
|
|
818caad7cb | ||
|
|
672b7e893e | ||
|
|
a8e66d84f4 | ||
|
|
e9090d64b9 | ||
|
|
728a205b7b | ||
|
|
67ba29d45a | ||
|
|
758caffdf9 | ||
|
|
302227e8a9 | ||
|
|
04a31220fb |
10
docs/_assets/body.css
Normal file
10
docs/_assets/body.css
Normal file
@@ -0,0 +1,10 @@
|
||||
html {
|
||||
--demo-background-color: #eee;
|
||||
--demo-color: #222;
|
||||
}
|
||||
|
||||
html[theme="dark"] body {
|
||||
background: #333;
|
||||
--demo-background-color: #888;
|
||||
--demo-color: #eee;
|
||||
}
|
||||
@@ -7,3 +7,5 @@
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<meta name="twitter:creator" content="@modern_web_dev" />
|
||||
|
||||
<link rel="stylesheet" href="{{ '/_assets/body.css' | asset | url }}" mdjs-use>
|
||||
|
||||
69
docs/docs/markdown-javascript/assets/demo-element.js
Normal file
69
docs/docs/markdown-javascript/assets/demo-element.js
Normal file
@@ -0,0 +1,69 @@
|
||||
class DemoElement extends HTMLElement {
|
||||
constructor() {
|
||||
super();
|
||||
this.attachShadow({ mode: 'open' });
|
||||
|
||||
this.platform = 'the web';
|
||||
this.language = 'en-US';
|
||||
this.theme = 'light';
|
||||
|
||||
this.observer = new MutationObserver(this.updateData);
|
||||
}
|
||||
|
||||
updateData = () => {
|
||||
this.platform = document.documentElement.getAttribute('platform') || 'the web';
|
||||
this.language = document.documentElement.getAttribute('data-lang') || 'en-US';
|
||||
this.theme = document.documentElement.getAttribute('theme') || 'light';
|
||||
this.requestUpdate();
|
||||
};
|
||||
|
||||
connectedCallback() {
|
||||
this.updateData();
|
||||
|
||||
this.observer.observe(document.documentElement, { attributes: true });
|
||||
}
|
||||
|
||||
requestUpdate() {
|
||||
this.shadowRoot.innerHTML = this.render();
|
||||
}
|
||||
|
||||
render() {
|
||||
return `
|
||||
<style>
|
||||
:host {
|
||||
display: block;
|
||||
background: var(--demo-background-color);
|
||||
color: var(--demo-color);
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
:host[platform~="web"] {
|
||||
border-bottom: 2px solid #333;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 640px) {
|
||||
.about {
|
||||
display: flex;
|
||||
}
|
||||
.about ul {
|
||||
width: 50%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<p>Hello I am DemoElement 👋</p>
|
||||
<div class="about">
|
||||
<ul>
|
||||
<li>My purpose is to demonstrate how an element can adopt to different environments</li>
|
||||
<li>I like <strong>${this.platform}</strong></li>
|
||||
</ul>
|
||||
<ul>
|
||||
<li>My mother languages is <strong>${this.language}</strong></li>
|
||||
<li>I feel very comfortable in the <strong>${this.theme}</strong></li>
|
||||
</ul>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define('demo-element', DemoElement);
|
||||
@@ -56,8 +56,8 @@ mdjs comes with some additional helpers you can choose to import:
|
||||
|
||||
````md
|
||||
```js script
|
||||
import '@mdjs/mdjs-story/mdjs-story.js';
|
||||
import '@mdjs/mdjs-preview/mdjs-preview.js';
|
||||
import '@mdjs/mdjs-story/define';
|
||||
import '@mdjs/mdjs-preview/define';
|
||||
```
|
||||
````
|
||||
|
||||
@@ -65,8 +65,8 @@ Once loaded you can use them like so:
|
||||
|
||||
````md
|
||||
```js script
|
||||
import '@mdjs/mdjs-story/mdjs-story.js';
|
||||
import '@mdjs/mdjs-preview/mdjs-preview.js';
|
||||
import '@mdjs/mdjs-story/define';
|
||||
import '@mdjs/mdjs-preview/define';
|
||||
```
|
||||
````
|
||||
|
||||
@@ -118,8 +118,8 @@ export const JsPreviewStory = () => html` <demo-wc-card>JS Preview Story</demo-w
|
||||
Here is a live example from [demo-wc-card](https://www.npmjs.com/package/demo-wc-card).
|
||||
|
||||
```js script
|
||||
import '@mdjs/mdjs-story/mdjs-story.js';
|
||||
import '@mdjs/mdjs-preview/mdjs-preview.js';
|
||||
import '@mdjs/mdjs-story/define';
|
||||
import '@mdjs/mdjs-preview/define';
|
||||
import { html } from 'lit-html';
|
||||
```
|
||||
|
||||
@@ -132,31 +132,6 @@ export const header = () => {
|
||||
|
||||
## Supported Systems
|
||||
|
||||
### es-dev-server
|
||||
|
||||
Preview your mdjs readme with live demos and auto reload.
|
||||
|
||||
- Add to your `package.json`:
|
||||
|
||||
```json
|
||||
"scripts": {
|
||||
"start": "es-dev-server",
|
||||
}
|
||||
```
|
||||
|
||||
- Create a `es-dev-server.config.js` in the root of your repository.
|
||||
|
||||
```js
|
||||
const { mdjsTransformer } = require('@mdjs/core');
|
||||
|
||||
module.exports = {
|
||||
nodeResolve: true,
|
||||
open: 'README.md',
|
||||
watch: true,
|
||||
responseTransformers: [mdjsTransformer],
|
||||
};
|
||||
```
|
||||
|
||||
### Storybook
|
||||
|
||||
Please check out [@open-wc/demoing-storybook](https://open-wc.org/demoing/) for a fully integrated setup.
|
||||
|
||||
@@ -2,18 +2,165 @@
|
||||
|
||||
You can showcase live running code by annotating a code block with `js preview-story`.
|
||||
|
||||
````md
|
||||
```js preview-story
|
||||
import { html } from 'lit-html';
|
||||
## Features
|
||||
|
||||
export const foo = () => html` <p>my html</p> `;
|
||||
- Shows components inside the page as they are
|
||||
- You can enable “Simulation Mode” to break them out
|
||||
- Simulation mode renders in an iframe to supporting media queries and isolated Simulation settings
|
||||
- Simulation Settings
|
||||
- Style (windows, mac, android, iOS)
|
||||
- Size (small, medium, large, Galaxy S5, iPhone X, iPad …)
|
||||
- Automatic Height
|
||||
- Theme (light, dark)
|
||||
- Language (en, nl, …)
|
||||
- Settings are ”global” for all Simulators (e.g. changing one will change all)
|
||||
- Settings can be remembered for other pages / return visits
|
||||
|
||||
```js script
|
||||
import { html } from 'lit-html';
|
||||
import './assets/demo-element.js';
|
||||
```
|
||||
|
||||
## JavaScript Story
|
||||
|
||||
````md
|
||||
```js script
|
||||
import { html } from 'lit-html';
|
||||
import './assets/demo-element.js';
|
||||
```
|
||||
|
||||
```js preview-story
|
||||
export const foo = () => html`<demo-element></demo-element>`;
|
||||
```
|
||||
````
|
||||
|
||||
will result in
|
||||
|
||||
```js preview-story
|
||||
import { html } from 'lit-html';
|
||||
|
||||
export const foo = () => html` <p>my html</p> `;
|
||||
export const foo = () => html` <demo-element></demo-element> `;
|
||||
```
|
||||
|
||||
## HTML Story
|
||||
|
||||
````md
|
||||
```html preview-story
|
||||
<demo-element></demo-element>
|
||||
```
|
||||
````
|
||||
|
||||
will result in
|
||||
|
||||
```html preview-story
|
||||
<demo-element></demo-element>
|
||||
```
|
||||
|
||||
## Setup Simulation Mode
|
||||
|
||||
For simulation mode we need a dedicated html file that will be used as an iframe target while loading stories.
|
||||
|
||||
The fastest way to create such a file is to use the `layout-simulator` layout.
|
||||
|
||||
Create a file `docs/simulator.md` with the following content.
|
||||
|
||||
```md
|
||||
---
|
||||
layout: layout-simulator
|
||||
eleventyExcludeFromCollections: true
|
||||
excludeFromSearch: true
|
||||
---
|
||||
```
|
||||
|
||||
Once you have that you need to configure it for the story renderer by setting it in your `rocket.config.js`.
|
||||
|
||||
```js
|
||||
export default {
|
||||
setupUnifiedPlugins: [
|
||||
adjustPluginOptions('mdjsSetupCode', {
|
||||
simulationSettings: { simulatorUrl: '/simulator/' },
|
||||
}),
|
||||
],
|
||||
};
|
||||
```
|
||||
|
||||
<inline-notification type="tip">
|
||||
|
||||
You can freely choose the path for the "simulator" by creating the md file in a different folder and adjusting the path in the config.
|
||||
|
||||
</inline-notification>
|
||||
|
||||
## Simulator states
|
||||
|
||||
To simulate these stats that usually come from the device itself we put those infos on the document tag.
|
||||
|
||||
We can simulate the following settings
|
||||
|
||||
1. `platform`
|
||||
Adopting styles and behavior depending on which device platform you are.
|
||||
```html
|
||||
<html platform="web"></html>
|
||||
<html platform="android"></html>
|
||||
<html platform="ios"></html>
|
||||
<!-- potentially later -->
|
||||
<html platform="web-windows"></html>
|
||||
<html platform="web-mac"></html>
|
||||
```
|
||||
2. `theme`
|
||||
Adjust your styles based on a theme - light/dark are the default but you can add as many as you want.
|
||||
```html
|
||||
<html theme="light"></html>
|
||||
<html theme="dark"></html>
|
||||
```
|
||||
3. `language`
|
||||
Best to relay on `data-lang` and `lang` often gets changes by translations services which may interfere with you translation loading system.
|
||||
```html
|
||||
<html lang="en-US" data-lang="en-US"></html>
|
||||
<html lang="de-DE" data-lang="de-DE"></html>
|
||||
```
|
||||
|
||||
If you want to react to such document changes you can use an [MutationObserver](https://developer.mozilla.org/de/docs/Web/API/MutationObserver).
|
||||
|
||||
For a vanilla web component it could look something like this:
|
||||
|
||||
```js
|
||||
class DemoElement extends HTMLElement {
|
||||
constructor() {
|
||||
super();
|
||||
this.attachShadow({ mode: 'open' });
|
||||
|
||||
this.platform = 'the web';
|
||||
this.language = 'en-US';
|
||||
this.theme = 'light';
|
||||
|
||||
this.observer = new MutationObserver(this.updateData);
|
||||
}
|
||||
|
||||
updateData = () => {
|
||||
this.platform = document.documentElement.getAttribute('platform') || 'the web';
|
||||
this.language = document.documentElement.getAttribute('data-lang') || 'en-US';
|
||||
this.theme = document.documentElement.getAttribute('theme') || 'light';
|
||||
this.requestUpdate();
|
||||
};
|
||||
|
||||
connectedCallback() {
|
||||
this.updateData();
|
||||
|
||||
this.observer.observe(document.documentElement, { attributes: true });
|
||||
}
|
||||
|
||||
requestUpdate() {
|
||||
this.shadowRoot.innerHTML = this.render();
|
||||
}
|
||||
|
||||
render() {
|
||||
return `
|
||||
...
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define('demo-element', DemoElement);
|
||||
```
|
||||
|
||||
```js script
|
||||
import '@rocket/launch/inline-notification/inline-notification.js';
|
||||
```
|
||||
|
||||
@@ -2,10 +2,16 @@
|
||||
|
||||
You can showcase live running code by annotating a code block with `js story`.
|
||||
|
||||
````md
|
||||
```js story
|
||||
```js script
|
||||
import { html } from 'lit-html';
|
||||
```
|
||||
|
||||
````md
|
||||
```js script
|
||||
import { html } from 'lit-html';
|
||||
```
|
||||
|
||||
```js story
|
||||
export const foo = () => html` <p>my html</p> `;
|
||||
```
|
||||
````
|
||||
@@ -13,7 +19,5 @@ export const foo = () => html` <p>my html</p> `;
|
||||
will result in
|
||||
|
||||
```js story
|
||||
import { html } from 'lit-html';
|
||||
|
||||
export const foo = () => html` <p>my html</p> `;
|
||||
```
|
||||
|
||||
@@ -47,3 +47,9 @@ export const headlineConverter = () => html`
|
||||
```
|
||||
|
||||
How it then works is very similar to https://www.11ty.dev/docs/plugins/navigation/
|
||||
|
||||
## Sidebar redirects
|
||||
|
||||
By default, the sidebar nav redirects clicks on category headings to the first child page in that category.
|
||||
|
||||
To disable those redirects, override `_includes/_joiningBlocks/_layoutSidebar/sidebar/20-navigation.njk` and add the `no-redirects` attribute to the `<rocket-navigation>` element.
|
||||
|
||||
5
docs/simulator.md
Normal file
5
docs/simulator.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
layout: layout-simulator
|
||||
eleventyExcludeFromCollections: true
|
||||
excludeFromSearch: true
|
||||
---
|
||||
@@ -38,6 +38,6 @@
|
||||
"testing"
|
||||
],
|
||||
"dependencies": {
|
||||
"plugins-manager": "^0.2.0"
|
||||
"plugins-manager": "^0.2.1"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# @rocket/building-rollup
|
||||
|
||||
## 0.2.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- bad4686: Preserve attributes on script tags. Preserve export names.
|
||||
|
||||
## 0.1.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@rocket/building-rollup",
|
||||
"version": "0.1.3",
|
||||
"version": "0.2.0",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
@@ -13,8 +13,8 @@
|
||||
},
|
||||
"author": "Modern Web <hello@modern-web.dev> (https://modern-web.dev/)",
|
||||
"homepage": "https://rocket.modern-web.dev/docs/tools/building-rollup/",
|
||||
"type": "module",
|
||||
"main": "./index.js",
|
||||
"type": "module",
|
||||
"exports": {
|
||||
".": "./index.js"
|
||||
},
|
||||
@@ -55,9 +55,9 @@
|
||||
"@babel/preset-env": "^7.12.11",
|
||||
"@rollup/plugin-babel": "^5.2.2",
|
||||
"@rollup/plugin-node-resolve": "^11.0.1",
|
||||
"@web/rollup-plugin-html": "^1.4.0",
|
||||
"@web/rollup-plugin-html": "^1.6.0",
|
||||
"@web/rollup-plugin-import-meta-assets": "^1.0.4",
|
||||
"@web/rollup-plugin-polyfills-loader": "^1.0.3",
|
||||
"@web/rollup-plugin-polyfills-loader": "^1.1.0",
|
||||
"browserslist": "^4.16.1",
|
||||
"rollup-plugin-terser": "^7.0.2",
|
||||
"rollup-plugin-workbox": "^6.1.0"
|
||||
|
||||
@@ -22,7 +22,7 @@ export function createBasicMetaConfig(userConfig = { output: {} }) {
|
||||
const assetName = `[${developmentMode ? 'name' : 'hash'}][extname]`;
|
||||
|
||||
const config = {
|
||||
preserveEntrySignatures: false,
|
||||
preserveEntrySignatures: 'strict',
|
||||
treeshake: !developmentMode,
|
||||
setupPlugins: [],
|
||||
...userConfig,
|
||||
|
||||
@@ -75,6 +75,14 @@ describe('createMapConfig', () => {
|
||||
'<h1>Has js in sub-js/index.html</h1>\n\n\n<script type="module" src="../sub-js.js"></script>',
|
||||
);
|
||||
|
||||
const subJsAbsoluteIndexHtml = await readOutput('sub-js-absolute/index.html', {
|
||||
stripToBody: true,
|
||||
stripServiceWorker: true,
|
||||
});
|
||||
expect(subJsAbsoluteIndexHtml).to.equal(
|
||||
'<h1>Has js in sub-js-absolute/index.html</h1>\n\n\n<script type="module" src="../sub-js-absolute.js"></script>',
|
||||
);
|
||||
|
||||
const serviceWorkerJs = await readOutput('service-worker.js');
|
||||
expect(serviceWorkerJs).to.include('Promise'); // not empty string might be enough...
|
||||
});
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
<h1>Has js in sub-js-absolute/index.html</h1>
|
||||
<script type="module" src="/sub-js-absolute/sub-js-absolute.js"></script>
|
||||
@@ -13,11 +13,11 @@
|
||||
},
|
||||
"author": "Modern Web <hello@modern-web.dev> (https://modern-web.dev/)",
|
||||
"homepage": "https://rocket.modern-web.dev/docs/tools/check-html-links/",
|
||||
"main": "./index.js",
|
||||
"bin": {
|
||||
"check-html-links": "src/cli.js"
|
||||
},
|
||||
"type": "module",
|
||||
"main": "./index.js",
|
||||
"exports": {
|
||||
".": "./index.js"
|
||||
},
|
||||
|
||||
@@ -1,5 +1,15 @@
|
||||
# @rocket/cli
|
||||
|
||||
## 0.6.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- abc8a02: You can now use an absolute path for the rootDir
|
||||
- Updated dependencies [bad4686]
|
||||
- Updated dependencies [2267e72]
|
||||
- @rocket/building-rollup@0.2.0
|
||||
- @rocket/eleventy-plugin-mdjs-unified@0.4.0
|
||||
|
||||
## 0.6.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@rocket/cli",
|
||||
"version": "0.6.0",
|
||||
"version": "0.6.1",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
@@ -13,11 +13,11 @@
|
||||
},
|
||||
"author": "Modern Web <hello@modern-web.dev> (https://modern-web.dev/)",
|
||||
"homepage": "https://rocket.modern-web.dev/",
|
||||
"main": "./index.cjs",
|
||||
"bin": {
|
||||
"rocket": "src/cli.js"
|
||||
},
|
||||
"type": "module",
|
||||
"main": "./index.cjs",
|
||||
"exports": {
|
||||
".": {
|
||||
"require": "./index.cjs",
|
||||
@@ -57,9 +57,9 @@
|
||||
"dependencies": {
|
||||
"@11ty/eleventy": "^0.11.1",
|
||||
"@11ty/eleventy-img": "^0.7.4",
|
||||
"@rocket/building-rollup": "^0.1.3",
|
||||
"@rocket/building-rollup": "^0.2.0",
|
||||
"@rocket/core": "^0.1.2",
|
||||
"@rocket/eleventy-plugin-mdjs-unified": "^0.3.1",
|
||||
"@rocket/eleventy-plugin-mdjs-unified": "^0.4.0",
|
||||
"@rocket/eleventy-rocket-nav": "^0.3.0",
|
||||
"@rollup/plugin-babel": "^5.2.2",
|
||||
"@rollup/plugin-node-resolve": "^11.0.1",
|
||||
|
||||
70
packages/cli/preset/_includes/layout-simulator.njk
Normal file
70
packages/cli/preset/_includes/layout-simulator.njk
Normal file
@@ -0,0 +1,70 @@
|
||||
<html theme="light" platform="web" lang="en">
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<style type="text/css">
|
||||
body {
|
||||
margin: 0;
|
||||
height: fit-content;
|
||||
}
|
||||
html[edge-distance] body {
|
||||
padding: 8px;
|
||||
}
|
||||
</style>
|
||||
<script type="module">
|
||||
import { render } from 'lit-html';
|
||||
|
||||
async function onHashChange() {
|
||||
const urlParts = new URLSearchParams(document.location.hash.substr(1));
|
||||
|
||||
if (urlParts.get('stylesheets')) {
|
||||
for (const stylesheet of urlParts.getAll('stylesheets')) {
|
||||
if (!document.querySelector(`link[rel="stylesheet"][href="${stylesheet}"]`)) {
|
||||
const link = document.createElement('link');
|
||||
link.rel = 'stylesheet';
|
||||
link.href = stylesheet;
|
||||
document.head.appendChild(link);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (urlParts.get('theme')) {
|
||||
document.documentElement.setAttribute('theme', urlParts.get('theme'));
|
||||
}
|
||||
if (urlParts.get('platform')) {
|
||||
document.documentElement.setAttribute('platform', urlParts.get('platform'));
|
||||
}
|
||||
if (urlParts.get('language')) {
|
||||
document.documentElement.setAttribute('lang', urlParts.get('language'));
|
||||
document.documentElement.setAttribute('data-lang', urlParts.get('language'));
|
||||
document.documentElement.setAttribute('data-localize-lang', urlParts.get('language'));
|
||||
}
|
||||
if (urlParts.get('story-key')) {
|
||||
document.documentElement.setAttribute('story-key', urlParts.get('story-key'));
|
||||
}
|
||||
if (urlParts.get('edge-distance') === 'true') {
|
||||
document.documentElement.setAttribute('edge-distance', '');
|
||||
} else {
|
||||
document.documentElement.removeAttribute('edge-distance');
|
||||
}
|
||||
|
||||
const mod = await import(urlParts.get('story-file'));
|
||||
render(mod[urlParts.get('story-key')](), document.body);
|
||||
}
|
||||
|
||||
window.addEventListener('hashchange', onHashChange, false);
|
||||
onHashChange();
|
||||
|
||||
const observer = new ResizeObserver(() => {
|
||||
const dimensions = document.body.getBoundingClientRect();
|
||||
const data = {
|
||||
action: 'mdjs-viewer-resize',
|
||||
storyKey: document.documentElement.getAttribute('story-key'),
|
||||
width: dimensions.width,
|
||||
height: dimensions.height,
|
||||
};
|
||||
parent.postMessage(JSON.stringify(data), '*');
|
||||
});
|
||||
observer.observe(document.body);
|
||||
</script>
|
||||
</head>
|
||||
<body></body>
|
||||
</html>
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
import { rollup } from 'rollup';
|
||||
import fs from 'fs-extra';
|
||||
import path from 'path';
|
||||
import { copy } from '@web/rollup-plugin-copy';
|
||||
|
||||
import { createMpaConfig } from '@rocket/building-rollup';
|
||||
@@ -45,7 +46,7 @@ async function productionBuild(config) {
|
||||
dir: config.outputDir,
|
||||
},
|
||||
// custom
|
||||
rootDir: config.outputDevDir,
|
||||
rootDir: path.resolve(config.outputDevDir),
|
||||
absoluteBaseUrl: config.absoluteBaseUrl,
|
||||
setupPlugins: [
|
||||
...defaultSetupPlugins,
|
||||
|
||||
@@ -34,12 +34,7 @@ describe('RocketCli use cases', () => {
|
||||
expect(aboutHtml).to.equal(
|
||||
[
|
||||
'<p><code>about.md</code></p>',
|
||||
'<script type="module">',
|
||||
' import { myData } from "../sub/assets/myData.js";',
|
||||
' import("../sub/assets/myData.js");',
|
||||
' const name = "myData";',
|
||||
' import(`../sub/assets/${name}.js`);',
|
||||
'</script>',
|
||||
'<script type="module" src="/about/__mdjs-stories.js" mdjs-setup></script>',
|
||||
].join('\n'),
|
||||
);
|
||||
|
||||
@@ -47,12 +42,7 @@ describe('RocketCli use cases', () => {
|
||||
expect(subHtml).to.equal(
|
||||
[
|
||||
'<p><code>sub/index.md</code></p>',
|
||||
'<script type="module">',
|
||||
' import { myData } from "./assets/myData.js";',
|
||||
' import("./assets/myData.js");',
|
||||
' const name = "myData";',
|
||||
' import(`./assets/${name}.js`);',
|
||||
'</script>',
|
||||
'<script type="module" src="/sub/__mdjs-stories.js" mdjs-setup></script>',
|
||||
].join('\n'),
|
||||
);
|
||||
|
||||
@@ -62,12 +52,7 @@ describe('RocketCli use cases', () => {
|
||||
expect(subDetailsHtml).to.equal(
|
||||
[
|
||||
'<p><code>sub/details.md</code></p>',
|
||||
'<script type="module">',
|
||||
' import { myData } from "../assets/myData.js";',
|
||||
' import("../assets/myData.js");',
|
||||
' const name = "myData";',
|
||||
' import(`../assets/${name}.js`);',
|
||||
'</script>',
|
||||
'<script type="module" src="/sub/details/__mdjs-stories.js" mdjs-setup></script>',
|
||||
].join('\n'),
|
||||
);
|
||||
|
||||
@@ -75,12 +60,7 @@ describe('RocketCli use cases', () => {
|
||||
expect(indexHtml).to.equal(
|
||||
[
|
||||
'<p><code>index.md</code></p>',
|
||||
'<script type="module">',
|
||||
' import { myData } from "./sub/assets/myData.js";',
|
||||
' import("./sub/assets/myData.js");',
|
||||
' const name = "myData";',
|
||||
' import(`./sub/assets/${name}.js`);',
|
||||
'</script>',
|
||||
'<script type="module" src="/__mdjs-stories.js" mdjs-setup></script>',
|
||||
].join('\n'),
|
||||
);
|
||||
});
|
||||
|
||||
@@ -13,8 +13,8 @@
|
||||
},
|
||||
"author": "Modern Web <hello@modern-web.dev> (https://modern-web.dev/)",
|
||||
"homepage": "https://rocket.modern-web.dev/",
|
||||
"type": "module",
|
||||
"main": "./dist/title.cjs",
|
||||
"type": "module",
|
||||
"exports": {
|
||||
"./title": {
|
||||
"require": "./dist/title.cjs",
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# @rocket/drawer
|
||||
|
||||
## 0.1.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 0b64116: Update @lion dependencies
|
||||
|
||||
## 0.1.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@rocket/drawer",
|
||||
"version": "0.1.2",
|
||||
"version": "0.1.3",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
@@ -33,7 +33,7 @@
|
||||
"testing"
|
||||
],
|
||||
"dependencies": {
|
||||
"@lion/overlays": "^0.23.2",
|
||||
"@lion/overlays": "^0.26.1",
|
||||
"lit-element": "^2.4.0"
|
||||
},
|
||||
"types": "dist-types/index.d.ts"
|
||||
|
||||
@@ -1,5 +1,18 @@
|
||||
# @rocket/eleventy-plugin-mdjs-unified
|
||||
|
||||
## 0.4.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 2267e72: Write the mdjs JavaScript code to a file and load it from there instead of an inline script
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [a8e66d8]
|
||||
- Updated dependencies [fe6a929]
|
||||
- Updated dependencies [a8e66d8]
|
||||
- @mdjs/core@0.7.0
|
||||
|
||||
## 0.3.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@rocket/eleventy-plugin-mdjs-unified",
|
||||
"version": "0.3.1",
|
||||
"version": "0.4.0",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
@@ -31,7 +31,7 @@
|
||||
"mdjs"
|
||||
],
|
||||
"dependencies": {
|
||||
"@mdjs/core": "^0.6.2",
|
||||
"@mdjs/core": "^0.7.0",
|
||||
"es-module-lexer": "^0.3.26",
|
||||
"unist-util-visit": "^2.0.3"
|
||||
},
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
const { mdjsProcess } = require('@mdjs/core');
|
||||
const visit = require('unist-util-visit');
|
||||
const { init, parse } = require('es-module-lexer');
|
||||
@@ -7,7 +9,7 @@ const { init, parse } = require('es-module-lexer');
|
||||
const { parseTitle } = require('@rocket/core/title');
|
||||
|
||||
/** @typedef {import('@mdjs/core').MdjsProcessPlugin} MdjsProcessPlugin */
|
||||
/** @typedef {import('../types/code').EleventPluginMdjsUnified} EleventPluginMdjsUnified */
|
||||
/** @typedef {import('../types/code').EleventyPluginMdjsUnified} EleventyPluginMdjsUnified */
|
||||
/** @typedef {import('../types/code').NodeChildren} NodeChildren */
|
||||
/** @typedef {import('../types/code').NodeElement} NodeElement */
|
||||
/** @typedef {import('unist').Node} Node */
|
||||
@@ -93,7 +95,7 @@ async function processImports(source, inputPath) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {EleventPluginMdjsUnified} pluginOptions
|
||||
* @param {EleventyPluginMdjsUnified} pluginOptions
|
||||
*/
|
||||
function eleventyUnified(pluginOptions) {
|
||||
/**
|
||||
@@ -139,10 +141,12 @@ function eleventyUnified(pluginOptions) {
|
||||
|
||||
let code = result.html;
|
||||
if (result.jsCode) {
|
||||
const newFolder = path.dirname(eleventySettings.page.outputPath);
|
||||
const newName = path.join(newFolder, '__mdjs-stories.js');
|
||||
await fs.promises.mkdir(newFolder, { recursive: true });
|
||||
await fs.promises.writeFile(newName, result.jsCode, 'utf8');
|
||||
code += `
|
||||
<script type="module">
|
||||
${result.jsCode}
|
||||
</script>
|
||||
<script type="module" src="${eleventySettings.page.url}__mdjs-stories.js" mdjs-setup></script>
|
||||
`;
|
||||
}
|
||||
return code;
|
||||
@@ -157,15 +161,15 @@ function eleventyUnified(pluginOptions) {
|
||||
|
||||
/**
|
||||
* @param {*} eleventyConfig
|
||||
* @param {EleventPluginMdjsUnified} [pluginOptions]
|
||||
* @param {EleventyPluginMdjsUnified} [pluginOptions]
|
||||
*/
|
||||
function configFunction(eleventyConfig, pluginOptions = {}) {
|
||||
eleventyConfig.setLibrary('md', eleventyUnified(pluginOptions));
|
||||
}
|
||||
|
||||
const eleventPluginMdjsUnified = {
|
||||
const EleventyPluginMdjsUnified = {
|
||||
initArguments: {},
|
||||
configFunction,
|
||||
};
|
||||
|
||||
module.exports = eleventPluginMdjsUnified;
|
||||
module.exports = EleventyPluginMdjsUnified;
|
||||
|
||||
@@ -53,13 +53,12 @@ describe('eleventy-plugin-mdjs-unified', () => {
|
||||
|
||||
it('renders markdown with javascript', async () => {
|
||||
const files = await renderEleventy('./test-node/fixtures/mdjs');
|
||||
expect(files).to.deep.equal([
|
||||
{
|
||||
html:
|
||||
'<h1 id="first"><a aria-hidden="true" tabindex="-1" href="#first"><span class="icon icon-link"></span></a>First</h1>\n<pre class="language-js"><code class="language-js"><span class="token keyword">const</span> foo <span class="token operator">=</span> <span class="token string">\'bar\'</span><span class="token punctuation">;</span>\n<span class="token keyword module">import</span> <span class="token punctuation">{</span> html <span class="token punctuation">}</span> <span class="token keyword module">from</span> <span class="token string">\'lit-html\'</span><span class="token punctuation">;</span>\n</code></pre>\n<mdjs-story mdjs-story-name="inline"></mdjs-story>\n<mdjs-preview mdjs-story-name="withBorder"></mdjs-preview>\n <script type="module">\n \nexport const inline = () => html` <p>main</p> `;\nexport const withBorder = () => html` <p>main</p> `;\nconst rootNode = document;\nconst stories = [{ key: \'inline\', story: inline, code: `<pre class="language-js"><code class="language-js"><span class="token keyword module">export</span> <span class="token keyword">const</span> <span class="token function-variable function">inline</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token arrow operator">=></span> html<span class="token template-string"><span class="token template-punctuation string">\\`</span><span class="token html language-html"> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>p</span><span class="token punctuation">></span></span>main<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>p</span><span class="token punctuation">></span></span> </span><span class="token template-punctuation string">\\`</span></span><span class="token punctuation">;</span>\n</code></pre>` }, { key: \'withBorder\', story: withBorder, code: `<pre class="language-js"><code class="language-js"><span class="token keyword module">export</span> <span class="token keyword">const</span> <span class="token function-variable function">withBorder</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token arrow operator">=></span> html<span class="token template-string"><span class="token template-punctuation string">\\`</span><span class="token html language-html"> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>p</span><span class="token punctuation">></span></span>main<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>p</span><span class="token punctuation">></span></span> </span><span class="token template-punctuation string">\\`</span></span><span class="token punctuation">;</span>\n</code></pre>` }];\nfor (const story of stories) {\n const storyEl = rootNode.querySelector(`[mdjs-story-name="${story.key}"]`);\n storyEl.codeHasHtml = true;\n storyEl.story = story.story;\n storyEl.code = story.code;\n};\nif (!customElements.get(\'mdjs-preview\')) { import(\'@mdjs/mdjs-preview/mdjs-preview.js\'); }\nif (!customElements.get(\'mdjs-story\')) { import(\'@mdjs/mdjs-story/mdjs-story.js\'); }\n </script>\n ',
|
||||
name: 'first/index.html',
|
||||
},
|
||||
]);
|
||||
|
||||
expect(files.length).to.equal(1);
|
||||
expect(files[0].name).to.equal('first/index.html');
|
||||
|
||||
expect(files[0].html).to.include('<script type="module"');
|
||||
expect(files[0].html).to.include('mdjs-setup>');
|
||||
});
|
||||
|
||||
it('rewrites relative import pathes', async () => {
|
||||
@@ -67,7 +66,7 @@ describe('eleventy-plugin-mdjs-unified', () => {
|
||||
expect(files).to.deep.equal([
|
||||
{
|
||||
html:
|
||||
"<p>first</p>\n <script type=\"module\">\n import '../import-me.js';\nimport('../import-me-too.js');\n </script>\n ",
|
||||
'<p>first</p>\n <script type="module" src="/first/__mdjs-stories.js" mdjs-setup></script>\n ',
|
||||
name: 'first/index.html',
|
||||
},
|
||||
]);
|
||||
@@ -78,7 +77,7 @@ describe('eleventy-plugin-mdjs-unified', () => {
|
||||
expect(files).to.deep.equal([
|
||||
{
|
||||
html:
|
||||
"<p>first</p>\n <script type=\"module\">\n import '../../import-me.js';\nimport('../../import-me-too.js');\n </script>\n ",
|
||||
'<p>first</p>\n <script type="module" src="/subpage/first/__mdjs-stories.js" mdjs-setup></script>\n ',
|
||||
name: 'subpage/first/index.html',
|
||||
},
|
||||
]);
|
||||
@@ -89,7 +88,7 @@ describe('eleventy-plugin-mdjs-unified', () => {
|
||||
expect(files).to.deep.equal([
|
||||
{
|
||||
html:
|
||||
"<p>index</p>\n <script type=\"module\">\n import './import-me.js';\nimport('./import-me-too.js');\n </script>\n ",
|
||||
'<p>index</p>\n <script type="module" src="/__mdjs-stories.js" mdjs-setup></script>\n ',
|
||||
name: 'index.html',
|
||||
},
|
||||
]);
|
||||
|
||||
@@ -3,7 +3,7 @@ import { Node } from 'unist';
|
||||
|
||||
export const setupUnifiedPluginsFn: (plugins: MdjsProcessPlugin[]) => MdjsProcessPlugin[];
|
||||
|
||||
export interface EleventPluginMdjsUnified {
|
||||
export interface EleventyPluginMdjsUnified {
|
||||
setupUnifiedPlugins?: setupUnifiedPluginsFn[];
|
||||
}
|
||||
|
||||
|
||||
@@ -36,6 +36,6 @@
|
||||
],
|
||||
"dependencies": {
|
||||
"@rocket/drawer": "^0.1.2",
|
||||
"@rocket/navigation": "^0.2.0"
|
||||
"@rocket/navigation": "^0.2.1"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,20 @@
|
||||
# Change Log
|
||||
|
||||
## 0.7.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- a8e66d8: Extract building of the JavaScript setup code into a unified plugin called mdjsSetupCode
|
||||
- fe6a929: For the story preview keep the original code block around to get code highlighting from the main document. This enables styling and reduces the code complexity.
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- a8e66d8: You can provide a highlightCode function to the mdjsSetupCode unified plugin
|
||||
- Updated dependencies [edb1abf]
|
||||
- Updated dependencies [604a80e]
|
||||
- @mdjs/mdjs-preview@0.4.0
|
||||
- @mdjs/mdjs-story@0.2.0
|
||||
|
||||
## 0.6.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@mdjs/core",
|
||||
"version": "0.6.2",
|
||||
"version": "0.7.0",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
@@ -43,12 +43,12 @@
|
||||
"remark"
|
||||
],
|
||||
"dependencies": {
|
||||
"@mdjs/mdjs-preview": "^0.3.1",
|
||||
"@mdjs/mdjs-story": "^0.1.1",
|
||||
"@mdjs/mdjs-preview": "^0.4.0",
|
||||
"@mdjs/mdjs-story": "^0.2.0",
|
||||
"@types/unist": "^2.0.3",
|
||||
"es-module-lexer": "^0.3.26",
|
||||
"github-markdown-css": "^4.0.0",
|
||||
"plugins-manager": "^0.2.0",
|
||||
"plugins-manager": "^0.2.1",
|
||||
"rehype-autolink-headings": "^5.0.1",
|
||||
"rehype-prism-template": "^0.4.1",
|
||||
"rehype-raw": "^5.0.0",
|
||||
|
||||
@@ -18,6 +18,7 @@ const { executeSetupFunctions } = require('plugins-manager');
|
||||
|
||||
const { mdjsParse } = require('./mdjsParse.js');
|
||||
const { mdjsStoryParse } = require('./mdjsStoryParse.js');
|
||||
const { mdjsSetupCode } = require('./mdjsSetupCode.js');
|
||||
|
||||
/** @type {MdjsProcessPlugin[]} */
|
||||
const defaultMetaPlugins = [
|
||||
@@ -25,6 +26,7 @@ const defaultMetaPlugins = [
|
||||
{ name: 'gfm', plugin: gfm },
|
||||
{ name: 'mdjsParse', plugin: mdjsParse },
|
||||
{ name: 'mdjsStoryParse', plugin: mdjsStoryParse },
|
||||
{ name: 'mdjsSetupCode', plugin: mdjsSetupCode },
|
||||
// @ts-ignore
|
||||
{ name: 'remark2rehype', plugin: remark2rehype, options: { allowDangerousHtml: true } },
|
||||
// @ts-ignore
|
||||
@@ -50,29 +52,15 @@ const defaultMetaPlugins = [
|
||||
* @param {function[]} [options.setupUnifiedPlugins]
|
||||
* @param {MdjsProcessPlugin[]} [options.plugins] deprecated option use setupUnifiedPlugins instead
|
||||
*/
|
||||
async function mdjsProcess(
|
||||
mdjs,
|
||||
{ rootNodeQueryCode = 'document', setupUnifiedPlugins = [] } = {},
|
||||
) {
|
||||
async function mdjsProcess(mdjs, { setupUnifiedPlugins = [] } = {}) {
|
||||
const parser = unified();
|
||||
|
||||
const metaPlugins = executeSetupFunctions(setupUnifiedPlugins, defaultMetaPlugins);
|
||||
|
||||
// @ts-ignore
|
||||
for (const pluginObj of metaPlugins) {
|
||||
parser.use(pluginObj.plugin, pluginObj.options);
|
||||
}
|
||||
|
||||
/** @type {unknown} */
|
||||
const parseResult = await parser.process(mdjs);
|
||||
const result = /** @type {ParseResult} */ (parseResult);
|
||||
|
||||
const { stories, jsCode } = result.data;
|
||||
let fullJsCode = jsCode;
|
||||
|
||||
if (stories && stories.length > 0) {
|
||||
const storiesCode = stories.map(story => story.code).join('\n');
|
||||
|
||||
/**
|
||||
* @param {string} code
|
||||
*/
|
||||
async function highlightCode(code) {
|
||||
// @ts-ignore
|
||||
const codePlugins = metaPlugins.filter(pluginObj =>
|
||||
['markdown', 'remark2rehype', 'rehypePrism', 'htmlStringify'].includes(pluginObj.name),
|
||||
@@ -82,46 +70,30 @@ async function mdjsProcess(
|
||||
for (const pluginObj of codePlugins) {
|
||||
codeParser.use(pluginObj.plugin, pluginObj.options);
|
||||
}
|
||||
|
||||
const invokeStoriesCode = [];
|
||||
for (const story of stories) {
|
||||
let code = '';
|
||||
switch (story.type) {
|
||||
case 'html':
|
||||
code = `\`\`\`html\n${story.code.split('`')[1]}\n\`\`\``;
|
||||
break;
|
||||
case 'js':
|
||||
code = `\`\`\`js\n${story.code}\n\`\`\``;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
const codeResult = await codeParser.process(code);
|
||||
const highlightedCode = /** @type {string} */ (codeResult.contents)
|
||||
.replace(/`/g, '\\`')
|
||||
.replace(/\$/g, '\\$');
|
||||
invokeStoriesCode.push(
|
||||
`{ key: '${story.key}', story: ${story.key}, code: \`${highlightedCode}\` }`,
|
||||
);
|
||||
}
|
||||
|
||||
fullJsCode = [
|
||||
jsCode,
|
||||
storiesCode,
|
||||
`const rootNode = ${rootNodeQueryCode};`,
|
||||
`const stories = [${invokeStoriesCode.join(', ')}];`,
|
||||
`for (const story of stories) {`,
|
||||
// eslint-disable-next-line no-template-curly-in-string
|
||||
' const storyEl = rootNode.querySelector(`[mdjs-story-name="${story.key}"]`);',
|
||||
` storyEl.codeHasHtml = true;`,
|
||||
` storyEl.story = story.story;`,
|
||||
` storyEl.code = story.code;`,
|
||||
`};`,
|
||||
`if (!customElements.get('mdjs-preview')) { import('@mdjs/mdjs-preview/mdjs-preview.js'); }`,
|
||||
`if (!customElements.get('mdjs-story')) { import('@mdjs/mdjs-story/mdjs-story.js'); }`,
|
||||
].join('\n');
|
||||
const codeResult = await codeParser.process(code);
|
||||
return codeResult.contents;
|
||||
}
|
||||
return { stories, jsCode: fullJsCode, html: result.contents };
|
||||
|
||||
// @ts-ignore
|
||||
for (const pluginObj of metaPlugins) {
|
||||
if (pluginObj.name === 'mdjsSetupCode') {
|
||||
if (pluginObj.options && !pluginObj.options.highlightCode) {
|
||||
pluginObj.options.highlightCode = highlightCode;
|
||||
}
|
||||
if (!pluginObj.options) {
|
||||
pluginObj.options = { highlightCode };
|
||||
}
|
||||
}
|
||||
parser.use(pluginObj.plugin, pluginObj.options);
|
||||
}
|
||||
|
||||
/** @type {unknown} */
|
||||
const parseResult = await parser.process(mdjs);
|
||||
const result = /** @type {ParseResult} */ (parseResult);
|
||||
|
||||
const { stories, setupJsCode } = result.data;
|
||||
|
||||
return { stories, jsCode: setupJsCode, html: result.contents };
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
|
||||
57
packages/mdjs-core/src/mdjsSetupCode.js
Normal file
57
packages/mdjs-core/src/mdjsSetupCode.js
Normal file
@@ -0,0 +1,57 @@
|
||||
/** @typedef {import('vfile').VFileOptions} VFileOptions */
|
||||
/** @typedef {import('unist').Node} Node */
|
||||
/** @typedef {import('@mdjs/core/types/code').Story} Story */
|
||||
|
||||
function mdjsSetupCode({ rootNodeQueryCode = 'document', simulationSettings = {} } = {}) {
|
||||
/**
|
||||
* @param {Node} tree
|
||||
* @param {VFileOptions} file
|
||||
*/
|
||||
async function transformer(tree, file) {
|
||||
const { stories, jsCode } = file.data;
|
||||
|
||||
file.data.setupJsCode = jsCode;
|
||||
|
||||
if (stories && stories.length > 0) {
|
||||
const storiesCode = stories.map(/** @param {Story} story */ story => story.code).join('\n');
|
||||
|
||||
const invokeStoriesCode = [];
|
||||
for (const story of stories) {
|
||||
invokeStoriesCode.push(`{ key: '${story.key}', story: ${story.key} }`);
|
||||
}
|
||||
|
||||
file.data.setupJsCode = [
|
||||
'/** script code **/',
|
||||
jsCode,
|
||||
'/** stories code **/',
|
||||
storiesCode,
|
||||
'/** stories setup code **/',
|
||||
`const rootNode = ${rootNodeQueryCode};`,
|
||||
`const stories = [${invokeStoriesCode.join(', ')}];`,
|
||||
'let needsMdjsElements = false;',
|
||||
`for (const story of stories) {`,
|
||||
// eslint-disable-next-line no-template-curly-in-string
|
||||
' const storyEl = rootNode.querySelector(`[mdjs-story-name="${story.key}"]`);',
|
||||
' if (storyEl) {',
|
||||
` storyEl.story = story.story;`,
|
||||
` storyEl.key = story.key;`,
|
||||
` needsMdjsElements = true;`,
|
||||
` Object.assign(storyEl, ${JSON.stringify(simulationSettings)});`,
|
||||
' }',
|
||||
`};`,
|
||||
'if (needsMdjsElements) {',
|
||||
` if (!customElements.get('mdjs-preview')) { import('@mdjs/mdjs-preview/define'); }`,
|
||||
` if (!customElements.get('mdjs-story')) { import('@mdjs/mdjs-story/define'); }`,
|
||||
'}',
|
||||
].join('\n');
|
||||
}
|
||||
|
||||
return tree;
|
||||
}
|
||||
|
||||
return transformer;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
mdjsSetupCode,
|
||||
};
|
||||
@@ -3,6 +3,7 @@
|
||||
/** @typedef {import('@mdjs/core/types/code').StoryTypes} StoryTypes */
|
||||
/** @typedef {(name: string) => string} TagFunction */
|
||||
/** @typedef {import('unist').Node} UnistNode */
|
||||
/** @typedef {import('unist').Parent} UnistParent */
|
||||
/** @typedef {import('vfile').VFileOptions} VFileOptions */
|
||||
|
||||
const visit = require('unist-util-visit');
|
||||
@@ -40,7 +41,7 @@ function defaultStoryTag(name) {
|
||||
* @param {string} name
|
||||
*/
|
||||
function defaultPreviewStoryTag(name) {
|
||||
return `<mdjs-preview mdjs-story-name="${name}"></mdjs-preview>`;
|
||||
return `<mdjs-preview mdjs-story-name="${name}">[[CODE SLOT]]</mdjs-preview>`;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -55,14 +56,16 @@ function mdjsStoryParse({
|
||||
} = {}) {
|
||||
/** @type {Story[]} */
|
||||
const stories = [];
|
||||
let index = 0;
|
||||
let htmlIndex = 0;
|
||||
|
||||
/* eslint-disable no-param-reassign */
|
||||
|
||||
/**
|
||||
* @param {UnistNode} node
|
||||
* @param {number} index
|
||||
* @param {UnistParent} parent
|
||||
*/
|
||||
const nodeCodeVisitor = node => {
|
||||
const nodeCodeVisitor = (node, index, parent) => {
|
||||
if (node.lang === 'js' && node.meta === 'story' && typeof node.value === 'string') {
|
||||
const storyData = extractStoryData(node.value);
|
||||
node.type = 'html';
|
||||
@@ -71,30 +74,65 @@ function mdjsStoryParse({
|
||||
}
|
||||
if (node.lang === 'js' && node.meta === 'preview-story' && typeof node.value === 'string') {
|
||||
const storyData = extractStoryData(node.value);
|
||||
node.type = 'html';
|
||||
node.value = previewStoryTag(storyData.name);
|
||||
const newValue = previewStoryTag(storyData.name);
|
||||
if (newValue.includes('[[CODE SLOT]]')) {
|
||||
const tagParts = newValue.split('[[CODE SLOT]]');
|
||||
node = {
|
||||
type: 'root',
|
||||
children: [
|
||||
{ type: 'html', value: tagParts[0] },
|
||||
{ type: 'text', value: '\n\n' },
|
||||
node,
|
||||
{ type: 'text', value: '\n\n' },
|
||||
{ type: 'html', value: tagParts[1] },
|
||||
],
|
||||
};
|
||||
parent.children.splice(index, 1, node);
|
||||
} else {
|
||||
node.type = 'html';
|
||||
node.value = previewStoryTag(storyData.name);
|
||||
}
|
||||
|
||||
stories.push(storyData);
|
||||
}
|
||||
|
||||
if (node.lang === 'html' && node.meta === 'story') {
|
||||
const storyData = extractStoryData(
|
||||
`export const HtmlStory${index} = () => html\`${node.value}\`;`,
|
||||
`export const HtmlStory${htmlIndex} = () => html\`${node.value}\`;`,
|
||||
{ type: 'html' },
|
||||
);
|
||||
node.type = 'html';
|
||||
node.value = storyTag(storyData.name);
|
||||
stories.push(storyData);
|
||||
index += 1;
|
||||
htmlIndex += 1;
|
||||
}
|
||||
if (node.lang === 'html' && node.meta === 'preview-story') {
|
||||
const storyData = extractStoryData(
|
||||
`export const HtmlStory${index} = () => html\`${node.value}\`;`,
|
||||
`export const HtmlStory${htmlIndex} = () => html\`${node.value}\`;`,
|
||||
{ type: 'html' },
|
||||
);
|
||||
node.type = 'html';
|
||||
node.value = previewStoryTag(storyData.name);
|
||||
|
||||
const newValue = previewStoryTag(storyData.name);
|
||||
if (newValue.includes('[[CODE SLOT]]')) {
|
||||
const tagParts = newValue.split('[[CODE SLOT]]');
|
||||
node = {
|
||||
type: 'root',
|
||||
children: [
|
||||
{ type: 'html', value: tagParts[0] },
|
||||
{ type: 'text', value: '\n\n' },
|
||||
node,
|
||||
{ type: 'text', value: '\n\n' },
|
||||
{ type: 'html', value: tagParts[1] },
|
||||
],
|
||||
};
|
||||
parent.children.splice(index, 1, node);
|
||||
} else {
|
||||
node.type = 'html';
|
||||
node.value = previewStoryTag(storyData.name);
|
||||
}
|
||||
|
||||
stories.push(storyData);
|
||||
index += 1;
|
||||
htmlIndex += 1;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -45,7 +45,16 @@ describe('Integration', () => {
|
||||
'<pre><code class="language-js">const foo = 1;',
|
||||
'</code></pre>',
|
||||
'<mdjs-story mdjs-story-name="fooStory"></mdjs-story>',
|
||||
'<mdjs-preview mdjs-story-name="fooPreviewStory"></mdjs-preview>',
|
||||
'<mdjs-preview mdjs-story-name="fooPreviewStory">',
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
'<pre><code class="language-js">export const fooPreviewStory = () => {}',
|
||||
'</code></pre>',
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
'</mdjs-preview>',
|
||||
];
|
||||
|
||||
const parser = unified()
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/* eslint-disable no-template-curly-in-string */
|
||||
|
||||
const chai = require('chai');
|
||||
const { adjustPluginOptions } = require('plugins-manager');
|
||||
const { mdjsProcess } = require('../src/mdjsProcess.js');
|
||||
|
||||
const { expect } = chai;
|
||||
@@ -28,27 +29,44 @@ describe('mdjsProcess', () => {
|
||||
'<pre class="language-js"><code class="language-js"><span class="token keyword">const</span> foo <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span>',
|
||||
'</code></pre>',
|
||||
'<mdjs-story mdjs-story-name="fooStory"></mdjs-story>',
|
||||
'<mdjs-preview mdjs-story-name="fooPreviewStory"></mdjs-preview>',
|
||||
'<mdjs-preview mdjs-story-name="fooPreviewStory">',
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
'<pre class="language-js"><code class="language-js"><span class="token keyword module">export</span> <span class="token keyword">const</span> <span class="token function-variable function">fooPreviewStory</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token arrow operator">=></span> <span class="token punctuation">{</span><span class="token punctuation">}</span>',
|
||||
'</code></pre>',
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
'</mdjs-preview>',
|
||||
].join('\n');
|
||||
const expectedJsCode = [
|
||||
'/** script code **/',
|
||||
'const bar = 2;',
|
||||
'/** stories code **/',
|
||||
'export const fooStory = () => {}',
|
||||
'export const fooPreviewStory = () => {}',
|
||||
'/** stories setup code **/',
|
||||
'const rootNode = document;',
|
||||
`const stories = [{ key: 'fooStory', story: fooStory, code: \`<pre class="language-js"><code class="language-js"><span class="token keyword module">export</span> <span class="token keyword">const</span> <span class="token function-variable function">fooStory</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token arrow operator">=></span> <span class="token punctuation">{</span><span class="token punctuation">}</span>`,
|
||||
`</code></pre>\` }, { key: 'fooPreviewStory', story: fooPreviewStory, code: \`<pre class="language-js"><code class="language-js"><span class="token keyword module">export</span> <span class="token keyword">const</span> <span class="token function-variable function">fooPreviewStory</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token arrow operator">=></span> <span class="token punctuation">{</span><span class="token punctuation">}</span>`,
|
||||
`</code></pre>\` }];`,
|
||||
`const stories = [{ key: 'fooStory', story: fooStory }, { key: 'fooPreviewStory', story: fooPreviewStory }];`,
|
||||
'let needsMdjsElements = false;',
|
||||
'for (const story of stories) {',
|
||||
' const storyEl = rootNode.querySelector(`[mdjs-story-name="${story.key}"]`);',
|
||||
' storyEl.codeHasHtml = true;',
|
||||
' storyEl.story = story.story;',
|
||||
' storyEl.code = story.code;',
|
||||
' if (storyEl) {',
|
||||
' storyEl.story = story.story;',
|
||||
' storyEl.key = story.key;',
|
||||
' needsMdjsElements = true;',
|
||||
' Object.assign(storyEl, {});',
|
||||
' }',
|
||||
'};',
|
||||
`if (!customElements.get('mdjs-preview')) { import('@mdjs/mdjs-preview/mdjs-preview.js'); }`,
|
||||
`if (!customElements.get('mdjs-story')) { import('@mdjs/mdjs-story/mdjs-story.js'); }`,
|
||||
'if (needsMdjsElements) {',
|
||||
` if (!customElements.get('mdjs-preview')) { import('@mdjs/mdjs-preview/define'); }`,
|
||||
` if (!customElements.get('mdjs-story')) { import('@mdjs/mdjs-story/define'); }`,
|
||||
'}',
|
||||
].join('\n');
|
||||
|
||||
const result = await mdjsProcess(input);
|
||||
|
||||
expect(result.html).to.equal(expected);
|
||||
expect(result.jsCode).to.equal(expectedJsCode);
|
||||
});
|
||||
@@ -150,4 +168,45 @@ describe('mdjsProcess', () => {
|
||||
const result = await mdjsProcess(input);
|
||||
expect(result.html.trim()).to.equal(expected);
|
||||
});
|
||||
|
||||
it('can adjust languages for story preview', async () => {
|
||||
const input = [
|
||||
'Intro',
|
||||
'```js preview-story',
|
||||
'export const fooPreviewStory = () => {}',
|
||||
'```',
|
||||
].join('\n');
|
||||
|
||||
const expected = [
|
||||
`/** script code **/`,
|
||||
``,
|
||||
`/** stories code **/`,
|
||||
`export const fooPreviewStory = () => {}`,
|
||||
`/** stories setup code **/`,
|
||||
`const rootNode = document;`,
|
||||
`const stories = [{ key: 'fooPreviewStory', story: fooPreviewStory }];`,
|
||||
`let needsMdjsElements = false;`,
|
||||
`for (const story of stories) {`,
|
||||
' const storyEl = rootNode.querySelector(`[mdjs-story-name="${story.key}"]`);',
|
||||
` if (storyEl) {`,
|
||||
` storyEl.story = story.story;`,
|
||||
` storyEl.key = story.key;`,
|
||||
` needsMdjsElements = true;`,
|
||||
' Object.assign(storyEl, {"languages":[{"key":"en","name":"English"}]});',
|
||||
` }`,
|
||||
`};`,
|
||||
`if (needsMdjsElements) {`,
|
||||
` if (!customElements.get('mdjs-preview')) { import('@mdjs/mdjs-preview/define'); }`,
|
||||
` if (!customElements.get('mdjs-story')) { import('@mdjs/mdjs-story/define'); }`,
|
||||
`}`,
|
||||
].join('\n');
|
||||
const result = await mdjsProcess(input, {
|
||||
setupUnifiedPlugins: [
|
||||
adjustPluginOptions('mdjsSetupCode', {
|
||||
simulationSettings: { languages: [{ key: 'en', name: 'English' }] },
|
||||
}),
|
||||
],
|
||||
});
|
||||
expect(result.jsCode.trim()).to.equal(expected);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -28,7 +28,7 @@ describe('mdjsParse', () => {
|
||||
expect(/** @type {MDJSVFileData} */ (result.data).jsCode).to.equal('const bar = 22;');
|
||||
});
|
||||
|
||||
// TODO: fix this bug
|
||||
// TODO: fix this bug - maybe something in unified itself 🤔
|
||||
it.skip('handling only "js script" code blocks', async () => {
|
||||
const input = [
|
||||
//
|
||||
|
||||
@@ -37,9 +37,27 @@ describe('mdjsStoryParse', () => {
|
||||
'<pre><code class="language-js">const foo = 1;',
|
||||
'</code></pre>',
|
||||
'<mdjs-story mdjs-story-name="fooStory"></mdjs-story>',
|
||||
'<mdjs-preview mdjs-story-name="fooPreviewStory"></mdjs-preview>',
|
||||
'<mdjs-preview mdjs-story-name="fooPreviewStory">',
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
'<pre><code class="language-js">export const fooPreviewStory = () => {}',
|
||||
'</code></pre>',
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
'</mdjs-preview>',
|
||||
'<mdjs-story mdjs-story-name="HtmlStory0"></mdjs-story>',
|
||||
'<mdjs-preview mdjs-story-name="HtmlStory1"></mdjs-preview>',
|
||||
'<mdjs-preview mdjs-story-name="HtmlStory1">',
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
'<pre><code class="language-html"><demo-el></demo-el>',
|
||||
'</code></pre>',
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
'</mdjs-preview>',
|
||||
'',
|
||||
].join('\n');
|
||||
|
||||
|
||||
1
packages/mdjs-core/types/code.d.ts
vendored
1
packages/mdjs-core/types/code.d.ts
vendored
@@ -25,6 +25,7 @@ export interface ParseResult {
|
||||
data: {
|
||||
stories: Story[];
|
||||
jsCode: string;
|
||||
setupJsCode: string;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,18 @@
|
||||
# @mdjs/mdjs-preview
|
||||
|
||||
## 0.4.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- edb1abf: Reworking completely by
|
||||
|
||||
- slotting in the highlighted code
|
||||
- open story in dedicated window
|
||||
- enabling an simulation mode that can render the story in an iframe
|
||||
- share settings between all simulators
|
||||
- option to remember simulator settings
|
||||
- force side effect import via `/define`
|
||||
|
||||
## 0.3.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@mdjs/mdjs-preview",
|
||||
"version": "0.3.2",
|
||||
"version": "0.4.0",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
@@ -17,7 +17,7 @@
|
||||
"type": "module",
|
||||
"exports": {
|
||||
".": "./index.js",
|
||||
"./mdjs-preview.js": "./mdjs-preview.js"
|
||||
"./define": "./src/define/define.js"
|
||||
},
|
||||
"scripts": {
|
||||
"debug": "cd ../../ && npm run debug -- --group mdjs-preview",
|
||||
@@ -32,8 +32,8 @@
|
||||
"src"
|
||||
],
|
||||
"dependencies": {
|
||||
"lit-element": "^2.4.0",
|
||||
"lit-html": "^1.3.0"
|
||||
"@lion/accordion": "^0.4.2",
|
||||
"lit-element": "^2.4.0"
|
||||
},
|
||||
"types": "dist-types/index.d.ts"
|
||||
}
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
import { LitElement, html, css } from 'lit-element';
|
||||
import { unsafeHTML } from 'lit-html/directives/unsafe-html.js';
|
||||
import '@lion/accordion/define';
|
||||
|
||||
import {
|
||||
subscribe,
|
||||
unSubscribe,
|
||||
saveToSharedStates,
|
||||
applySharedStates,
|
||||
} from './mdjsViewerSharedStates.js';
|
||||
import { addResizeHandler } from './resizeHandler.js';
|
||||
|
||||
/**
|
||||
* @typedef {object} StoryOptions
|
||||
@@ -20,160 +28,731 @@ export class MdJsPreview extends LitElement {
|
||||
story: {
|
||||
attribute: false,
|
||||
},
|
||||
code: {
|
||||
key: {
|
||||
type: String,
|
||||
},
|
||||
codeHasHtml: {
|
||||
deviceMode: {
|
||||
type: Boolean,
|
||||
},
|
||||
showCode: {
|
||||
type: Boolean,
|
||||
attribute: 'show-code',
|
||||
attribute: 'device-mode',
|
||||
reflect: true,
|
||||
},
|
||||
sameSettings: { type: Boolean },
|
||||
contentHeight: { type: Number },
|
||||
simulatorUrl: { type: String },
|
||||
// page settings
|
||||
platform: { type: String },
|
||||
platforms: { type: Array },
|
||||
size: { type: String },
|
||||
sizes: { type: Array },
|
||||
theme: { type: String, reflect: true },
|
||||
themes: { type: Array },
|
||||
language: { type: String },
|
||||
languages: { type: Array },
|
||||
edgeDistance: { type: Boolean },
|
||||
autoHeight: { type: Boolean },
|
||||
rememberSettings: { type: Boolean },
|
||||
};
|
||||
}
|
||||
|
||||
toggleShowCode() {
|
||||
this.showCode = !this.showCode;
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.code = '';
|
||||
/** @type {LitHtmlStoryFn} */
|
||||
this.story = () => html` <p>Loading...</p> `;
|
||||
this.codeHasHtml = false;
|
||||
this.key = '';
|
||||
this.contentHeight = 0;
|
||||
this.simulatorUrl = '';
|
||||
|
||||
this.theme = 'light';
|
||||
this.themes = [
|
||||
{ key: 'light', name: 'Light' },
|
||||
{ key: 'dark', name: 'Dark' },
|
||||
];
|
||||
|
||||
this.language = 'en-US';
|
||||
this.languages = [
|
||||
{ key: 'en', name: 'English' },
|
||||
{ key: 'en-US', name: 'English (United States)' },
|
||||
{ key: 'en-US', name: 'English (United Kingdom)' },
|
||||
{ key: 'de', name: 'German' },
|
||||
{ key: 'es', name: 'Spanish' },
|
||||
{ key: 'fi', name: 'Finnish' },
|
||||
{ key: 'fr', name: 'French' },
|
||||
{ key: 'it', name: 'Italian' },
|
||||
{ key: 'nl', name: 'Dutch' },
|
||||
{ key: 'pl', name: 'Polish' },
|
||||
{ key: 'pt', name: 'Portuguese' },
|
||||
{ key: 'ro', name: 'Romanian' },
|
||||
{ key: 'sv', name: 'Swedish' },
|
||||
{ key: 'sv', name: 'Swedish' },
|
||||
];
|
||||
|
||||
this.platform = 'web';
|
||||
this.platforms = [
|
||||
{ key: 'web', name: 'Web' },
|
||||
// { key: 'web-windows', name: 'Windows' },
|
||||
// { key: 'web-mac', name: 'Mac' },
|
||||
{ key: 'android', name: 'Android' },
|
||||
{ key: 'ios', name: 'iOS' },
|
||||
];
|
||||
|
||||
this.size = 'webSmall';
|
||||
this.sizes = [
|
||||
{
|
||||
key: 'webSmall',
|
||||
name: 'Small',
|
||||
platform: 'web',
|
||||
width: 360,
|
||||
height: 640,
|
||||
dpr: 1,
|
||||
},
|
||||
{
|
||||
key: 'webMedium',
|
||||
name: 'Medium',
|
||||
platform: 'web',
|
||||
width: 640,
|
||||
height: 640,
|
||||
dpr: 1,
|
||||
},
|
||||
{
|
||||
key: 'webLarge',
|
||||
name: 'Large',
|
||||
platform: 'web',
|
||||
width: 1024,
|
||||
height: 640,
|
||||
dpr: 1,
|
||||
},
|
||||
{
|
||||
key: 'pixel2',
|
||||
name: 'Pixel 2',
|
||||
platform: 'android',
|
||||
width: 411,
|
||||
height: 731,
|
||||
dpr: 2.6,
|
||||
},
|
||||
{
|
||||
key: 'galaxyS5',
|
||||
name: 'Galaxy S5',
|
||||
platform: 'android',
|
||||
width: 360,
|
||||
height: 640,
|
||||
dpr: 3,
|
||||
},
|
||||
{
|
||||
key: 'iphoneX',
|
||||
name: 'iPhone X',
|
||||
platform: 'ios',
|
||||
width: 375,
|
||||
height: 812,
|
||||
dpr: 3,
|
||||
},
|
||||
{
|
||||
key: 'iPad',
|
||||
name: 'iPad',
|
||||
platform: 'ios',
|
||||
width: 768,
|
||||
height: 1024,
|
||||
dpr: 2,
|
||||
},
|
||||
];
|
||||
|
||||
this.deviceMode = false;
|
||||
this.autoHeight = true;
|
||||
this.edgeDistance = true;
|
||||
this.sameSettings = true;
|
||||
this.rememberSettings = false;
|
||||
|
||||
this.__firstRun = true;
|
||||
this.__syncUp = false;
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
super.connectedCallback();
|
||||
if (this.sameSettings) {
|
||||
applySharedStates(this);
|
||||
}
|
||||
addResizeHandler();
|
||||
}
|
||||
|
||||
get baseUrl() {
|
||||
return document.location.origin;
|
||||
}
|
||||
|
||||
get deviceHeight() {
|
||||
if (this.autoHeight) {
|
||||
return this.contentHeight + 10;
|
||||
}
|
||||
return this.sizeData?.height || 50;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} platform
|
||||
*/
|
||||
getSizesFor(platform) {
|
||||
return this.sizes.filter(el => el.platform === platform);
|
||||
}
|
||||
|
||||
get sizeData() {
|
||||
return (
|
||||
this.sizes.find(el => el.key === this.size) || { width: 50, height: 50, name: 'default' }
|
||||
);
|
||||
}
|
||||
|
||||
onSubscribe = () => {
|
||||
this.__syncUp = false;
|
||||
applySharedStates(this);
|
||||
this.__syncUp = true;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {import('lit-element').PropertyValues} changeProps
|
||||
*/
|
||||
update(changeProps) {
|
||||
super.update(changeProps);
|
||||
if (this.sameSettings && this.__syncUp) {
|
||||
saveToSharedStates(this, this.onSubscribe);
|
||||
}
|
||||
|
||||
if (changeProps.has('sameSettings')) {
|
||||
if (this.sameSettings) {
|
||||
subscribe(this.onSubscribe);
|
||||
} else {
|
||||
unSubscribe(this.onSubscribe);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
disconnectedCallback() {
|
||||
super.disconnectedCallback();
|
||||
if (this.sameSettings) {
|
||||
unSubscribe(this.onSubscribe);
|
||||
}
|
||||
}
|
||||
|
||||
firstUpdated() {
|
||||
this.__syncUp = true;
|
||||
}
|
||||
|
||||
get iframeUrl() {
|
||||
const mdjsSetupScript = /** @type {HTMLScriptElement} */ (document.querySelector(
|
||||
'script[type=module][mdjs-setup]',
|
||||
));
|
||||
if (!mdjsSetupScript) {
|
||||
throw new Error('Could not find a <script type="module" src="..." mdjs-setup></script>');
|
||||
}
|
||||
|
||||
const params = new URLSearchParams();
|
||||
params.set('story-file', mdjsSetupScript.src);
|
||||
params.set('story-key', this.key);
|
||||
params.set('theme', this.theme);
|
||||
params.set('platform', this.platform);
|
||||
params.set('language', this.language);
|
||||
params.set('edge-distance', this.edgeDistance.toString());
|
||||
|
||||
const links = /** @type {HTMLLinkElement[]} */ ([
|
||||
...document.querySelectorAll('link[mdjs-use]'),
|
||||
]);
|
||||
for (const link of links) {
|
||||
if (link.href) {
|
||||
params.append('stylesheets', link.href);
|
||||
}
|
||||
}
|
||||
|
||||
return `${this.simulatorUrl}#?${params.toString()}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} platform
|
||||
*/
|
||||
changePlatform(platform) {
|
||||
this.platform = platform;
|
||||
const sizes = this.getSizesFor(this.platform);
|
||||
this.size = sizes[0].key;
|
||||
}
|
||||
|
||||
renderPlatforms() {
|
||||
return html`
|
||||
<div>
|
||||
<h3>Platform</h3>
|
||||
<h4>Platform</h4>
|
||||
<div
|
||||
class="segmented-control"
|
||||
@change=${
|
||||
/** @param {Event} ev */ ev => {
|
||||
if (ev.target) {
|
||||
this.changePlatform(/** @type {HTMLInputElement} */ (ev.target).value);
|
||||
}
|
||||
}
|
||||
}
|
||||
>
|
||||
${this.platforms.map(
|
||||
platform => html`
|
||||
<label class="${this.platform === platform.key ? 'selected' : ''}">
|
||||
<span>${platform.name}</span>
|
||||
<input
|
||||
type="radio"
|
||||
name="platform"
|
||||
value="${platform.key}"
|
||||
?checked=${this.platform === platform.key}
|
||||
/>
|
||||
</label>
|
||||
`,
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
renderSizes() {
|
||||
return html`
|
||||
<div>
|
||||
<h3>Viewport</h3>
|
||||
<h4>Size</h4>
|
||||
<div
|
||||
class="segmented-control"
|
||||
@change=${
|
||||
/** @param {Event} ev */ ev => {
|
||||
if (ev.target) {
|
||||
this.size = /** @type {HTMLInputElement} */ (ev.target).value;
|
||||
}
|
||||
}
|
||||
}
|
||||
>
|
||||
${this.getSizesFor(this.platform).map(
|
||||
size => html`
|
||||
<label class="${this.size === size.key ? 'selected' : ''}">
|
||||
<span>${size.name}</span>
|
||||
<input
|
||||
type="radio"
|
||||
name="size"
|
||||
value="${size.key}"
|
||||
.checked=${this.size === size.key}
|
||||
/>
|
||||
</label>
|
||||
`,
|
||||
)}
|
||||
</div>
|
||||
${this.renderAutoHeight()}
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
renderThemes() {
|
||||
return html`
|
||||
<div>
|
||||
<h3>Visual</h3>
|
||||
<h4>Theme</h4>
|
||||
<div
|
||||
class="segmented-control"
|
||||
@change=${
|
||||
/** @param {Event} ev */ ev => {
|
||||
if (ev.target) {
|
||||
this.theme = /** @type {HTMLInputElement} */ (ev.target).value;
|
||||
}
|
||||
}
|
||||
}
|
||||
>
|
||||
${this.themes.map(
|
||||
theme => html`
|
||||
<label class="${this.theme === theme.key ? 'selected' : ''}">
|
||||
<span>${theme.name}</span>
|
||||
<input
|
||||
type="radio"
|
||||
name="theme"
|
||||
value="${theme.key}"
|
||||
?checked=${this.theme === theme.key}
|
||||
/>
|
||||
</label>
|
||||
`,
|
||||
)}
|
||||
</div>
|
||||
${this.renderEdgeDistance()}
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
renderLanguages() {
|
||||
return html`
|
||||
<div>
|
||||
<h3>Localization</h3>
|
||||
<label>
|
||||
Language
|
||||
<select
|
||||
@change=${
|
||||
/** @param {Event} ev */ ev => {
|
||||
if (ev.target) {
|
||||
this.language = /** @type {HTMLInputElement} */ (ev.target).value;
|
||||
}
|
||||
}
|
||||
}
|
||||
>
|
||||
${this.languages.map(
|
||||
language => html`
|
||||
<option value="${language.key}" ?selected=${this.language === language.key}>
|
||||
${language.name}
|
||||
</option>
|
||||
`,
|
||||
)}
|
||||
</select>
|
||||
</label>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
renderEdgeDistance() {
|
||||
return html`
|
||||
<div>
|
||||
<label class="${this.edgeDistance ? 'switch selected' : 'switch'}">
|
||||
Apply distance to edge
|
||||
<span class="switch-button"></span>
|
||||
|
||||
<input
|
||||
type="checkbox"
|
||||
?checked=${this.edgeDistance}
|
||||
@change=${
|
||||
/** @param {Event} ev */ ev => {
|
||||
if (ev.target) {
|
||||
this.edgeDistance = /** @type {HTMLInputElement} */ (ev.target).checked;
|
||||
}
|
||||
}
|
||||
}
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
renderAutoHeight() {
|
||||
return html`
|
||||
<div>
|
||||
<label class="${this.autoHeight ? 'switch selected' : 'switch'}">
|
||||
Fit height to content
|
||||
<span class="switch-button"></span>
|
||||
<input
|
||||
type="checkbox"
|
||||
?checked=${this.autoHeight}
|
||||
@change=${
|
||||
/** @param {Event} ev */ ev => {
|
||||
if (ev.target) {
|
||||
this.autoHeight = /** @type {HTMLInputElement} */ (ev.target).checked;
|
||||
}
|
||||
}
|
||||
}
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
renderSameSettings() {
|
||||
return html`
|
||||
<div>
|
||||
<label class="${this.sameSettings ? 'switch selected' : 'switch'}">
|
||||
Same settings for all simulations
|
||||
<span class="switch-button"></span>
|
||||
<input
|
||||
type="checkbox"
|
||||
?checked=${this.sameSettings}
|
||||
@change=${
|
||||
/** @param {Event} ev */ ev => {
|
||||
if (ev.target) {
|
||||
this.sameSettings = /** @type {HTMLInputElement} */ (ev.target).checked;
|
||||
}
|
||||
}
|
||||
}
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
renderRememberSettings() {
|
||||
if (!this.sameSettings) {
|
||||
return html``;
|
||||
}
|
||||
return html`
|
||||
<div>
|
||||
<label class="${this.rememberSettings ? 'switch selected' : 'switch'}">
|
||||
Remember settings
|
||||
<span class="switch-button"></span>
|
||||
<input
|
||||
type="checkbox"
|
||||
?checked=${this.rememberSettings}
|
||||
@change=${
|
||||
/** @param {Event} ev */ ev => {
|
||||
if (ev.target) {
|
||||
this.rememberSettings = /** @type {HTMLInputElement} */ (ev.target).checked;
|
||||
}
|
||||
}
|
||||
}
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
renderSyncSettings() {
|
||||
return html`
|
||||
<div>
|
||||
<h3>Global</h3>
|
||||
${this.renderSameSettings()} ${this.renderRememberSettings()}
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
render() {
|
||||
return html`
|
||||
<div id="wrapper">
|
||||
<div>${this.story({ shadowRoot: this.shadowRoot })}</div>
|
||||
<button id="showCodeButton" @click=${this.toggleShowCode}>show code</button>
|
||||
${this.deviceMode === false
|
||||
? html`<div>${this.story({ shadowRoot: this.shadowRoot })}</div>`
|
||||
: html`
|
||||
<iframe
|
||||
csp=${`script-src ${document.location.origin} 'unsafe-inline'; connect-src ws://${document.location.host}/`}
|
||||
.src=${this.iframeUrl}
|
||||
style=${`width: ${this.sizeData.width}px; height: ${this.deviceHeight}px;`}
|
||||
></iframe>
|
||||
<p class="frame-description" style=${`width: ${this.sizeData.width + 4}px;`}>
|
||||
${this.sizeData.name} - ${this.deviceHeight}x${this.sizeData.width}
|
||||
</p>
|
||||
`}
|
||||
</div>
|
||||
${this.codeHasHtml ? unsafeHTML(this.code) : html`<pre><code>${this.code}</code></pre>`}
|
||||
<lion-accordion class="options">
|
||||
${this.deviceMode
|
||||
? html`
|
||||
<h3 slot="invoker">
|
||||
<button>Settings</button>
|
||||
</h3>
|
||||
<div slot="content">
|
||||
<div class="settings-wrapper">
|
||||
${this.renderPlatforms()} ${this.renderSizes()} ${this.renderThemes()}
|
||||
${this.renderLanguages()} ${this.renderSyncSettings()}
|
||||
</div>
|
||||
</div>
|
||||
`
|
||||
: ''}
|
||||
<h3 slot="invoker">
|
||||
<button>Code</button>
|
||||
</h3>
|
||||
<div slot="content">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</lion-accordion>
|
||||
${this.simulatorUrl
|
||||
? html`
|
||||
<div class="controls">
|
||||
<a href=${this.iframeUrl} target="_blank">Open simulation in new window</a>
|
||||
<button
|
||||
@click=${() => (this.deviceMode = !this.deviceMode)}
|
||||
class="simulation-toggle"
|
||||
>
|
||||
${this.deviceMode ? html`Disable` : html`Enable`} device simulation
|
||||
</button>
|
||||
</div>
|
||||
`
|
||||
: ''}
|
||||
`;
|
||||
}
|
||||
|
||||
static get styles() {
|
||||
return css`
|
||||
:host {
|
||||
border: 1px solid #ccc;
|
||||
display: block;
|
||||
box-shadow: rgba(0, 0, 0, 0.1) 0px 1px 3px 0px;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
#showCodeButton {
|
||||
position: absolute;
|
||||
right: 5px;
|
||||
bottom: 5px;
|
||||
font-size: 12px;
|
||||
line-height: 20px;
|
||||
color: #24292e;
|
||||
background-color: #eff3f6;
|
||||
background-image: linear-gradient(-180deg, #fafbfc, #eff3f6 90%);
|
||||
iframe {
|
||||
border: 2px solid #4caf50;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.switch {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.switch:focus-within .switch-button {
|
||||
box-shadow: 0 0 0 1px hsl(0deg 0% 100% / 40%), 0 0 0 4px rgb(31 117 203 / 48%);
|
||||
}
|
||||
|
||||
.switch-button {
|
||||
display: inline-block;
|
||||
padding: 3px 12px;
|
||||
white-space: nowrap;
|
||||
vertical-align: middle;
|
||||
cursor: pointer;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
background-repeat: repeat-x;
|
||||
background-position: -1px -1px;
|
||||
background-size: 110% 110%;
|
||||
border: 1px solid rgba(27, 31, 35, 0.2);
|
||||
border-radius: 0.25em;
|
||||
-webkit-appearance: none;
|
||||
-moz-appearance: none;
|
||||
appearance: none;
|
||||
}
|
||||
|
||||
#showCodeButton:hover {
|
||||
background-color: #e6ebf1;
|
||||
background-image: linear-gradient(-180deg, #f0f3f6, #e6ebf1 90%);
|
||||
background-position: -0.5em;
|
||||
border-color: rgba(27, 31, 35, 0.35);
|
||||
text-decoration: none;
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
|
||||
#wrapper {
|
||||
width: 44px;
|
||||
background: grey;
|
||||
height: 25px;
|
||||
border-radius: 15px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.switch-button::after {
|
||||
content: ' ';
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
border-radius: 10px;
|
||||
background: rgb(255, 255, 255);
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: 3px;
|
||||
left: 4px;
|
||||
}
|
||||
|
||||
.switch.selected .switch-button {
|
||||
background: green;
|
||||
}
|
||||
|
||||
.switch.selected .switch-button::after {
|
||||
left: auto;
|
||||
right: 4px;
|
||||
}
|
||||
|
||||
.frame-description {
|
||||
margin: -5px 0 10px 0;
|
||||
text-align: right;
|
||||
font-size: 12px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.settings-wrapper {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
grid-gap: 20px 40px;
|
||||
max-width: 650px;
|
||||
}
|
||||
|
||||
@media (min-width: 640px) {
|
||||
.settings-wrapper {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
}
|
||||
}
|
||||
|
||||
.settings-wrapper h3 {
|
||||
margin: 10px 0;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.options {
|
||||
display: block;
|
||||
padding: 15px 0;
|
||||
}
|
||||
|
||||
.controls {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.controls a {
|
||||
color: #3f51b5;
|
||||
font-size: 14px;
|
||||
line-height: 37px;
|
||||
}
|
||||
|
||||
.simulation-toggle {
|
||||
border: 1px solid #3f51b5;
|
||||
border-radius: 9px;
|
||||
padding: 10px;
|
||||
background: none;
|
||||
font-weight: bold;
|
||||
color: #3f51b5;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.simulation-toggle:hover {
|
||||
background-color: #3f51b5;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
h3[slot='invoker'] button {
|
||||
font-size: 16px;
|
||||
display: block;
|
||||
position: relative;
|
||||
padding: 10px;
|
||||
border: none;
|
||||
border-bottom: 1px solid #bbb;
|
||||
width: 100%;
|
||||
background: none;
|
||||
text-align: left;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
h3[slot='invoker'] button::after {
|
||||
content: '>';
|
||||
right: 20px;
|
||||
top: 10px;
|
||||
position: absolute;
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
|
||||
h3[slot='invoker'][expanded='true'] button::after {
|
||||
transform: rotate(-90deg);
|
||||
}
|
||||
|
||||
h3[slot='invoker'][expanded='true'] button {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
[slot='content'] {
|
||||
border-bottom: 1px solid #bbb;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
:host > pre {
|
||||
display: none;
|
||||
margin: 0;
|
||||
padding: 16px;
|
||||
overflow: auto;
|
||||
font-size: 85%;
|
||||
line-height: 1.45;
|
||||
background-color: #f6f8fa;
|
||||
border-radius: 3px;
|
||||
h3[slot='invoker']:first-child button {
|
||||
border-top: 1px solid #bbb;
|
||||
}
|
||||
|
||||
:host([show-code]) > pre {
|
||||
h4 {
|
||||
font-weight: normal;
|
||||
font-size: 14px;
|
||||
margin: 5px 0;
|
||||
}
|
||||
|
||||
.segmented-control {
|
||||
border: 1px solid #3f51b5;
|
||||
border-radius: 18px;
|
||||
display: inline-block;
|
||||
font-size: 14px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.segmented-control span {
|
||||
padding: 5px 10px;
|
||||
display: inline-block;
|
||||
border-radius: 18px;
|
||||
margin: 2px 0;
|
||||
}
|
||||
|
||||
.segmented-control label:first-child span {
|
||||
margin-left: 2px;
|
||||
}
|
||||
|
||||
.segmented-control label:last-child span {
|
||||
margin-right: 2px;
|
||||
}
|
||||
|
||||
.segmented-control label.selected span {
|
||||
background: #3f51b5;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.segmented-control label:focus-within span {
|
||||
box-shadow: 0 0 0 1px hsl(0deg 0% 100% / 40%), 0 0 0 4px rgb(31 117 203 / 48%);
|
||||
}
|
||||
|
||||
.segmented-control input,
|
||||
.switch input {
|
||||
clip: rect(0 0 0 0);
|
||||
clip-path: inset(50%);
|
||||
height: 1px;
|
||||
overflow: hidden;
|
||||
position: absolute;
|
||||
white-space: nowrap;
|
||||
width: 1px;
|
||||
}
|
||||
|
||||
select {
|
||||
display: block;
|
||||
}
|
||||
|
||||
code[class*='language-'],
|
||||
pre[class*='language-'] {
|
||||
color: #393a34;
|
||||
font-family: SFMono-Regular, Consolas, Liberation Mono, Menlo, monospace;
|
||||
direction: ltr;
|
||||
text-align: left;
|
||||
white-space: pre;
|
||||
word-spacing: normal;
|
||||
word-break: normal;
|
||||
tab-size: 4;
|
||||
hyphens: none;
|
||||
overflow: auto;
|
||||
font-size: 85%;
|
||||
line-height: 1.45;
|
||||
background-color: #f6f8fa;
|
||||
padding: 5px;
|
||||
border: 1px solid #333;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.token.function,
|
||||
.token.class-name {
|
||||
color: #6f42c1;
|
||||
}
|
||||
|
||||
.token.tag,
|
||||
.token.selector,
|
||||
.language-autohotkey .token.keyword {
|
||||
color: #22863a;
|
||||
}
|
||||
|
||||
.token.entity,
|
||||
.token.url,
|
||||
.token.symbol,
|
||||
.token.number,
|
||||
.token.boolean,
|
||||
.token.variable,
|
||||
.token.constant,
|
||||
.token.property,
|
||||
.token.inserted,
|
||||
.token.punctuation,
|
||||
.token.operator {
|
||||
color: #005cc5;
|
||||
}
|
||||
|
||||
.token.regex {
|
||||
color: #032f62;
|
||||
}
|
||||
|
||||
.token.atrule,
|
||||
.token.keyword,
|
||||
.token.attr-name,
|
||||
.language-autohotkey .token.selector {
|
||||
color: #d73a49;
|
||||
}
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
import { MdJsPreview } from './src/MdJsPreview.js';
|
||||
import { MdJsPreview } from '../MdJsPreview.js';
|
||||
|
||||
customElements.define('mdjs-preview', MdJsPreview);
|
||||
115
packages/mdjs-preview/src/mdjsViewerSharedStates.js
Normal file
115
packages/mdjs-preview/src/mdjsViewerSharedStates.js
Normal file
@@ -0,0 +1,115 @@
|
||||
const _sharedStates = {
|
||||
platform: 'web',
|
||||
size: 'webSmall',
|
||||
theme: 'light',
|
||||
language: 'en',
|
||||
autoHeight: true,
|
||||
deviceMode: false,
|
||||
rememberSettings: false,
|
||||
edgeDistance: true,
|
||||
};
|
||||
|
||||
/** @type {Function[]} */
|
||||
let subscribeFns = [];
|
||||
|
||||
/**
|
||||
* @param {Function} subscribeFn
|
||||
*/
|
||||
export function subscribe(subscribeFn) {
|
||||
subscribeFns.push(subscribeFn);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Function} subscribeFn
|
||||
*/
|
||||
export function unSubscribe(subscribeFn) {
|
||||
subscribeFns = subscribeFns.filter(fn => fn !== subscribeFn);
|
||||
}
|
||||
|
||||
function storeSettings() {
|
||||
for (const _sharedStateKey of Object.keys(_sharedStates)) {
|
||||
const sharedStateKey = /** @type {keyof _sharedStates} */ (_sharedStateKey);
|
||||
if (_sharedStates.rememberSettings) {
|
||||
localStorage.setItem(
|
||||
`mdjsViewerSharedStates-${sharedStateKey}`,
|
||||
_sharedStates[sharedStateKey].toString(),
|
||||
);
|
||||
} else {
|
||||
localStorage.removeItem(`mdjsViewerSharedStates-${sharedStateKey}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function restoreSettings() {
|
||||
for (const _sharedStateKey of Object.keys(_sharedStates)) {
|
||||
const sharedStateKey = /** @type {keyof _sharedStates} */ (_sharedStateKey);
|
||||
const restoredValue = localStorage.getItem(`mdjsViewerSharedStates-${sharedStateKey}`);
|
||||
if (restoredValue !== null) {
|
||||
switch (sharedStateKey) {
|
||||
case 'autoHeight':
|
||||
case 'deviceMode':
|
||||
case 'rememberSettings':
|
||||
case 'edgeDistance':
|
||||
_sharedStates[sharedStateKey] = restoredValue === 'true' ? true : false;
|
||||
break;
|
||||
default:
|
||||
_sharedStates[sharedStateKey] = restoredValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
restoreSettings();
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {import('./MdJsPreview.js').MdJsPreview} target
|
||||
*/
|
||||
export function applySharedStates(target) {
|
||||
for (const _sharedStateKey of Object.keys(_sharedStates)) {
|
||||
const sharedStateKey = /** @type {keyof _sharedStates} */ (_sharedStateKey);
|
||||
switch (sharedStateKey) {
|
||||
case 'autoHeight':
|
||||
case 'deviceMode':
|
||||
case 'rememberSettings':
|
||||
case 'edgeDistance':
|
||||
target[sharedStateKey] = _sharedStates[sharedStateKey];
|
||||
break;
|
||||
default:
|
||||
target[sharedStateKey] = _sharedStates[sharedStateKey];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {import('./MdJsPreview.js').MdJsPreview} target
|
||||
* @param {Function} subscribedFn
|
||||
*/
|
||||
export function saveToSharedStates(target, subscribedFn) {
|
||||
let updated = false;
|
||||
for (const _sharedStateKey of Object.keys(_sharedStates)) {
|
||||
const sharedStateKey = /** @type {keyof _sharedStates} */ (_sharedStateKey);
|
||||
if (_sharedStates[sharedStateKey] !== target[sharedStateKey]) {
|
||||
switch (sharedStateKey) {
|
||||
case 'autoHeight':
|
||||
case 'deviceMode':
|
||||
case 'rememberSettings':
|
||||
case 'edgeDistance':
|
||||
_sharedStates[sharedStateKey] = target[sharedStateKey];
|
||||
break;
|
||||
default:
|
||||
_sharedStates[sharedStateKey] = target[sharedStateKey];
|
||||
}
|
||||
updated = true;
|
||||
}
|
||||
}
|
||||
if (updated) {
|
||||
storeSettings();
|
||||
for (const subscribeFn of subscribeFns) {
|
||||
if (subscribeFn !== subscribedFn) {
|
||||
subscribeFn();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
19
packages/mdjs-preview/src/resizeHandler.js
Normal file
19
packages/mdjs-preview/src/resizeHandler.js
Normal file
@@ -0,0 +1,19 @@
|
||||
let addedCount = 0;
|
||||
|
||||
export function addResizeHandler() {
|
||||
if (addedCount > 0) {
|
||||
addedCount += 1;
|
||||
return;
|
||||
}
|
||||
window.addEventListener('message', ev => {
|
||||
const data = JSON.parse(ev.data);
|
||||
if (data.action === 'mdjs-viewer-resize') {
|
||||
const viewer = /** @type {import('./MdJsPreview.js').MdJsPreview} */ (document.body.querySelector(
|
||||
`[mdjs-story-name="${data.storyKey}"]`,
|
||||
));
|
||||
if (viewer) {
|
||||
viewer.contentHeight = data.height;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
38
packages/mdjs-preview/test-web/mdjs-preview.test.js
Normal file
38
packages/mdjs-preview/test-web/mdjs-preview.test.js
Normal file
@@ -0,0 +1,38 @@
|
||||
import { expect, fixture, html } from '@open-wc/testing';
|
||||
import '@mdjs/mdjs-preview/define';
|
||||
|
||||
/** @typedef {import('@mdjs/mdjs-preview').MdJsPreview} MdJsPreview */
|
||||
|
||||
describe('mdjs-preview', () => {
|
||||
it('will render the element into the shadow root by default', async () => {
|
||||
const el = await fixture(html`
|
||||
<mdjs-preview .story=${() => html`<p id="testing"></p>`}></mdjs-preview>
|
||||
`);
|
||||
expect(el.shadowRoot.querySelectorAll('#testing').length).to.equal(1);
|
||||
});
|
||||
|
||||
it('sync simulator states between instances', async () => {
|
||||
const el = await fixture(html`
|
||||
<div>
|
||||
<mdjs-preview .story=${() => html`<p></p>`}></mdjs-preview>
|
||||
<mdjs-preview .story=${() => html`<p></p>`}></mdjs-preview>
|
||||
</div>
|
||||
`);
|
||||
const [preview1, preview2] = /** @type {MdJsPreview[]} */ (el.children);
|
||||
preview1.platform = 'web';
|
||||
preview1.edgeDistance = true;
|
||||
await preview1.updateComplete;
|
||||
expect(preview1.platform).to.equal('web');
|
||||
expect(preview2.platform).to.equal('web');
|
||||
expect(preview1.edgeDistance).to.be.true;
|
||||
expect(preview2.edgeDistance).to.be.true;
|
||||
|
||||
preview1.platform = 'android';
|
||||
preview1.edgeDistance = false;
|
||||
await preview1.updateComplete;
|
||||
expect(preview1.platform).to.equal('android');
|
||||
expect(preview2.platform).to.equal('android');
|
||||
expect(preview1.edgeDistance).to.be.false;
|
||||
expect(preview2.edgeDistance).to.be.false;
|
||||
});
|
||||
});
|
||||
@@ -1,5 +1,11 @@
|
||||
# @mdjs/mdjs-story
|
||||
|
||||
## 0.2.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 604a80e: Force `/define`Ï entrypoint via export map
|
||||
|
||||
## 0.1.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@mdjs/mdjs-story",
|
||||
"version": "0.1.2",
|
||||
"version": "0.2.0",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
@@ -17,7 +17,7 @@
|
||||
"type": "module",
|
||||
"exports": {
|
||||
".": "./index.js",
|
||||
"./mdjs-story.js": "./mdjs-story.js"
|
||||
"./define": "./src/define.js"
|
||||
},
|
||||
"scripts": {
|
||||
"debug": "cd ../../ && npm run debug -- --group mdjs-story",
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
import { MdJsStory } from './src/MdJsStory.js';
|
||||
import { MdJsStory } from './MdJsStory.js';
|
||||
|
||||
customElements.define('mdjs-story', MdJsStory);
|
||||
@@ -1,5 +1,19 @@
|
||||
# @rocket/navigation
|
||||
|
||||
## 0.2.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 728a205: feat(navigation): add no-redirects attribute
|
||||
|
||||
By default, the sidebar nav redirects clicks on category headings to
|
||||
their first child.
|
||||
|
||||
To disable those redirects, override
|
||||
\_includes/\_joiningBlocks/\_layoutSidebar/sidebar/20-navigation.njk
|
||||
and add the no-redirects attribute to the <rocket-navigation>
|
||||
element.
|
||||
|
||||
## 0.2.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@rocket/navigation",
|
||||
"version": "0.2.0",
|
||||
"version": "0.2.1",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
|
||||
@@ -1,3 +1,27 @@
|
||||
/**
|
||||
* Debounce a function
|
||||
* @template {(this: any, ...args: any[]) => void} T
|
||||
* @param {T} func function
|
||||
* @param {number} wait time in milliseconds to debounce
|
||||
* @param {boolean} immediate when true, run immediately and on the leading edge
|
||||
* @return {T} debounced function
|
||||
*/
|
||||
function debounce(func, wait, immediate) {
|
||||
/** @type {number|undefined} */
|
||||
let timeout;
|
||||
return /** @type {typeof func}*/ (function () {
|
||||
let args = /** @type {Parameters<typeof func>} */ (/** @type {unknown}*/ (arguments));
|
||||
const later = () => {
|
||||
timeout = undefined;
|
||||
if (!immediate) func.apply(this, args);
|
||||
};
|
||||
const callNow = immediate && !timeout;
|
||||
clearTimeout(timeout);
|
||||
timeout = setTimeout(later, wait);
|
||||
if (callNow) func.apply(this, args);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {object} NavigationListItem
|
||||
* @property {HTMLElement} headline
|
||||
@@ -5,12 +29,17 @@
|
||||
* @property {number} top
|
||||
*/
|
||||
|
||||
/**
|
||||
* @element rocket-navigation
|
||||
* @attr {Boolean} no-redirects - if set, will not redirect to first child of nav category when clicking on category header.
|
||||
*/
|
||||
export class RocketNavigation extends HTMLElement {
|
||||
constructor() {
|
||||
super();
|
||||
/** @type NavigationListItem[] */
|
||||
this.list = [];
|
||||
this.__scrollHandler = this.__scrollHandler.bind(this);
|
||||
this.__clickHandler = this.__clickHandler.bind(this);
|
||||
this.__scrollHandler = debounce(this.__scrollHandler.bind(this), 25, true);
|
||||
this.__isSetup = false;
|
||||
}
|
||||
|
||||
@@ -20,27 +49,7 @@ export class RocketNavigation extends HTMLElement {
|
||||
}
|
||||
this.__isSetup = true;
|
||||
|
||||
this.addEventListener('click', ev => {
|
||||
const el = /** @type {HTMLElement} */ (ev.target);
|
||||
if (el.classList.contains('anchor')) {
|
||||
const anchor = /** @type {HTMLAnchorElement} */ (el);
|
||||
ev.preventDefault();
|
||||
this.dispatchEvent(new Event('close-overlay', { bubbles: true }));
|
||||
// wait for closing animation to finish before start scrolling
|
||||
setTimeout(() => {
|
||||
const parsedUrl = new URL(anchor.href);
|
||||
document.location.hash = parsedUrl.hash;
|
||||
}, 250);
|
||||
}
|
||||
const links = el.parentElement?.querySelectorAll('ul a');
|
||||
if (links && links.length > 1) {
|
||||
const subLink = /** @type {HTMLAnchorElement} */ (links[1]);
|
||||
if (!subLink.classList.contains('anchor')) {
|
||||
ev.preventDefault();
|
||||
subLink.click();
|
||||
}
|
||||
}
|
||||
});
|
||||
this.addEventListener('click', this.__clickHandler);
|
||||
|
||||
const anchors = /** @type {NodeListOf<HTMLAnchorElement>} */ (this.querySelectorAll(
|
||||
'li.current a.anchor',
|
||||
@@ -57,12 +66,41 @@ export class RocketNavigation extends HTMLElement {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: debounce
|
||||
window.addEventListener('scroll', this.__scrollHandler);
|
||||
window.addEventListener('scroll', this.__scrollHandler, { passive: true });
|
||||
|
||||
this.__scrollHandler();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Event} ev
|
||||
*/
|
||||
__clickHandler(ev) {
|
||||
const el = /** @type {HTMLElement} */ (ev.target);
|
||||
if (el.classList.contains('anchor')) {
|
||||
const anchor =
|
||||
el instanceof HTMLAnchorElement
|
||||
? el
|
||||
: /** @type{HTMLAnchorElement} */ (el.querySelector('a.anchor'));
|
||||
ev.preventDefault();
|
||||
this.dispatchEvent(new Event('close-overlay', { bubbles: true }));
|
||||
// wait for closing animation to finish before start scrolling
|
||||
setTimeout(() => {
|
||||
const parsedUrl = new URL(anchor.href);
|
||||
document.location.hash = parsedUrl.hash;
|
||||
}, 250);
|
||||
}
|
||||
if (!this.hasAttribute('no-redirects')) {
|
||||
const links = el.parentElement?.querySelectorAll('ul a');
|
||||
if (links && links.length > 1) {
|
||||
const subLink = /** @type {HTMLAnchorElement} */ (links[1]);
|
||||
if (!subLink.classList.contains('anchor')) {
|
||||
ev.preventDefault();
|
||||
subLink.click();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
__scrollHandler() {
|
||||
for (const listObj of this.list) {
|
||||
listObj.top = listObj.headline.getBoundingClientRect().top;
|
||||
|
||||
@@ -58,7 +58,8 @@ describe('rocket-navigation', () => {
|
||||
expect(anchorSpy).to.not.be.called;
|
||||
});
|
||||
|
||||
it('will mark the currently "active" headline in the menu', async () => {
|
||||
it('will mark the currently "active" headline in the menu', async function () {
|
||||
this.timeout(5000);
|
||||
function addBlock(headline, length = 5) {
|
||||
return html`
|
||||
<h2 id="${headline}">${headline}</h2>
|
||||
@@ -96,20 +97,20 @@ describe('rocket-navigation', () => {
|
||||
}
|
||||
</style>
|
||||
`);
|
||||
await aTimeout(0);
|
||||
await aTimeout(50);
|
||||
const anchorLis = wrapper.querySelectorAll('.menu-item.anchor');
|
||||
expect(anchorLis[0]).to.have.class('current');
|
||||
expect(anchorLis[1]).to.not.have.class('current');
|
||||
expect(anchorLis[2]).to.not.have.class('current');
|
||||
|
||||
document.querySelector('#middle').scrollIntoView();
|
||||
await aTimeout(20);
|
||||
await aTimeout(100);
|
||||
expect(anchorLis[0]).to.not.have.class('current');
|
||||
expect(anchorLis[1]).to.have.class('current');
|
||||
expect(anchorLis[2]).to.not.have.class('current');
|
||||
|
||||
document.querySelector('#bottom').scrollIntoView();
|
||||
await aTimeout(20);
|
||||
await aTimeout(100);
|
||||
expect(anchorLis[0]).to.not.have.class('current');
|
||||
expect(anchorLis[1]).to.not.have.class('current');
|
||||
expect(anchorLis[2]).to.have.class('current');
|
||||
|
||||
@@ -13,8 +13,8 @@
|
||||
},
|
||||
"author": "Modern Web <hello@modern-web.dev> (https://modern-web.dev/)",
|
||||
"homepage": "https://rocket.modern-web.dev/docs/tools/plugins-manager/",
|
||||
"type": "module",
|
||||
"main": "./dist/index.cjs",
|
||||
"type": "module",
|
||||
"exports": {
|
||||
".": {
|
||||
"require": "./dist/index.cjs",
|
||||
|
||||
@@ -1,5 +1,18 @@
|
||||
# @rocket/search
|
||||
|
||||
## 0.3.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 818caad: chore: generalize label & add alt when no img
|
||||
- 0b64116: Update @lion dependencies
|
||||
|
||||
## 0.3.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 302227e: Add variable for border-radius of SearchCombobox
|
||||
|
||||
## 0.3.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@rocket/search",
|
||||
"version": "0.3.1",
|
||||
"version": "0.3.3",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
@@ -13,8 +13,8 @@
|
||||
},
|
||||
"author": "Modern Web <hello@modern-web.dev> (https://modern-web.dev/)",
|
||||
"homepage": "https://rocket.modern-web.dev/docs/presets/search/",
|
||||
"type": "module",
|
||||
"main": "./node.js",
|
||||
"type": "module",
|
||||
"exports": {
|
||||
".": "./node.js",
|
||||
"./node": "./node.js",
|
||||
@@ -41,7 +41,7 @@
|
||||
"search"
|
||||
],
|
||||
"dependencies": {
|
||||
"@lion/combobox": "^0.1.20",
|
||||
"@lion/combobox": "^0.5.1",
|
||||
"@open-wc/scoped-elements": "^1.3.2",
|
||||
"chalk": "^4.0.0",
|
||||
"minisearch": "^3.0.2",
|
||||
|
||||
@@ -112,7 +112,7 @@ export class RocketSearch extends ScopedElementsMixin(LitElement) {
|
||||
return html`
|
||||
<rocket-search-combobox
|
||||
name="combo"
|
||||
label="Rocket Search"
|
||||
label="Search"
|
||||
@input=${ev => {
|
||||
this.search = ev.target.value;
|
||||
}}
|
||||
|
||||
@@ -138,7 +138,7 @@ export class RocketSearchCombobox extends LionCombobox {
|
||||
display: flex;
|
||||
border: 1px solid var(--rocket-search-input-border-color, #dfe1e5);
|
||||
box-shadow: none;
|
||||
border-radius: 24px;
|
||||
border-radius: var(--rocket-search-input-border-radius, 24px);
|
||||
padding: 5px 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -103,7 +103,7 @@ export class RocketSearchOption extends LinkMixin(LionOption) {
|
||||
|
||||
render() {
|
||||
return html`
|
||||
<img class="icon" src=${getIcon(this.section)} />
|
||||
<img class="icon" src=${getIcon(this.section)} alt=${this.section} />
|
||||
<div class="choice-field__label">
|
||||
<div class="title">${unsafeHTML(this.title)}</div>
|
||||
<div class="text">${unsafeHTML(this.text)}</div>
|
||||
|
||||
@@ -2,10 +2,16 @@ import { rocketLaunch } from '@rocket/launch';
|
||||
import { rocketBlog } from '@rocket/blog';
|
||||
import { rocketSearch } from '@rocket/search';
|
||||
import { absoluteBaseUrlNetlify } from '@rocket/core/helpers';
|
||||
import { adjustPluginOptions } from 'plugins-manager';
|
||||
|
||||
export default {
|
||||
presets: [rocketLaunch(), rocketBlog(), rocketSearch()],
|
||||
absoluteBaseUrl: absoluteBaseUrlNetlify('http://localhost:8080'),
|
||||
setupUnifiedPlugins: [
|
||||
adjustPluginOptions('mdjsSetupCode', {
|
||||
simulationSettings: { simulatorUrl: '/simulator/' },
|
||||
}),
|
||||
],
|
||||
|
||||
// emptyOutputDir: false,
|
||||
};
|
||||
|
||||
207
yarn.lock
207
yarn.lock
@@ -1134,59 +1134,66 @@
|
||||
dependencies:
|
||||
"@hapi/hoek" "^8.3.0"
|
||||
|
||||
"@lion/combobox@^0.1.20":
|
||||
version "0.1.20"
|
||||
resolved "https://registry.yarnpkg.com/@lion/combobox/-/combobox-0.1.20.tgz#9514c655171773a12f9c841187297f8791a029a6"
|
||||
integrity sha512-Iw3BzZv7K36c2ReBDD76298VrNTPe7XElGAnr9/jzTH22eJdZD33DBXcY3D/tJlrhh02aC+4nTYxTww33lRqCA==
|
||||
"@lion/accordion@^0.4.2":
|
||||
version "0.4.2"
|
||||
resolved "https://registry.yarnpkg.com/@lion/accordion/-/accordion-0.4.2.tgz#efeb56360113a2b68e182ff29ef0932edd17df8c"
|
||||
integrity sha512-xETjNmpBWYO1tYx2nBMq0I45UgydUJafZ4ft3szH3fQFjYWSBwjJjKsWxIhZSqX/IoTJzA0nNCdtbXoVEbSCLg==
|
||||
dependencies:
|
||||
"@lion/core" "0.13.7"
|
||||
"@lion/form-core" "0.7.0"
|
||||
"@lion/listbox" "0.4.0"
|
||||
"@lion/overlays" "0.23.2"
|
||||
"@lion/core" "0.16.0"
|
||||
|
||||
"@lion/core@0.13.7":
|
||||
version "0.13.7"
|
||||
resolved "https://registry.yarnpkg.com/@lion/core/-/core-0.13.7.tgz#c49cff0c7199711c14d9758b8e340cd93aca2f8c"
|
||||
integrity sha512-9KwCwd1DDM26wLEib30Lw/6Nexcz3o1SSxnBlOdLFE/akJhi9nZOK1YmlSefL0XosND8ngCa1DXn348W8B693w==
|
||||
"@lion/combobox@^0.5.1":
|
||||
version "0.5.1"
|
||||
resolved "https://registry.yarnpkg.com/@lion/combobox/-/combobox-0.5.1.tgz#6395d5c34f0935aee32034584a253c1a2c6fa717"
|
||||
integrity sha512-sOpJLCH8pzZAOohrqVnlTjC7L93tavXugSV2SqhVsFFnSQIWXytaeL8eJPlVBrTrmcOpns6AQX2uyBbeY6ZTsg==
|
||||
dependencies:
|
||||
"@lion/core" "0.16.0"
|
||||
"@lion/form-core" "0.11.0"
|
||||
"@lion/listbox" "0.7.0"
|
||||
"@lion/overlays" "0.26.1"
|
||||
|
||||
"@lion/core@0.16.0":
|
||||
version "0.16.0"
|
||||
resolved "https://registry.yarnpkg.com/@lion/core/-/core-0.16.0.tgz#c4c8ac81b8d5bece6d40d561a392382c7ae73533"
|
||||
integrity sha512-/MB/G44fZtL+s8iX1GAnyjw+Drn+fROkA13BpTn808UrDMGQ+WW1oq67Wp9Hr+t34LB3ghH3tm7afniDMa1VCA==
|
||||
dependencies:
|
||||
"@open-wc/dedupe-mixin" "^1.2.18"
|
||||
"@open-wc/scoped-elements" "^1.3.2"
|
||||
"@open-wc/scoped-elements" "^1.3.3"
|
||||
lit-element "~2.4.0"
|
||||
lit-html "^1.3.0"
|
||||
|
||||
"@lion/form-core@0.7.0":
|
||||
"@lion/form-core@0.11.0":
|
||||
version "0.11.0"
|
||||
resolved "https://registry.yarnpkg.com/@lion/form-core/-/form-core-0.11.0.tgz#83985baba62e11082b42ea84f3683f72a8f36fcf"
|
||||
integrity sha512-opDXzTtVHJlRo+BLSI0dtSjbIz7PsJL80wnU8WAK3S+WNH5z2S37OBCoVvOVpXRpoqGAj5L/BmaJnHZeo6pPYw==
|
||||
dependencies:
|
||||
"@lion/core" "0.16.0"
|
||||
"@lion/localize" "0.18.0"
|
||||
|
||||
"@lion/listbox@0.7.0":
|
||||
version "0.7.0"
|
||||
resolved "https://registry.yarnpkg.com/@lion/form-core/-/form-core-0.7.0.tgz#0df2cefb62876dd62e2baa980129ed7bf790b3ae"
|
||||
integrity sha512-5aWqKNQgJKgqJC6VIRNoGe5imz9w0thLEnPqWJ8y6vSru/BC114ZLefvmltK9FG21DPkPOCa+vm4PSjilaqh1w==
|
||||
resolved "https://registry.yarnpkg.com/@lion/listbox/-/listbox-0.7.0.tgz#bd1d8cb25098387fd0ae1087f8dd641510f741f0"
|
||||
integrity sha512-wHGqahRIjpTmMAvU/hDZyDGNhmjRj6FEYSWn7Z3ugE52D9a1PQd7HVc1cVVIRc71jC3w4n5ZYVeZChwR3N3fWw==
|
||||
dependencies:
|
||||
"@lion/core" "0.13.7"
|
||||
"@lion/localize" "0.15.4"
|
||||
"@lion/core" "0.16.0"
|
||||
"@lion/form-core" "0.11.0"
|
||||
|
||||
"@lion/listbox@0.4.0":
|
||||
version "0.4.0"
|
||||
resolved "https://registry.yarnpkg.com/@lion/listbox/-/listbox-0.4.0.tgz#429838fd75d40662b67e5a3f611bf3ea94b506de"
|
||||
integrity sha512-bwVIlVX0cQoKKGf6HNqDmTH5JUM0TKAzZuHsrmLcsYG9V5bgMjfiLBXPNQxyy39WOwicPM8f2g+O5rRXBcsIYQ==
|
||||
dependencies:
|
||||
"@lion/core" "0.13.7"
|
||||
"@lion/form-core" "0.7.0"
|
||||
|
||||
"@lion/localize@0.15.4":
|
||||
version "0.15.4"
|
||||
resolved "https://registry.yarnpkg.com/@lion/localize/-/localize-0.15.4.tgz#b9ed5eb5b3a1304694314b4d6bbbcddc0b85f616"
|
||||
integrity sha512-OP7Og/JXWl4Wm+AzLNKcCAoeft5eQfZlkvEFqOnRuGAXxotbxwk+yQB3kI/K7QvLURNQbv6mzwdDu2buhZdV9w==
|
||||
"@lion/localize@0.18.0":
|
||||
version "0.18.0"
|
||||
resolved "https://registry.yarnpkg.com/@lion/localize/-/localize-0.18.0.tgz#beaf8c161feb58ecab670892c06e7b524527b7e8"
|
||||
integrity sha512-+adOGlot4IItOy1udLKflZlO2fTKM7R0Ji7iZ5SEVG80XOZxC3RXjVM7mWSd5wqcCUe51j1P/tgKM3vDLF0RAw==
|
||||
dependencies:
|
||||
"@bundled-es-modules/message-format" "6.0.4"
|
||||
"@lion/core" "0.13.7"
|
||||
singleton-manager "1.2.1"
|
||||
"@lion/core" "0.16.0"
|
||||
singleton-manager "1.4.1"
|
||||
|
||||
"@lion/overlays@0.23.2", "@lion/overlays@^0.23.2":
|
||||
version "0.23.2"
|
||||
resolved "https://registry.yarnpkg.com/@lion/overlays/-/overlays-0.23.2.tgz#cfdff6cb7ee4f46cdaa621574affbe2e9c374976"
|
||||
integrity sha512-nKVSn37arx9+gdmlIj3gEkpJXGTnsUvbOEXcymLEFJBekvdYKCNWDe9bVBX/iTBBsgO0rQ9+eA5RskxwKPdraQ==
|
||||
"@lion/overlays@0.26.1", "@lion/overlays@^0.26.1":
|
||||
version "0.26.1"
|
||||
resolved "https://registry.yarnpkg.com/@lion/overlays/-/overlays-0.26.1.tgz#d1bfa4f5f97108982afa7b409ba4300f8b2d2ba5"
|
||||
integrity sha512-1FvphbR/yTQ1WtcB1gNuH772i9qAydQkI6NwibIw8QeOGXisA+6SChv2OHS7CijlpDJnDxNyX44LGdDM1/Pd8A==
|
||||
dependencies:
|
||||
"@lion/core" "0.13.7"
|
||||
"@lion/core" "0.16.0"
|
||||
"@popperjs/core" "^2.5.4"
|
||||
singleton-manager "1.2.1"
|
||||
singleton-manager "1.4.1"
|
||||
|
||||
"@manypkg/find-root@^1.1.0":
|
||||
version "1.1.0"
|
||||
@@ -1251,6 +1258,14 @@
|
||||
"@open-wc/dedupe-mixin" "^1.3.0"
|
||||
lit-html "^1.0.0"
|
||||
|
||||
"@open-wc/scoped-elements@^1.3.3":
|
||||
version "1.3.3"
|
||||
resolved "https://registry.yarnpkg.com/@open-wc/scoped-elements/-/scoped-elements-1.3.3.tgz#fe008aef4d74fb00c553c900602960638fc1c7b0"
|
||||
integrity sha512-vFIQVYYjFw67odUE4JzZOpctnF7S/2DX+S+clrL3bQPql7HvEnV0wMFwOWUavQTuCJi0rfU8GTcNMiUybio+Yg==
|
||||
dependencies:
|
||||
"@open-wc/dedupe-mixin" "^1.3.0"
|
||||
lit-html "^1.0.0"
|
||||
|
||||
"@open-wc/semantic-dom-diff@^0.13.16":
|
||||
version "0.13.21"
|
||||
resolved "https://registry.yarnpkg.com/@open-wc/semantic-dom-diff/-/semantic-dom-diff-0.13.21.tgz#718b9ec5f9a98935fc775e577ad094ae8d8b7dea"
|
||||
@@ -1856,25 +1871,32 @@
|
||||
"@types/parse5" "^5.0.3"
|
||||
parse5 "^6.0.1"
|
||||
|
||||
"@web/polyfills-loader@^1.0.1":
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@web/polyfills-loader/-/polyfills-loader-1.0.1.tgz#cee51b6aa956a3c061c5018ce14424958b85946a"
|
||||
integrity sha512-2c2UQpAYT2xSmo7mwf3RHsl9o7toB+dzVZbLEoDKCRhKX4T4jeiCSL828HrgHffckDI/PDIrsXtJ+SLvu4xGvg==
|
||||
"@web/parse5-utils@^1.2.2":
|
||||
version "1.2.2"
|
||||
resolved "https://registry.yarnpkg.com/@web/parse5-utils/-/parse5-utils-1.2.2.tgz#33eec93321eb07cf364651c131b980a7afd8c4d7"
|
||||
integrity sha512-B68DoJ5qF8Cu3o7nDA2RQTCf9bslVz2b0WHTk3qir5YCbWfhnPEGhDOedOjbE8xDiHqgzI1zXQsJ2+655aluLA==
|
||||
dependencies:
|
||||
"@babel/core" "^7.11.1"
|
||||
"@types/parse5" "^5.0.3"
|
||||
parse5 "^6.0.1"
|
||||
|
||||
"@web/polyfills-loader@^1.1.0":
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@web/polyfills-loader/-/polyfills-loader-1.1.0.tgz#9df3da3d40159fce55c17cc370750052f62798bd"
|
||||
integrity sha512-1bF1nhFG25isy6NbMhz9jVBCoXqrB1WzxkhT8Pyw9vKhXO+F83+TUWp0QeInsvvDVo0QPIeg+bVz6spRJrvfkg==
|
||||
dependencies:
|
||||
"@babel/core" "^7.12.10"
|
||||
"@web/parse5-utils" "^1.1.2"
|
||||
"@webcomponents/webcomponentsjs" "^2.5.0"
|
||||
abortcontroller-polyfill "^1.4.0"
|
||||
core-js-bundle "^3.6.0"
|
||||
deepmerge "^4.2.2"
|
||||
abortcontroller-polyfill "^1.5.0"
|
||||
core-js-bundle "^3.8.1"
|
||||
dynamic-import-polyfill "^0.1.1"
|
||||
intersection-observer "^0.11.0"
|
||||
parse5 "^6.0.0"
|
||||
regenerator-runtime "^0.13.3"
|
||||
intersection-observer "^0.12.0"
|
||||
parse5 "^6.0.1"
|
||||
regenerator-runtime "^0.13.7"
|
||||
resize-observer-polyfill "^1.5.1"
|
||||
systemjs "^6.7.1"
|
||||
terser "^5.3.8"
|
||||
whatwg-fetch "^3.0.0"
|
||||
systemjs "^6.8.1"
|
||||
terser "^5.5.1"
|
||||
whatwg-fetch "^3.5.0"
|
||||
|
||||
"@web/rollup-plugin-copy@^0.2.0":
|
||||
version "0.2.0"
|
||||
@@ -1883,12 +1905,12 @@
|
||||
dependencies:
|
||||
glob "^7.0.0"
|
||||
|
||||
"@web/rollup-plugin-html@^1.4.0":
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/@web/rollup-plugin-html/-/rollup-plugin-html-1.4.0.tgz#bf94d1ee525e5f41dc527bbff9f7e24973a82238"
|
||||
integrity sha512-AYOeRuNsPXQmNpxlJRFLlfVMm4EazXcJEz0bbVd6wKQVcEBM71kRboGfupxhoIkDcVyThefw9gETcMZ4ntUcTw==
|
||||
"@web/rollup-plugin-html@^1.6.0":
|
||||
version "1.6.0"
|
||||
resolved "https://registry.yarnpkg.com/@web/rollup-plugin-html/-/rollup-plugin-html-1.6.0.tgz#fd3f406fd6d74a0cded581953a3146fe9f0454ad"
|
||||
integrity sha512-m5xDI6ZhdAI2nfHwU3NXJ/dcDWghR+g/RrlAtIWYlj8NvXk/ZNqVVK1NbJrI/e5RlgDQ/+OycjmKgyAP9W1tWA==
|
||||
dependencies:
|
||||
"@web/parse5-utils" "^1.1.2"
|
||||
"@web/parse5-utils" "^1.2.2"
|
||||
glob "^7.1.6"
|
||||
parse5 "^6.0.1"
|
||||
|
||||
@@ -1901,12 +1923,12 @@
|
||||
estree-walker "^2.0.1"
|
||||
magic-string "^0.25.7"
|
||||
|
||||
"@web/rollup-plugin-polyfills-loader@^1.0.3":
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@web/rollup-plugin-polyfills-loader/-/rollup-plugin-polyfills-loader-1.0.3.tgz#26b162c20cf22100117c154793d6be232cbb979b"
|
||||
integrity sha512-9DkZy0x5F+axj3gDx36x5mxvqg9ugVIS85hCZT2uDEBJ1VBVdSG0pzI5R5zHaLAq/Xk88D999S0zLVRE7DKuHw==
|
||||
"@web/rollup-plugin-polyfills-loader@^1.1.0":
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@web/rollup-plugin-polyfills-loader/-/rollup-plugin-polyfills-loader-1.1.0.tgz#5d49c11c6e9874550d8bac2934d368e6437c9982"
|
||||
integrity sha512-p3GtEKeeyRJa5S/sKWpIa3eg+fiPeYux+Z+r85kxyAw4FY+4AOts9vEeg1McEDjCZ/4V40X2vaPTi1alFBNrig==
|
||||
dependencies:
|
||||
"@web/polyfills-loader" "^1.0.1"
|
||||
"@web/polyfills-loader" "^1.1.0"
|
||||
|
||||
"@web/test-runner-chrome@^0.9.0":
|
||||
version "0.9.0"
|
||||
@@ -2010,10 +2032,10 @@ abbrev@1:
|
||||
resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8"
|
||||
integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==
|
||||
|
||||
abortcontroller-polyfill@^1.4.0:
|
||||
version "1.5.0"
|
||||
resolved "https://registry.yarnpkg.com/abortcontroller-polyfill/-/abortcontroller-polyfill-1.5.0.tgz#2c562f530869abbcf88d949a2b60d1d402e87a7c"
|
||||
integrity sha512-O6Xk757Jb4o0LMzMOMdWvxpHWrQzruYBaUruFaIOfAQRnWFxfdXYobw12jrVHGtoXk6WiiyYzc0QWN9aL62HQA==
|
||||
abortcontroller-polyfill@^1.5.0:
|
||||
version "1.7.1"
|
||||
resolved "https://registry.yarnpkg.com/abortcontroller-polyfill/-/abortcontroller-polyfill-1.7.1.tgz#27084bac87d78a7224c8ee78135d05df430c2d2f"
|
||||
integrity sha512-yml9NiDEH4M4p0G4AcPkg8AAa4mF3nfYF28VQxaokpO67j9H7gWgmsVWJ/f1Rn+PzsnDYvzJzWIQzCqDKRvWlA==
|
||||
|
||||
accepts@^1.3.5, accepts@~1.3.4:
|
||||
version "1.3.7"
|
||||
@@ -3133,10 +3155,10 @@ copyfiles@^2.4.1:
|
||||
untildify "^4.0.0"
|
||||
yargs "^16.1.0"
|
||||
|
||||
core-js-bundle@^3.6.0:
|
||||
version "3.8.1"
|
||||
resolved "https://registry.yarnpkg.com/core-js-bundle/-/core-js-bundle-3.8.1.tgz#a4445eff5da56e316f68365ec89648be1027a808"
|
||||
integrity sha512-bkulwU0ZPkG9aZ79JCRL5ltTSvxP9YsKfyZ6ZpGolJ8BEDGK3BFPPmQ2LlWSuhSshcIxIQzArCSXBYacyGf+aQ==
|
||||
core-js-bundle@^3.8.1:
|
||||
version "3.10.2"
|
||||
resolved "https://registry.yarnpkg.com/core-js-bundle/-/core-js-bundle-3.10.2.tgz#16734b2674373afa40f0533b985a1c9e87bd426f"
|
||||
integrity sha512-cU/daFGOLWwtNAdXBksUl2HNqPOaM5g6bMxJ8doMw9PkshbWSzUweog2EEJsIlgmCCAFI0NLDBl4SD2TzZEevw==
|
||||
|
||||
core-js-compat@^3.8.0:
|
||||
version "3.8.1"
|
||||
@@ -4745,10 +4767,10 @@ inline-style-parser@0.1.1:
|
||||
resolved "https://registry.yarnpkg.com/inline-style-parser/-/inline-style-parser-0.1.1.tgz#ec8a3b429274e9c0a1f1c4ffa9453a7fef72cea1"
|
||||
integrity sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==
|
||||
|
||||
intersection-observer@^0.11.0:
|
||||
version "0.11.0"
|
||||
resolved "https://registry.yarnpkg.com/intersection-observer/-/intersection-observer-0.11.0.tgz#f4ea067070326f68393ee161cc0a2ca4c0040c6f"
|
||||
integrity sha512-KZArj2QVnmdud9zTpKf279m2bbGfG+4/kn16UU0NL3pTVl52ZHiJ9IRNSsnn6jaHrL9EGLFM5eWjTx2fz/+zoQ==
|
||||
intersection-observer@^0.12.0:
|
||||
version "0.12.0"
|
||||
resolved "https://registry.yarnpkg.com/intersection-observer/-/intersection-observer-0.12.0.tgz#6c84628f67ce8698e5f9ccf857d97718745837aa"
|
||||
integrity sha512-2Vkz8z46Dv401zTWudDGwO7KiGHNDkMv417T5ItcNYfmvHR/1qCTVBO9vwH8zZmQ0WkA/1ARwpysR9bsnop4NQ==
|
||||
|
||||
ip@^1.1.5:
|
||||
version "1.1.5"
|
||||
@@ -7144,7 +7166,7 @@ regenerator-runtime@^0.11.0:
|
||||
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9"
|
||||
integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==
|
||||
|
||||
regenerator-runtime@^0.13.3, regenerator-runtime@^0.13.4:
|
||||
regenerator-runtime@^0.13.4, regenerator-runtime@^0.13.7:
|
||||
version "0.13.7"
|
||||
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz#cac2dacc8a1ea675feaabaeb8ae833898ae46f55"
|
||||
integrity sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==
|
||||
@@ -7698,10 +7720,10 @@ simple-swizzle@^0.2.2:
|
||||
dependencies:
|
||||
is-arrayish "^0.3.1"
|
||||
|
||||
singleton-manager@1.2.1:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/singleton-manager/-/singleton-manager-1.2.1.tgz#9ad080707f0fe1be849e14994d3e7a2308d56f83"
|
||||
integrity sha512-n+G7rHlANmJsi6Y6K7wV3wluO0oT1veSIL/vazbnG+nXfc4fB855JwsBXHccm1pCi7vNSh63PRGzoIfCBo3b+g==
|
||||
singleton-manager@1.4.1:
|
||||
version "1.4.1"
|
||||
resolved "https://registry.yarnpkg.com/singleton-manager/-/singleton-manager-1.4.1.tgz#0a9cd1db2b26e5cbc4ecdc20d5a16f284b36aabb"
|
||||
integrity sha512-HOvKT/WcHvl2cLYGqmO6MaC2J4wAA82LntGwtLn6avnTq15UDLCnSRVXedmglVooLbQGVsQJ+dQz2sKz+2GUZA==
|
||||
|
||||
sinon-chai@^3.3.0:
|
||||
version "3.5.0"
|
||||
@@ -8170,10 +8192,10 @@ symbol-observable@1.0.1:
|
||||
resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.0.1.tgz#8340fc4702c3122df5d22288f88283f513d3fdd4"
|
||||
integrity sha1-g0D8RwLDEi310iKI+IKD9RPT/dQ=
|
||||
|
||||
systemjs@^6.7.1:
|
||||
version "6.8.2"
|
||||
resolved "https://registry.yarnpkg.com/systemjs/-/systemjs-6.8.2.tgz#6200ce215ee5eb8d6c2815b9470c52015cb3c867"
|
||||
integrity sha512-YknH4S+Xq7Rlwdnvyj4QKHWm5YQGPJnnkVXFQLC/Wl/O21nZ+NrV9IjwUQQ0Pl0Jh0Wgf91IeGzSHGELsv5kkA==
|
||||
systemjs@^6.8.1:
|
||||
version "6.8.3"
|
||||
resolved "https://registry.yarnpkg.com/systemjs/-/systemjs-6.8.3.tgz#67e27f49242e9d81c2b652b204ae54e8bfcc75a3"
|
||||
integrity sha512-UcTY+FEA1B7e+bpJk1TI+a9Na6LG7wFEqW7ED16cLqLuQfI/9Ri0rsXm3tKlIgNoHyLHZycjdAOijzNbzelgwA==
|
||||
|
||||
table-layout@^1.0.1:
|
||||
version "1.0.1"
|
||||
@@ -8243,7 +8265,7 @@ term-size@^2.1.0:
|
||||
resolved "https://registry.yarnpkg.com/term-size/-/term-size-2.2.1.tgz#2a6a54840432c2fb6320fea0f415531e90189f54"
|
||||
integrity sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==
|
||||
|
||||
terser@^5.0.0, terser@^5.3.8:
|
||||
terser@^5.0.0:
|
||||
version "5.5.1"
|
||||
resolved "https://registry.yarnpkg.com/terser/-/terser-5.5.1.tgz#540caa25139d6f496fdea056e414284886fb2289"
|
||||
integrity sha512-6VGWZNVP2KTUcltUQJ25TtNjx/XgdDsBDKGt8nN0MpydU36LmbPPcMBd2kmtZNNGVVDLg44k7GKeHHj+4zPIBQ==
|
||||
@@ -8252,6 +8274,15 @@ terser@^5.0.0, terser@^5.3.8:
|
||||
source-map "~0.7.2"
|
||||
source-map-support "~0.5.19"
|
||||
|
||||
terser@^5.5.1:
|
||||
version "5.6.1"
|
||||
resolved "https://registry.yarnpkg.com/terser/-/terser-5.6.1.tgz#a48eeac5300c0a09b36854bf90d9c26fb201973c"
|
||||
integrity sha512-yv9YLFQQ+3ZqgWCUk+pvNJwgUTdlIxUk1WTN+RnaFJe2L7ipG2csPT0ra2XRm7Cs8cxN7QXmK1rFzEwYEQkzXw==
|
||||
dependencies:
|
||||
commander "^2.20.0"
|
||||
source-map "~0.7.2"
|
||||
source-map-support "~0.5.19"
|
||||
|
||||
text-table@^0.2.0:
|
||||
version "0.2.0"
|
||||
resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
|
||||
@@ -8761,10 +8792,10 @@ webidl-conversions@^6.1.0:
|
||||
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-6.1.0.tgz#9111b4d7ea80acd40f5270d666621afa78b69514"
|
||||
integrity sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==
|
||||
|
||||
whatwg-fetch@^3.0.0:
|
||||
version "3.5.0"
|
||||
resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.5.0.tgz#605a2cd0a7146e5db141e29d1c62ab84c0c4c868"
|
||||
integrity sha512-jXkLtsR42xhXg7akoDKvKWE40eJeI+2KZqcp2h3NsOrRnDvtWX36KcKl30dy+hxECivdk2BVUHVNrPtoMBUx6A==
|
||||
whatwg-fetch@^3.5.0:
|
||||
version "3.6.2"
|
||||
resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz#dced24f37f2624ed0281725d51d0e2e3fe677f8c"
|
||||
integrity sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA==
|
||||
|
||||
whatwg-url@^8.4.0:
|
||||
version "8.4.0"
|
||||
|
||||
Reference in New Issue
Block a user