Skip to content

Commit eef7b85

Browse files
committed
new responsive embed method
1 parent e9f8382 commit eef7b85

File tree

8 files changed

+681
-103
lines changed

8 files changed

+681
-103
lines changed

package-lock.json

Lines changed: 528 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "import-doc",
3-
"version": "0.0.5",
3+
"version": "1.0.0",
44
"description": "import-doc Element",
55
"main": "dist/index.js",
66
"module": "dist/index.mjs",
@@ -17,11 +17,18 @@
1717
"scripts": {
1818
"build": "stencil build --docs",
1919
"start": "stencil build --dev --watch --serve",
20+
"serve": "stencil build --watch --serve",
2021
"test": "stencil test --spec --e2e",
2122
"test.watch": "stencil test --spec --e2e --watchAll"
2223
},
2324
"devDependencies": {
24-
"@stencil/core": "^1.7.5"
25+
"@rollup/plugin-replace": "^2.3.1",
26+
"@stencil/core": "^1.12.3",
27+
"rollup": "^2.3.4",
28+
"workbox-build": "4.3.1"
2529
},
26-
"license": "MIT"
30+
"license": "MIT",
31+
"dependencies": {
32+
"@juggle/resize-observer": "^3.1.3"
33+
}
2734
}

src/components.d.ts

