lookbook 2.0.0.beta.4 → 2.0.0.beta.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/components/lookbook/button/component.js +2 -2
- data/app/components/lookbook/copy_button/component.js +1 -1
- data/app/components/lookbook/display_options/field/component.js +1 -1
- data/app/components/lookbook/header/component.css +12 -0
- data/app/components/lookbook/header/component.html.erb +13 -9
- data/app/components/lookbook/header/component.rb +4 -2
- data/app/components/lookbook/icon/component.css +8 -0
- data/app/components/lookbook/icon/component.html.erb +2 -4
- data/app/components/lookbook/icon/component.rb +16 -4
- data/app/components/lookbook/nav/directory/component.html.erb +4 -4
- data/app/components/lookbook/nav/entity/component.html.erb +4 -4
- data/app/components/lookbook/tabs/component.js +1 -1
- data/app/views/layouts/lookbook/application.html.erb +40 -42
- data/app/views/layouts/lookbook/skeleton.html.erb +3 -9
- data/app/views/lookbook/inspector/panels/_preview.html.erb +1 -0
- data/app/views/lookbook/inspector/show.html.erb +10 -2
- data/config/app.yml +2 -1
- data/lib/lookbook/engine.rb +20 -18
- data/lib/lookbook/entities/concerns/navigable_entity.rb +6 -1
- data/lib/lookbook/entities/preview_entity.rb +24 -4
- data/lib/lookbook/entities/scenario_group_entity.rb +5 -0
- data/lib/lookbook/preview.rb +4 -0
- data/lib/lookbook/services/urls/data_uri_encoder.rb +14 -0
- data/lib/lookbook/services/urls/file_data_uri_encoder.rb +24 -0
- data/lib/lookbook/stores/config_store.rb +46 -1
- data/lib/lookbook/stores/hook_store.rb +0 -10
- data/lib/lookbook/stores/input_store.rb +7 -1
- data/lib/lookbook/stores/panel_store.rb +4 -1
- data/lib/lookbook/stores/tag_store.rb +6 -5
- data/lib/lookbook/version.rb +1 -1
- data/lib/lookbook.rb +3 -3
- data/public/lookbook-assets/css/lookbook.css +125 -6
- data/public/lookbook-assets/css/lookbook.css.map +1 -1
- data/public/lookbook-assets/css/themes/blue.css.map +1 -1
- data/public/lookbook-assets/css/themes/green.css.map +1 -1
- data/public/lookbook-assets/css/themes/indigo.css.map +1 -1
- data/public/lookbook-assets/css/themes/rose.css.map +1 -1
- data/public/lookbook-assets/css/themes/zinc.css.map +1 -1
- data/public/lookbook-assets/js/iframe.js +2 -1
- data/public/lookbook-assets/js/iframe.js.map +1 -1
- data/public/lookbook-assets/js/index.js +322 -350
- data/public/lookbook-assets/js/index.js.map +1 -1
- data/public/lookbook-assets/js/lookbook-core.js +21 -21
- data/public/lookbook-assets/js/lookbook.js +30 -29
- metadata +10 -43
- data/app/assets/lookbook/css/fonts.css +0 -33
- data/app/assets/lookbook/css/lookbook.css +0 -145
- data/app/assets/lookbook/css/themes/blue.css +0 -76
- data/app/assets/lookbook/css/themes/green.css +0 -76
- data/app/assets/lookbook/css/themes/indigo.css +0 -76
- data/app/assets/lookbook/css/themes/rose.css +0 -76
- data/app/assets/lookbook/css/themes/zinc.css +0 -76
- data/app/assets/lookbook/css/tooltip.css +0 -53
- data/app/assets/lookbook/img/lucide-sprite.svg +0 -4960
- data/app/assets/lookbook/js/app.js +0 -112
- data/app/assets/lookbook/js/components/clipboard.js +0 -47
- data/app/assets/lookbook/js/components/params_input.js +0 -23
- data/app/assets/lookbook/js/components/tooltip.js +0 -30
- data/app/assets/lookbook/js/config.js +0 -24
- data/app/assets/lookbook/js/helpers/build.js +0 -22
- data/app/assets/lookbook/js/helpers/dom.js +0 -42
- data/app/assets/lookbook/js/helpers/layout.js +0 -21
- data/app/assets/lookbook/js/helpers/request.js +0 -16
- data/app/assets/lookbook/js/helpers/string.js +0 -26
- data/app/assets/lookbook/js/iframe.js +0 -1
- data/app/assets/lookbook/js/index.js +0 -61
- data/app/assets/lookbook/js/lib/lookbook.js +0 -123
- data/app/assets/lookbook/js/lib/socket.js +0 -28
- data/app/assets/lookbook/js/lib/tippy.js +0 -9
- data/app/assets/lookbook/js/lookbook-core.js +0 -1
- data/app/assets/lookbook/js/lookbook.js +0 -2
- data/app/assets/lookbook/js/plugins/logger.js +0 -39
- data/app/assets/lookbook/js/stores/filter.js +0 -11
- data/app/assets/lookbook/js/stores/inspector.js +0 -31
- data/app/assets/lookbook/js/stores/layout.js +0 -111
- data/app/assets/lookbook/js/stores/nav.js +0 -22
- data/app/assets/lookbook/js/stores/pages.js +0 -7
- data/app/assets/lookbook/js/stores/settings.js +0 -7
- data/app/assets/lookbook/js/stores/workbench.js +0 -29
- data/app/components/lookbook/icon/component.js +0 -5
- data/config/hooks.yml +0 -4
- /data/{app/assets/lookbook/fonts/Inter-italic.var.woff2 → public/lookbook-assets/Inter-italic.var.53a0de5f.woff2} +0 -0
- /data/{app/assets/lookbook/fonts/Inter-roman.var.woff2 → public/lookbook-assets/Inter-roman.var.d4f9805a.woff2} +0 -0
- /data/{app/assets/lookbook/fonts/SourceCodeVariable-Italic.ttf.woff2 → public/lookbook-assets/SourceCodeVariable-Italic.ttf.a93fa22f.woff2} +0 -0
- /data/{app/assets/lookbook/fonts/SourceCodeVariable-Roman.ttf.woff2 → public/lookbook-assets/SourceCodeVariable-Roman.ttf.f1c8fcce.woff2} +0 -0
@@ -1,112 +0,0 @@
|
|
1
|
-
import createSocket from "./lib/socket";
|
2
|
-
import { morph } from "./helpers/dom";
|
3
|
-
import { fetchHTML } from "./helpers/request";
|
4
|
-
import { isExternalLink } from "./helpers/dom";
|
5
|
-
|
6
|
-
export default function app() {
|
7
|
-
return {
|
8
|
-
_requestsInProgress: 0,
|
9
|
-
|
10
|
-
version: Alpine.$persist("").as("lookbook-version"),
|
11
|
-
|
12
|
-
location: window.location,
|
13
|
-
|
14
|
-
get sidebarHidden() {
|
15
|
-
return this.$store.layout.sidebar.hidden;
|
16
|
-
},
|
17
|
-
|
18
|
-
get loading() {
|
19
|
-
return this._requestsInProgress > 0;
|
20
|
-
},
|
21
|
-
|
22
|
-
init() {
|
23
|
-
if (window.SOCKET_PATH) {
|
24
|
-
this.debug(`Lookbook socket created`);
|
25
|
-
const socket = createSocket(window.SOCKET_PATH);
|
26
|
-
socket.addListener("Lookbook::ReloadChannel", () => this.updateDOM());
|
27
|
-
}
|
28
|
-
},
|
29
|
-
|
30
|
-
navigateTo(path) {
|
31
|
-
this.debug(`Navigating to ${path}`);
|
32
|
-
history.pushState({}, null, path);
|
33
|
-
this.$dispatch("popstate");
|
34
|
-
},
|
35
|
-
|
36
|
-
async handleNavigation() {
|
37
|
-
this.debug("Navigating to ", window.location.pathname);
|
38
|
-
this.$dispatch("navigation:start");
|
39
|
-
this.location = window.location;
|
40
|
-
await this.updateDOM();
|
41
|
-
this.$dispatch("navigation:complete");
|
42
|
-
},
|
43
|
-
|
44
|
-
hijax(evt) {
|
45
|
-
const link = evt.target.closest("a[href]");
|
46
|
-
if (link) {
|
47
|
-
const external = isExternalLink(link);
|
48
|
-
const embedded = this.isEmbedded();
|
49
|
-
|
50
|
-
if (embedded && (!link.hasAttribute("target") || external)) {
|
51
|
-
evt.preventDefault();
|
52
|
-
window.top.location = link.href;
|
53
|
-
return;
|
54
|
-
} else if (!embedded && !external && !link.hasAttribute("target")) {
|
55
|
-
evt.preventDefault();
|
56
|
-
this.navigateTo(link.href);
|
57
|
-
return;
|
58
|
-
}
|
59
|
-
}
|
60
|
-
},
|
61
|
-
|
62
|
-
async updateDOM() {
|
63
|
-
this.debug("Starting DOM update");
|
64
|
-
this.$dispatch("dom:update-start");
|
65
|
-
this.requestStart();
|
66
|
-
try {
|
67
|
-
const { fragment, title } = await fetchHTML(
|
68
|
-
window.location,
|
69
|
-
`#${this.$root.id}`
|
70
|
-
);
|
71
|
-
morph(this.$root, fragment);
|
72
|
-
document.title = title;
|
73
|
-
this.requestEnd();
|
74
|
-
this.$dispatch("dom:update-complete");
|
75
|
-
this.debug("DOM update complete");
|
76
|
-
} catch (err) {
|
77
|
-
this.error(err);
|
78
|
-
window.location.reload();
|
79
|
-
}
|
80
|
-
},
|
81
|
-
|
82
|
-
toggleSidebar() {
|
83
|
-
this.$store.layout.sidebar.hidden = !this.$store.layout.sidebar.hidden;
|
84
|
-
},
|
85
|
-
|
86
|
-
closeMobileSidebar() {
|
87
|
-
if (this.$store.layout.mobile && !this.sidebarHidden) {
|
88
|
-
this.toggleSidebar();
|
89
|
-
}
|
90
|
-
},
|
91
|
-
|
92
|
-
requestStart() {
|
93
|
-
this._requestsInProgress += 1;
|
94
|
-
},
|
95
|
-
|
96
|
-
requestEnd() {
|
97
|
-
if (this._requestsInProgress > 0) {
|
98
|
-
this._requestsInProgress -= 1;
|
99
|
-
}
|
100
|
-
},
|
101
|
-
|
102
|
-
isEmbedded() {
|
103
|
-
try {
|
104
|
-
return window.self !== window.top;
|
105
|
-
} catch (e) {
|
106
|
-
return true;
|
107
|
-
}
|
108
|
-
},
|
109
|
-
|
110
|
-
...Alpine.$log,
|
111
|
-
};
|
112
|
-
}
|
@@ -1,47 +0,0 @@
|
|
1
|
-
import { decodeEntities } from "../helpers/string";
|
2
|
-
|
3
|
-
function initClipboard(context = {}) {
|
4
|
-
let copyTimeout = null;
|
5
|
-
|
6
|
-
return Object.assign(context, {
|
7
|
-
copied: false,
|
8
|
-
|
9
|
-
async copyToClipboard(target = null) {
|
10
|
-
let targetEl;
|
11
|
-
if (this.$refs.copyTarget) {
|
12
|
-
targetEl = this.$refs.copyTarget;
|
13
|
-
} else if (typeof target === "string") {
|
14
|
-
targetEl = document.querySelector(target);
|
15
|
-
}
|
16
|
-
|
17
|
-
if (!targetEl) {
|
18
|
-
this.warn("Could not find copy target");
|
19
|
-
return false;
|
20
|
-
}
|
21
|
-
|
22
|
-
const content = decodeEntities(targetEl.innerHTML.trim());
|
23
|
-
|
24
|
-
await window.navigator.clipboard.writeText(content);
|
25
|
-
this.copied = true;
|
26
|
-
|
27
|
-
if (copyTimeout) {
|
28
|
-
clearTimeout(copyTimeout);
|
29
|
-
}
|
30
|
-
|
31
|
-
copyTimeout = setTimeout(() => {
|
32
|
-
this.copied = false;
|
33
|
-
this.onCopyComplete();
|
34
|
-
}, 1000);
|
35
|
-
|
36
|
-
return content;
|
37
|
-
},
|
38
|
-
|
39
|
-
onCopyComplete() {},
|
40
|
-
});
|
41
|
-
}
|
42
|
-
|
43
|
-
export default function clipboardComponent() {
|
44
|
-
return initClipboard({});
|
45
|
-
}
|
46
|
-
|
47
|
-
export { initClipboard };
|
@@ -1,23 +0,0 @@
|
|
1
|
-
export default function paramsInputComponent({ name, value }) {
|
2
|
-
return {
|
3
|
-
name,
|
4
|
-
value,
|
5
|
-
|
6
|
-
init() {
|
7
|
-
this.$watch("value", () => this.update());
|
8
|
-
},
|
9
|
-
|
10
|
-
update() {
|
11
|
-
if (this.validate()) {
|
12
|
-
const searchParams = new URLSearchParams(window.location.search);
|
13
|
-
searchParams.set(this.name, this.value);
|
14
|
-
const path = location.href.replace(location.search, "");
|
15
|
-
this.navigateTo(`${path}?${searchParams.toString()}`);
|
16
|
-
}
|
17
|
-
},
|
18
|
-
|
19
|
-
validate() {
|
20
|
-
return this.$root.reportValidity ? this.$root.reportValidity() : true;
|
21
|
-
},
|
22
|
-
};
|
23
|
-
}
|
@@ -1,30 +0,0 @@
|
|
1
|
-
import tippy from "../lib/tippy";
|
2
|
-
|
3
|
-
function tooltipCreator({ target }) {
|
4
|
-
const content =
|
5
|
-
this.$el.dataset.tooltipText ||
|
6
|
-
(this.$refs.tooltip ? this.$refs.tooltip.innerHTML : null);
|
7
|
-
if (content) {
|
8
|
-
return tippy(target || this.$refs.tooltipTarget || this.$el, {
|
9
|
-
delay: [200, 0],
|
10
|
-
content,
|
11
|
-
theme: "tooltip",
|
12
|
-
triggerTarget: this.$el,
|
13
|
-
onShow: () => this.$store.settings.showTooltips,
|
14
|
-
});
|
15
|
-
}
|
16
|
-
}
|
17
|
-
|
18
|
-
function initTooltip(context, opts) {
|
19
|
-
return tooltipCreator.bind(context)(opts || {});
|
20
|
-
}
|
21
|
-
|
22
|
-
export default function tooltipComponent() {
|
23
|
-
return {
|
24
|
-
init() {
|
25
|
-
initTooltip(this);
|
26
|
-
},
|
27
|
-
};
|
28
|
-
}
|
29
|
-
|
30
|
-
export { initTooltip };
|
@@ -1,24 +0,0 @@
|
|
1
|
-
export default {
|
2
|
-
desktopWidth: 768,
|
3
|
-
wideDesktopWidth: 1200,
|
4
|
-
sidebar: {
|
5
|
-
defaultWidth: 280,
|
6
|
-
minWidth: 200,
|
7
|
-
minSectionHeight: 200,
|
8
|
-
},
|
9
|
-
main: {
|
10
|
-
minWidth: 200,
|
11
|
-
},
|
12
|
-
inspector: {
|
13
|
-
drawer: {
|
14
|
-
defaultHeight: 300,
|
15
|
-
defaultWidth: 500,
|
16
|
-
minWidth: 350,
|
17
|
-
minHeight: 200,
|
18
|
-
},
|
19
|
-
preview: {
|
20
|
-
minHeight: 200,
|
21
|
-
minWidth: 200,
|
22
|
-
},
|
23
|
-
},
|
24
|
-
};
|
@@ -1,22 +0,0 @@
|
|
1
|
-
function getComponents(importObject, path = []) {
|
2
|
-
let components = {};
|
3
|
-
Object.keys(importObject).forEach((key) => {
|
4
|
-
if (key === "default") {
|
5
|
-
components[toCamel(path.join("_"))] = importObject[key];
|
6
|
-
} else {
|
7
|
-
components = {
|
8
|
-
...components,
|
9
|
-
...getComponents(importObject[key], [...path, key]),
|
10
|
-
};
|
11
|
-
}
|
12
|
-
});
|
13
|
-
return components;
|
14
|
-
}
|
15
|
-
|
16
|
-
function toCamel(s) {
|
17
|
-
return s.replace(/([-_][a-z])/gi, ($1) => {
|
18
|
-
return $1.toUpperCase().replace("-", "").replace("_", "");
|
19
|
-
});
|
20
|
-
}
|
21
|
-
|
22
|
-
export { getComponents };
|
@@ -1,42 +0,0 @@
|
|
1
|
-
function morph(from, to) {
|
2
|
-
Alpine.morph(from, to, {
|
3
|
-
key(el) {
|
4
|
-
return el.getAttribute("key") ? el.getAttribute("key") : el.id;
|
5
|
-
},
|
6
|
-
lookahead: true,
|
7
|
-
updating(el, toEl, childrenOnly, skip) {
|
8
|
-
if (!el.getAttribute) return;
|
9
|
-
if (el.getAttribute("data-morph-strategy") === "replace") {
|
10
|
-
el.innerHTML = toEl.innerHTML;
|
11
|
-
return skip();
|
12
|
-
} else if (el.getAttribute("data-morph-strategy") === "skip") {
|
13
|
-
return skip();
|
14
|
-
}
|
15
|
-
},
|
16
|
-
});
|
17
|
-
}
|
18
|
-
|
19
|
-
function getElementSize(el, opts = {}) {
|
20
|
-
const style = window.getComputedStyle(el, null);
|
21
|
-
return {
|
22
|
-
width: opts.includeMargins
|
23
|
-
? el.offsetWidth +
|
24
|
-
parseInt(style.getPropertyValue("margin-left")) +
|
25
|
-
parseInt(style.getPropertyValue("margin-right"))
|
26
|
-
: el.offsetWidth,
|
27
|
-
height: opts.includeMargins
|
28
|
-
? el.offsetHeight +
|
29
|
-
parseInt(style.getPropertyValue("margin-top")) +
|
30
|
-
parseInt(style.getPropertyValue("margin-bottom"))
|
31
|
-
: el.offsetHeight,
|
32
|
-
};
|
33
|
-
}
|
34
|
-
|
35
|
-
function isExternalLink(link) {
|
36
|
-
if (link.href) {
|
37
|
-
return link.host !== window.location.host;
|
38
|
-
}
|
39
|
-
return false;
|
40
|
-
}
|
41
|
-
|
42
|
-
export { morph, getElementSize, isExternalLink };
|
@@ -1,21 +0,0 @@
|
|
1
|
-
function addMediaQueryListener(condition, callback) {
|
2
|
-
const mediaQueryList = window.matchMedia(condition);
|
3
|
-
const handleChange = (mql) => callback(mql.matches);
|
4
|
-
handleChange(mediaQueryList);
|
5
|
-
mediaQueryList.addEventListener("change", (mql) => handleChange(mql));
|
6
|
-
return mediaQueryList;
|
7
|
-
}
|
8
|
-
|
9
|
-
function observeSize(element, callback = () => {}) {
|
10
|
-
const observer = new ResizeObserver((entries) => {
|
11
|
-
const rect = entries[0].target.getBoundingClientRect();
|
12
|
-
callback({
|
13
|
-
width: Math.round(rect.width),
|
14
|
-
height: Math.round(rect.height),
|
15
|
-
});
|
16
|
-
});
|
17
|
-
observer.observe(element);
|
18
|
-
return observer;
|
19
|
-
}
|
20
|
-
|
21
|
-
export { addMediaQueryListener, observeSize };
|
@@ -1,16 +0,0 @@
|
|
1
|
-
async function fetchHTML(url, selector) {
|
2
|
-
const response = await fetch(url || window.document.location);
|
3
|
-
if (response.ok) {
|
4
|
-
const html = await response.text();
|
5
|
-
const doc = new DOMParser().parseFromString(html, "text/html");
|
6
|
-
return {
|
7
|
-
fragment: selector ? doc.querySelector(selector).outerHTML : null,
|
8
|
-
title: doc.title,
|
9
|
-
doc,
|
10
|
-
};
|
11
|
-
} else {
|
12
|
-
throw new Error(`Error fetching HTML from ${url}`);
|
13
|
-
}
|
14
|
-
}
|
15
|
-
|
16
|
-
export { fetchHTML };
|
@@ -1,26 +0,0 @@
|
|
1
|
-
function decodeEntities(content) {
|
2
|
-
var txt = document.createElement("textarea");
|
3
|
-
txt.innerHTML = content;
|
4
|
-
return txt.value;
|
5
|
-
}
|
6
|
-
|
7
|
-
function prefixString(string, prefix = null) {
|
8
|
-
return prefix ? `${prefix}-${string}` : string;
|
9
|
-
}
|
10
|
-
|
11
|
-
function parseSearchParamValue(value) {
|
12
|
-
const json = decodeURIComponent(value);
|
13
|
-
return JSON.parse(json);
|
14
|
-
}
|
15
|
-
|
16
|
-
function buildSearchParamValue(data) {
|
17
|
-
const str = JSON.stringify(data);
|
18
|
-
return encodeURIComponent(str);
|
19
|
-
}
|
20
|
-
|
21
|
-
export {
|
22
|
-
prefixString,
|
23
|
-
decodeEntities,
|
24
|
-
parseSearchParamValue,
|
25
|
-
buildSearchParamValue,
|
26
|
-
};
|
@@ -1 +0,0 @@
|
|
1
|
-
import "iframe-resizer/js/iframeResizer.contentWindow";
|
@@ -1,61 +0,0 @@
|
|
1
|
-
import Alpine from "alpinejs";
|
2
|
-
|
3
|
-
import Morph from "@alpinejs/morph";
|
4
|
-
import Persist from "@alpinejs/persist";
|
5
|
-
import Collapse from "@alpinejs/morph";
|
6
|
-
import Tooltip from "@ryangjchandler/alpine-tooltip";
|
7
|
-
|
8
|
-
import Logger, { log } from "./plugins/logger";
|
9
|
-
|
10
|
-
import initLayoutStore from "./stores/layout";
|
11
|
-
import initNavStore from "./stores/nav";
|
12
|
-
import initInspectorStore from "./stores/inspector";
|
13
|
-
import initPagesStore from "./stores/pages";
|
14
|
-
import initSettingsStore from "./stores/settings";
|
15
|
-
import initWorkbenchStore from "./stores/workbench";
|
16
|
-
|
17
|
-
import app from "./app";
|
18
|
-
|
19
|
-
// Note: A ParcelJS issue prevents loading all depths of component JS files in one glob,
|
20
|
-
// so need to split it up. Path aliases also do not work with the glob imports.
|
21
|
-
import { getComponents } from "./helpers/build";
|
22
|
-
import * as components from "../../../components/lookbook/*/*component.js";
|
23
|
-
import * as subComponents from "../../../components/lookbook/*/*/component.js";
|
24
|
-
import * as jsComponents from "./components/*.js";
|
25
|
-
|
26
|
-
// Plugins
|
27
|
-
|
28
|
-
Alpine.plugin(Morph);
|
29
|
-
Alpine.plugin(Persist);
|
30
|
-
Alpine.plugin(Collapse);
|
31
|
-
Alpine.plugin(Tooltip);
|
32
|
-
Alpine.plugin(Logger);
|
33
|
-
|
34
|
-
// Stores
|
35
|
-
const prefix = window.APP_NAME;
|
36
|
-
Alpine.store("layout", initLayoutStore(Alpine, { prefix }));
|
37
|
-
Alpine.store("nav", initNavStore(Alpine, { prefix }));
|
38
|
-
Alpine.store("inspector", initInspectorStore(Alpine, { prefix }));
|
39
|
-
Alpine.store("pages", initPagesStore(Alpine, { prefix }));
|
40
|
-
Alpine.store("settings", initSettingsStore(Alpine, { prefix }));
|
41
|
-
|
42
|
-
if (process.env.NODE_ENV !== "production") {
|
43
|
-
Alpine.store("workbench", initWorkbenchStore(Alpine, { prefix }));
|
44
|
-
}
|
45
|
-
|
46
|
-
// Components
|
47
|
-
|
48
|
-
Alpine.data("app", app);
|
49
|
-
|
50
|
-
[components, subComponents, jsComponents].forEach((scripts) => {
|
51
|
-
const components = getComponents(scripts);
|
52
|
-
Object.keys(components).forEach((name) => {
|
53
|
-
Alpine.data(`${name}Component`, components[name]);
|
54
|
-
});
|
55
|
-
});
|
56
|
-
|
57
|
-
// Init
|
58
|
-
|
59
|
-
window.log = log;
|
60
|
-
window.Alpine = Alpine;
|
61
|
-
Alpine.start();
|
@@ -1,123 +0,0 @@
|
|
1
|
-
window.Lookbook = window.Lookbook || {};
|
2
|
-
window.Lookbook.initEmbeds = initEmbeds;
|
3
|
-
|
4
|
-
const embedUrlPrefix = "embed";
|
5
|
-
const whiteListedAttributes = [
|
6
|
-
"preview",
|
7
|
-
"scenario",
|
8
|
-
"panels",
|
9
|
-
"actions",
|
10
|
-
"param-*",
|
11
|
-
];
|
12
|
-
|
13
|
-
function initEmbeds(root = document) {
|
14
|
-
if (typeof window.iFrameResize !== "function") {
|
15
|
-
console.error(
|
16
|
-
"Lookbook embeds require the 'iframe-resizer' library to be available. Skipping embed instantiation."
|
17
|
-
);
|
18
|
-
return;
|
19
|
-
}
|
20
|
-
|
21
|
-
if (typeof root === "string") {
|
22
|
-
root = document.querySelector(root);
|
23
|
-
}
|
24
|
-
|
25
|
-
if (!root) {
|
26
|
-
return console.error(
|
27
|
-
"Could not initialize Lookbook embeds. Root node not found."
|
28
|
-
);
|
29
|
-
}
|
30
|
-
|
31
|
-
const embeds = Array.from(root.querySelectorAll("lookbook-embed"));
|
32
|
-
|
33
|
-
embeds.forEach((embed) => {
|
34
|
-
const attrs = Array.from(embed.attributes);
|
35
|
-
const wrapper = createWrapper();
|
36
|
-
const iframe = createIframe(attrs);
|
37
|
-
|
38
|
-
wrapper.appendChild(iframe);
|
39
|
-
embed.replaceWith(wrapper);
|
40
|
-
});
|
41
|
-
|
42
|
-
window.iFrameResize({ checkOrigin: false }, "[data-lookbook-embed-iframe]");
|
43
|
-
}
|
44
|
-
|
45
|
-
function createWrapper() {
|
46
|
-
const wrapper = document.createElement("div");
|
47
|
-
|
48
|
-
wrapper.setAttribute("data-lookbook-embed", "");
|
49
|
-
wrapper.classList.add("lookbook-embed");
|
50
|
-
|
51
|
-
return wrapper;
|
52
|
-
}
|
53
|
-
|
54
|
-
function createIframe(attrs) {
|
55
|
-
const src = buildSrc(attrs);
|
56
|
-
const id = attrValue(attrs, "id");
|
57
|
-
const styles = attrValue(attrs, "style");
|
58
|
-
const classes = attrValue(attrs, "class", "")
|
59
|
-
.split(" ")
|
60
|
-
.map((c) => c.trim())
|
61
|
-
.filter((c) => c.length);
|
62
|
-
|
63
|
-
const iframe = document.createElement("iframe");
|
64
|
-
iframe.src = src;
|
65
|
-
if (id) iframe.id = id;
|
66
|
-
|
67
|
-
iframe.setAttribute("frameborder", 0);
|
68
|
-
iframe.setAttribute("data-lookbook-embed-iframe", "");
|
69
|
-
|
70
|
-
if (classes.length) iframe.classList.add(...classes);
|
71
|
-
if (styles) iframe.style.cssText = styles;
|
72
|
-
|
73
|
-
iframe.style.width = "100%";
|
74
|
-
iframe.style.transition = "height 0.3s";
|
75
|
-
|
76
|
-
return iframe;
|
77
|
-
}
|
78
|
-
|
79
|
-
function buildSrc(attrs) {
|
80
|
-
const appPath = attrValue(attrs, "app") || guessBasePath();
|
81
|
-
const props = {};
|
82
|
-
|
83
|
-
permittedAttrs(attrs).forEach(({ name, value }) => {
|
84
|
-
name = name.replace("-", "_").toLowerCase();
|
85
|
-
props[name] = value;
|
86
|
-
});
|
87
|
-
|
88
|
-
return encodeURI(
|
89
|
-
[appPath, embedUrlPrefix].join("/") + `?props=${JSON.stringify(props)}`
|
90
|
-
);
|
91
|
-
}
|
92
|
-
|
93
|
-
function attrValue(attrs, name, fallback = null) {
|
94
|
-
const attr = attrs.find((attr) => attr.name === name);
|
95
|
-
return attr ? attr.value : fallback;
|
96
|
-
}
|
97
|
-
|
98
|
-
function permittedAttrs(attrs) {
|
99
|
-
return attrs.filter((attr) => {
|
100
|
-
return whiteListedAttributes.find((key) => {
|
101
|
-
const name = attr.name;
|
102
|
-
return (
|
103
|
-
key === name ||
|
104
|
-
(key.includes("*") && name.startsWith(key.replace("*", "")))
|
105
|
-
);
|
106
|
-
});
|
107
|
-
});
|
108
|
-
}
|
109
|
-
|
110
|
-
function guessBasePath() {
|
111
|
-
const script =
|
112
|
-
document.currentScript ||
|
113
|
-
document.querySelector('script[src*="lookbook.js"]');
|
114
|
-
const scriptSrc = script.src;
|
115
|
-
|
116
|
-
if (scriptSrc && scriptSrc.includes("lookbook-assets")) {
|
117
|
-
return scriptSrc.replace("lookbook-assets/js/lookbook.js", "lookbook");
|
118
|
-
}
|
119
|
-
|
120
|
-
return `//${location.host}/lookbook`;
|
121
|
-
}
|
122
|
-
|
123
|
-
document.addEventListener("DOMContentLoaded", () => initEmbeds());
|
@@ -1,28 +0,0 @@
|
|
1
|
-
import { createConsumer } from "@rails/actioncable";
|
2
|
-
import { debounce } from "throttle-debounce";
|
3
|
-
import { log } from "../plugins/logger";
|
4
|
-
|
5
|
-
export default function socket(endpoint) {
|
6
|
-
const uid = (Date.now() + ((Math.random() * 100) | 0)).toString();
|
7
|
-
const consumer = createConsumer(`${endpoint}?uid=${uid}`);
|
8
|
-
return {
|
9
|
-
addListener(channel, callback) {
|
10
|
-
consumer.subscriptions.create(channel, {
|
11
|
-
received: debounce(
|
12
|
-
200,
|
13
|
-
(data) => {
|
14
|
-
log.debug("Lookbook files changed");
|
15
|
-
callback(data);
|
16
|
-
},
|
17
|
-
{ atBegin: true }
|
18
|
-
),
|
19
|
-
connected() {
|
20
|
-
log.info("Lookbook websocket connected");
|
21
|
-
},
|
22
|
-
disconnected() {
|
23
|
-
log.info("Lookbook websocket disconnected");
|
24
|
-
},
|
25
|
-
});
|
26
|
-
},
|
27
|
-
};
|
28
|
-
}
|
@@ -1 +0,0 @@
|
|
1
|
-
import "./lib/lookbook";
|
@@ -1,39 +0,0 @@
|
|
1
|
-
import log from "loglevel";
|
2
|
-
import logPrefix from "loglevel-plugin-prefix";
|
3
|
-
|
4
|
-
logPrefix.reg(log);
|
5
|
-
logPrefix.apply(log, {
|
6
|
-
format: (level) => `${`[${level}]`.padStart(7)} Lookbook:`,
|
7
|
-
});
|
8
|
-
|
9
|
-
let logLevel = process.env.NODE_ENV === "development" ? 2 : 3;
|
10
|
-
if (window.LOG_LEVEL !== undefined) {
|
11
|
-
logLevel = window.LOG_LEVEL;
|
12
|
-
}
|
13
|
-
log.setLevel(logLevel);
|
14
|
-
|
15
|
-
export default function loggerPlugin(Alpine) {
|
16
|
-
Alpine.directive(
|
17
|
-
"log",
|
18
|
-
(el, { modifiers, expression }, { evaluateLater, effect }) => {
|
19
|
-
let logFn =
|
20
|
-
typeof expression === "string"
|
21
|
-
? (callback) => callback(expression)
|
22
|
-
: evaluateLater(expression);
|
23
|
-
effect(() =>
|
24
|
-
logFn((message) => {
|
25
|
-
const level = modifiers[0] || "debug";
|
26
|
-
log[level](message);
|
27
|
-
})
|
28
|
-
);
|
29
|
-
}
|
30
|
-
);
|
31
|
-
|
32
|
-
Alpine.magic("log", () => {
|
33
|
-
return log;
|
34
|
-
});
|
35
|
-
|
36
|
-
Alpine.$log = log;
|
37
|
-
}
|
38
|
-
|
39
|
-
export { log };
|
@@ -1,31 +0,0 @@
|
|
1
|
-
import { prefixString } from "../helpers/string";
|
2
|
-
|
3
|
-
export default function initInspectorStore(Alpine, { prefix }) {
|
4
|
-
return {
|
5
|
-
minVerticalSplitWidth: 800,
|
6
|
-
|
7
|
-
main: {
|
8
|
-
activeTab: Alpine.$persist("").as(
|
9
|
-
prefixString("inspector-main-active-tab", prefix)
|
10
|
-
),
|
11
|
-
width: Alpine.$persist("100%").as(
|
12
|
-
prefixString("inspector-main-width", prefix)
|
13
|
-
),
|
14
|
-
height: Alpine.$persist("100%").as(
|
15
|
-
prefixString("inspector-main-height", prefix)
|
16
|
-
),
|
17
|
-
lastWidth: null,
|
18
|
-
lastHeight: null,
|
19
|
-
resizing: false,
|
20
|
-
},
|
21
|
-
|
22
|
-
drawer: {
|
23
|
-
hidden: Alpine.$persist(false).as(
|
24
|
-
prefixString("inspector-drawer-hidden", prefix)
|
25
|
-
),
|
26
|
-
activeTab: Alpine.$persist("").as(
|
27
|
-
prefixString("inspector-drawer-active-tab", prefix)
|
28
|
-
),
|
29
|
-
},
|
30
|
-
};
|
31
|
-
}
|