Lines changed: 27 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -4,49 +4,40 @@
44
* This is an autogenerated file created by the Stencil compiler.
55
* It contains typing information for all components that exist in this project.
66
*/
7-
8-
9-
import { HTMLStencilElement, JSXBase } from '@stencil/core/internal';
10-
11-
7+
import { HTMLStencilElement, JSXBase } from "@stencil/core/internal";
128
export namespace Components {
13-
interface ImportDoc {
14-
'src': string;
15-
}
9+
interface ImportDoc {
10+
"dataId"?: string;
11+
"noFonts"?: boolean;
12+
"src"?: string;
13+
}
1614
}
17-
1815
declare global {
19-
20-
21-
interface HTMLImportDocElement extends Components.ImportDoc, HTMLStencilElement {}
22-
var HTMLImportDocElement: {
23-
prototype: HTMLImportDocElement;
24-
new (): HTMLImportDocElement;
25-
};
26-
interface HTMLElementTagNameMap {
27-
'import-doc': HTMLImportDocElement;
28-
}
16+
interface HTMLImportDocElement extends Components.ImportDoc, HTMLStencilElement {
17+
}
18+
var HTMLImportDocElement: {
19+
prototype: HTMLImportDocElement;
20+
new (): HTMLImportDocElement;
21+
};
22+
interface HTMLElementTagNameMap {
23+
"import-doc": HTMLImportDocElement;
24+
}
2925
}
30-
3126
declare namespace LocalJSX {
32-
interface ImportDoc {
33-
'src'?: string;
34-
}
35-
36-
interface IntrinsicElements {
37-
'import-doc': ImportDoc;
38-
}
27+
interface ImportDoc {
28+
"dataId"?: string;
29+
"noFonts"?: boolean;
30+
"src"?: string;
31+
}
32+
interface IntrinsicElements {
33+
"import-doc": ImportDoc;
34+
}
3935
}
40-
4136
export { LocalJSX as JSX };
42-
43-
4437
declare module "@stencil/core" {
45-
export namespace JSX {
46-
interface IntrinsicElements {
47-
'import-doc': LocalJSX.ImportDoc & JSXBase.HTMLAttributes<HTMLImportDocElement>;
38+
export namespace JSX {
39+
interface IntrinsicElements {
40+
"import-doc": LocalJSX.ImportDoc & JSXBase.HTMLAttributes<HTMLImportDocElement>;
41+
}
4842
}
49-
}
5043
}
51-
52-
Lines changed: 91 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,51 @@
1-
import { Element, Component, State, Listen, Prop, h } from "@stencil/core";
1+
import {
2+
Component,
3+
State,
4+
Element,
5+
Listen,
6+
Prop,
7+
h,
8+
Watch,
9+
Host,
10+
} from "@stencil/core";
11+
import { ResizeObserver as ResizeObserverPolyfill } from "@juggle/resize-observer";
12+
13+
declare global {
14+
interface Window {
15+
ResizeObserver: typeof ResizeObserverPolyfill;
16+
}
17+
}
18+
19+
const ResizeObserver = window.ResizeObserver || ResizeObserverPolyfill;
220

321
@Component({
422
tag: "import-doc",
523
styleUrl: "import-doc.css",
6-
shadow: true
724
})
825
export class ImportDoc {
9-
@Prop() src: string;
10-
@Element() el: HTMLElement;
26+
@Element() element?: HTMLElement;
27+
@Prop() dataId?: string;
28+
@Prop() src?: string;
29+
@Prop() noFonts?: boolean;
30+
31+
container?: HTMLDivElement;
32+
ro?: ResizeObserverPolyfill;
1133

1234
@State() focused: boolean = false;
13-
@State() document: string = "";
35+
@State() loading?: boolean = true;
36+
@State() breakpoints?: { [breakpoint: string]: number };
37+
38+
@Watch("dataId")
39+
async watchHandler(newValue: string, oldValue: string) {
40+
if (newValue !== oldValue) {
41+
this.loading = true;
42+
await this.fetchDocument();
43+
this.loading = false;
44+
}
45+
}
1446

1547
@Listen("focus", { target: "window" })
16-
async handleFocus() {
48+
handleFocus() {
1749
this.focused = true;
1850
}
1951

@@ -22,37 +54,76 @@ export class ImportDoc {
2254
this.focused = false;
2355
}
2456

25-
private async fetchDocument(url: string) {
57+
private async fetchDocument(force: boolean = false) {
2658
try {
59+
const url = this.dataId
60+
? `API_URL/document?id=${this.dataId}${force ? "&force=true" : ""}${
61+
this.noFonts ? "" : "&fonts=true"
62+
}`
63+
: this.src;
64+
if (!url) return;
2765
const response = await fetch(url);
2866
if (!response.ok) {
2967
throw new Error(`Fetch failed: ${response.statusText}`);
3068
}
31-
const text = await response.text();
32-
if (this.src !== url) {
33-
return "";
69+
const data = await response.text();
70+
if (this.container) {
71+
this.container.innerHTML = data;
72+
const data_element = this.container.querySelector("#__IMPORTDOC_DATA");
73+
if (data_element) {
74+
this.breakpoints = JSON.parse(data_element.innerHTML).breakpoints;
75+
}
3476
}
35-
return text;
77+
this.loading = false;
3678
} catch (e) {
3779
console.error(e);
38-
return "";
80+
return;
3981
}
4082
}
4183

42-
async componentDidLoad() {
43-
this.document = await this.fetchDocument(this.src);
84+
componentDidLoad() {
85+
this.ro = new ResizeObserver((entries) => {
86+
entries.forEach((entry) => {
87+
this.container?.style.setProperty(
88+
"--ew",
89+
entry.contentRect.width + "px"
90+
);
91+
if (this.breakpoints)
92+
Object.keys(this.breakpoints).forEach((breakpoint: string) => {
93+
const minWidth = this.breakpoints && this.breakpoints[breakpoint];
94+
if (minWidth && entry.contentRect.width >= minWidth) {
95+
entry.target.classList.add(breakpoint);
96+
} else {
97+
entry.target.classList.remove(breakpoint);
98+
}
99+
});
100+
});
101+
});
102+
this.container && this.ro?.observe(this.container);
103+
return this.fetchDocument();
44104
}
45105

46-
async componentWillUpdate() {
106+
componentDidUnload() {
107+
this.ro?.disconnect();
108+
}
109+
110+
componentWillUpdate() {
47111
if (this.focused) {
48-
this.document = await this.fetchDocument(this.src);
112+
return this.fetchDocument(true);
49113
}
50114
}
51115

52116
render() {
53-
if (!this.document) {
54-
return <slot name="loading" />;
55-
}
56-
return <div innerHTML={this.document}></div>;
117+
return (
118+
<Host>
119+
<div
120+
style={{ display: this.loading ? "none" : "block" }}
121+
ref={(el) => (this.container = el as HTMLDivElement)}
122+
></div>
123+
<div style={{ display: this.loading ? "block" : "none" }}>
124+
<slot name="loading" />
125+
</div>
126+
</Host>
127+
);
57128
}
58129
}

src/components/import-doc/readme.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,11 @@
77

88
## Properties
99

10-
| Property | Attribute | Description | Type | Default |
11-
| -------- | --------- | ----------- | -------- | ----------- |
12-
| `src` | `src` | | `string` | `undefined` |
10+
| Property | Attribute | Description | Type | Default |
11+
| --------- | ---------- | ----------- | ---------------------- | ----------- |
12+
| `dataId` | `data-id` | | `string \| undefined` | `undefined` |
13+
| `noFonts` | `no-fonts` | | `boolean \| undefined` | `undefined` |
14+
| `src` | `src` | | `string \| undefined` | `undefined` |
1315

1416

1517
----------------------------------------------

src/index.html

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,12 @@
77
content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=5.0"
88
/>
99
<title>import-doc</title>
10-
1110
<script type="module" src="/build/import-doc.esm.js"></script>
1211
<script nomodule src="/build/import-doc.js"></script>
1312
</head>
14-
15-
<body>
16-
<import-doc
17-
src="https://api.importdoc.com/document?id=1na9I7436OGoDASupFmk"
18-
>
13+
<body style="max-width: 1000px; margin: auto;">
14+
<import-doc data-id="XJ49NTIJDnu6TcMoTvMd">
1915
<p slot="loading">Loading...</p>
20-
<noscript>
21-
<iframe
22-
src="https://api.importdoc.com/document?id=1na9I7436OGoDASupFmk"
23-
>
24-
</iframe>
25-
</noscript>
2616
</import-doc>
2717
</body>
2818
</html>

stencil.config.ts

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,23 @@
1-
import { Config } from '@stencil/core';
1+
import { Config } from "@stencil/core";
2+
import replace from "@rollup/plugin-replace";
23

34
export const config: Config = {
4-
namespace: 'import-doc',
5-
globalScript: 'src/global/index.ts',
5+
namespace: "import-doc",
66
outputTargets: [
77
{
8-
type: 'dist',
9-
esmLoaderPath: '../loader'
8+
type: "dist",
9+
esmLoaderPath: "../loader",
1010
},
1111
{
12-
type: 'docs-readme'
12+
type: "docs-readme",
1313
},
1414
{
15-
type: 'www',
16-
serviceWorker: null // disable service workers
17-
}
18-
]
15+
type: "www",
16+
serviceWorker: null, // disable service workers
17+
},
18+
],
19+
plugins: [
20+
// @ts-ignore
21+
replace({ API_URL: process.env.API_URL || "https://api.importdoc.com" }),
22+
],
1923
};

tsconfig.json

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,16 @@
44
"allowUnreachableCode": false,
55
"declaration": false,
66
"experimentalDecorators": true,
7-
"lib": [
8-
"dom",
9-
"es2017"
10-
],
7+
"lib": ["dom", "es2017", "dom.iterable"],
118
"moduleResolution": "node",
129
"module": "esnext",
1310
"target": "es2017",
11+
"strict": true,
1412
"noUnusedLocals": true,
1513
"noUnusedParameters": true,
1614
"jsx": "react",
1715
"jsxFactory": "h"
1816
},
19-
"include": [
20-
"src",
21-
"types/jsx.d.ts"
22-
],
23-
"exclude": [
24-
"node_modules"
25-
]
17+
"include": ["src", "types/jsx.d.ts"],
18+
"exclude": ["node_modules"]
2619
}

0 commit comments

Comments
 (0)