lookbook 0.4.5 → 0.5.0.beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +8 -4
- data/app/assets/lookbook/css/app.css +63 -5
- data/app/assets/lookbook/css/tooltip_theme.css +28 -0
- data/app/assets/lookbook/js/app.js +40 -54
- data/app/assets/lookbook/js/components/copy.js +16 -0
- data/app/assets/lookbook/js/components/filter.js +24 -0
- data/app/assets/lookbook/js/components/inspector.js +58 -0
- data/app/assets/lookbook/js/{nav/node.js → components/nav-group.js} +17 -16
- data/app/assets/lookbook/js/components/nav-item.js +27 -0
- data/app/assets/lookbook/js/components/nav.js +35 -0
- data/app/assets/lookbook/js/components/page.js +45 -0
- data/app/assets/lookbook/js/components/param.js +32 -0
- data/app/assets/lookbook/js/components/preview-window.js +107 -0
- data/app/assets/lookbook/js/components/sidebar.js +3 -0
- data/app/assets/lookbook/js/components/sizes.js +16 -0
- data/app/assets/lookbook/js/components/splitter.js +25 -0
- data/app/assets/lookbook/js/components/tabs.js +50 -0
- data/app/assets/lookbook/js/config.js +20 -0
- data/app/assets/lookbook/js/{utils/reloader.js → lib/socket.js} +7 -12
- data/app/assets/lookbook/js/lib/split.js +21 -0
- data/app/assets/lookbook/js/lib/utils.js +3 -0
- data/app/assets/lookbook/js/stores/filter.js +11 -0
- data/app/assets/lookbook/js/stores/inspector.js +24 -0
- data/app/assets/lookbook/js/stores/layout.js +12 -0
- data/app/assets/lookbook/js/stores/nav.js +21 -0
- data/app/assets/lookbook/js/stores/sidebar.js +14 -0
- data/app/controllers/lookbook/app_controller.rb +71 -96
- data/app/helpers/lookbook/application_helper.rb +48 -4
- data/app/views/layouts/lookbook/app.html.erb +58 -0
- data/app/views/layouts/lookbook/preview.html.erb +12 -0
- data/app/views/lookbook/components/_code.html.erb +8 -0
- data/app/views/lookbook/components/_copy.html.erb +14 -0
- data/app/views/lookbook/components/_drawer.html.erb +121 -0
- data/app/views/lookbook/components/_filter.html.erb +15 -0
- data/app/views/lookbook/{shared → components}/_header.html.erb +3 -3
- data/app/views/lookbook/components/_icon.html.erb +5 -0
- data/app/views/lookbook/components/_nav.html.erb +17 -0
- data/app/views/lookbook/components/_nav_collection.html.erb +5 -0
- data/app/views/lookbook/components/_nav_group.html.erb +14 -0
- data/app/views/lookbook/components/_nav_item.html.erb +23 -0
- data/app/views/lookbook/components/_nav_preview.html.erb +11 -0
- data/app/views/lookbook/components/_param.html.erb +24 -0
- data/app/views/lookbook/components/_preview.html.erb +52 -0
- data/app/views/lookbook/{app/error.html.erb → error.html.erb} +0 -0
- data/app/views/lookbook/index.html.erb +9 -0
- data/app/views/lookbook/{workbench/inspector/params → inputs}/_select.html.erb +2 -2
- data/app/views/lookbook/{workbench/inspector/params → inputs}/_text.html.erb +3 -2
- data/app/views/lookbook/inputs/_textarea.html.erb +9 -0
- data/app/views/lookbook/{workbench/inspector/params → inputs}/_toggle.html.erb +5 -5
- data/app/views/lookbook/{app/not_found.html.erb → not_found.html.erb} +2 -4
- data/app/views/lookbook/panels/_notes.html.erb +25 -0
- data/app/views/lookbook/panels/_output.html.erb +18 -0
- data/app/views/lookbook/panels/_params.html.erb +17 -0
- data/app/views/lookbook/panels/_source.html.erb +20 -0
- data/app/views/lookbook/show.html.erb +73 -0
- data/lib/lookbook/code_formatter.rb +20 -0
- data/lib/lookbook/engine.rb +8 -1
- data/lib/lookbook/lang.rb +10 -5
- data/lib/lookbook/preview.rb +1 -1
- data/lib/lookbook/preview_controller.rb +1 -1
- data/lib/lookbook/preview_group.rb +5 -1
- data/lib/lookbook/version.rb +1 -1
- data/lib/lookbook.rb +2 -0
- data/public/lookbook-assets/css/app.css +4 -0
- data/public/lookbook-assets/css/app.css.map +1 -0
- data/public/lookbook-assets/js/app.js +2 -0
- data/public/lookbook-assets/js/app.js.map +1 -0
- metadata +58 -45
- data/app/assets/lookbook/js/nav/leaf.js +0 -20
- data/app/assets/lookbook/js/nav.js +0 -38
- data/app/assets/lookbook/js/page.js +0 -38
- data/app/assets/lookbook/js/utils/clipboard.js +0 -13
- data/app/assets/lookbook/js/utils/morph.js +0 -19
- data/app/assets/lookbook/js/utils/screen.js +0 -44
- data/app/assets/lookbook/js/utils/size_observer.js +0 -16
- data/app/assets/lookbook/js/utils/split.js +0 -26
- data/app/assets/lookbook/js/workbench/inspector.js +0 -11
- data/app/assets/lookbook/js/workbench/param.js +0 -19
- data/app/assets/lookbook/js/workbench/preview.js +0 -39
- data/app/assets/lookbook/js/workbench.js +0 -14
- data/app/views/lookbook/app/index.html.erb +0 -11
- data/app/views/lookbook/app/show.html.erb +0 -1
- data/app/views/lookbook/layouts/app.html.erb +0 -41
- data/app/views/lookbook/nav/_collection.html.erb +0 -5
- data/app/views/lookbook/nav/_leaf.html.erb +0 -22
- data/app/views/lookbook/nav/_node.html.erb +0 -19
- data/app/views/lookbook/nav/_preview.html.erb +0 -11
- data/app/views/lookbook/preview/group.html.erb +0 -8
- data/app/views/lookbook/shared/_clipboard.html.erb +0 -11
- data/app/views/lookbook/shared/_sidebar.html.erb +0 -45
- data/app/views/lookbook/shared/_workbench.html.erb +0 -12
- data/app/views/lookbook/workbench/_header.html.erb +0 -39
- data/app/views/lookbook/workbench/_inspector.html.erb +0 -38
- data/app/views/lookbook/workbench/_preview.html.erb +0 -24
- data/app/views/lookbook/workbench/inspector/_code.html.erb +0 -3
- data/app/views/lookbook/workbench/inspector/_notes.html.erb +0 -24
- data/app/views/lookbook/workbench/inspector/_params.html.erb +0 -28
- data/app/views/lookbook/workbench/inspector/_plain.html.erb +0 -3
- data/app/views/lookbook/workbench/inspector/params/_textarea.html.erb +0 -8
- data/public/lookbook-assets/app.css +0 -2626
- data/public/lookbook-assets/app.js +0 -8718
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 95624cc7d6d6e9389e87c3b13c6f4980f0be8ae2f13ac81757a9ed7acbaf554d
|
|
4
|
+
data.tar.gz: e8e8c6787b96e23fc3d71bc3b47c4a9253ef8a607f8f41c292c52e2ecc99549d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5ac7b680d183349e374b1a2368b2839fa9c9ec8790f53cbf76a97171c0da7375cf6599d2e4936e2fcb1a0dca685aae9d37cfd54672e68ef0e935086af43b60bc
|
|
7
|
+
data.tar.gz: 03bee3f6b73191fc5bcfd5afed389fee54b3ec41ce31827ddedf647dc17f68740db1314f6f4a0c78d7dfe4960851d9cce12e23e6598970b74d8ec428f258db88
|
data/README.md
CHANGED
|
@@ -34,7 +34,9 @@ Lookbook uses [RDoc/Yard-style comment tags](#annotating-preview-files) to exten
|
|
|
34
34
|
|
|
35
35
|
If you want to have a quick play with Lookbook, the easiest way is to [give the demo app](https://github.com/allmarkedup/lookbook-demo) a spin. It's a basic Rails/ViewComponent app with a few test components included to tinker with.
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
**Online demo: https://lookbook-demo-app.herokuapp.com/lookbook**
|
|
38
|
+
|
|
39
|
+
If you'd rather dig in a bit more and run the demo app locally, the [demo repo](https://github.com/allmarkedup/lookbook-demo) contains instructions on how to get it up and running.
|
|
38
40
|
|
|
39
41
|
## Installing
|
|
40
42
|
|
|
@@ -77,7 +79,7 @@ Lookbook parses [Yard-style comment tags](https://rubydoc.info/gems/yard/file/do
|
|
|
77
79
|
|
|
78
80
|
```ruby
|
|
79
81
|
# @label Basic Button
|
|
80
|
-
# @display bg_color #fff
|
|
82
|
+
# @display bg_color "#fff"
|
|
81
83
|
class ButtonComponentPreview < ViewComponent::Preview
|
|
82
84
|
|
|
83
85
|
# Primary button
|
|
@@ -108,7 +110,7 @@ class ButtonComponentPreview < ViewComponent::Preview
|
|
|
108
110
|
# ---------------
|
|
109
111
|
# For light-on-dark screens
|
|
110
112
|
#
|
|
111
|
-
# @display bg_color #000
|
|
113
|
+
# @display bg_color "#000"
|
|
112
114
|
def secondary
|
|
113
115
|
render ButtonComponent.new(style: :inverted) do
|
|
114
116
|
"Click me"
|
|
@@ -186,7 +188,7 @@ end
|
|
|
186
188
|
The `@display` tag lets you pass custom parameters to your preview layout so that the component preview can be customised on a per-example basis.
|
|
187
189
|
|
|
188
190
|
```ruby
|
|
189
|
-
# @display bg_color #eee
|
|
191
|
+
# @display bg_color "#eee"
|
|
190
192
|
class FooComponentPreview < ViewComponent::Preview
|
|
191
193
|
|
|
192
194
|
# @display max_width 500px
|
|
@@ -205,6 +207,8 @@ The `@display` tag can be applied at the preview (class) or at the example (meth
|
|
|
205
207
|
- `<key>` must be a valid Ruby hash key name, without quotes or spaces
|
|
206
208
|
- `<value>` will be parsed using the [Ruby YAML parser](https://yaml.org/YAML_for_ruby.html) to resolve the value
|
|
207
209
|
|
|
210
|
+
> Note: Ruby YAML does not (generally) require quoting of string values. However in some cases it _is_ required due to the presence of [indicator characters](https://yaml.org/YAML_for_ruby.html#indicators_in_strings) (such as `#`, `:` etc) - hence why the hex color code in the example above is surrounded by quotes. It's perfectly ok to quote all string values if you prefer.
|
|
211
|
+
|
|
208
212
|
These display parameters can then be accessed via the `params` hash in your preview layout using `params[:lookbook][:display][<key>]`:
|
|
209
213
|
|
|
210
214
|
```html
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
@import "tailwindcss/components";
|
|
3
3
|
@import "tailwindcss/utilities";
|
|
4
4
|
@import "tippy.js/dist/tippy";
|
|
5
|
+
@import "tippy.js/dist/border";
|
|
5
6
|
@import "code_theme";
|
|
6
7
|
@import "tooltip_theme";
|
|
7
8
|
|
|
@@ -56,16 +57,73 @@
|
|
|
56
57
|
}
|
|
57
58
|
}
|
|
58
59
|
|
|
59
|
-
@layer
|
|
60
|
-
|
|
61
|
-
|
|
60
|
+
@layer components {
|
|
61
|
+
#nav > ul > li > div {
|
|
62
|
+
@apply py-1 border-b border-gray-300;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.nav-toggle {
|
|
66
|
+
@apply flex items-center cursor-pointer pr-3 hover:bg-gray-200 hover:bg-opacity-50;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.nav-label {
|
|
70
|
+
@apply truncate w-full whitespace-nowrap text-left select-none;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
.code {
|
|
74
|
+
@apply font-mono;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
.code pre {
|
|
78
|
+
@apply block;
|
|
79
|
+
/* @apply whitespace-pre-wrap; */
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
.code .line {
|
|
83
|
+
@apply leading-relaxed;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
.code.numbered {
|
|
87
|
+
@apply relative pt-3;
|
|
62
88
|
}
|
|
63
89
|
|
|
64
|
-
.
|
|
65
|
-
|
|
90
|
+
.code.numbered:before {
|
|
91
|
+
content: "";
|
|
92
|
+
left: 2.7em;
|
|
93
|
+
@apply absolute top-0 bottom-0 border-r border-gray-200;
|
|
66
94
|
}
|
|
67
95
|
|
|
96
|
+
.code.numbered .line {
|
|
97
|
+
padding-left: calc(2.7em + 8px);
|
|
98
|
+
@apply relative;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
.code .line-number {
|
|
102
|
+
display: inline-block;
|
|
103
|
+
width: calc(2.7em + 8px);
|
|
104
|
+
padding-top: 3px;
|
|
105
|
+
padding-bottom: 3px;
|
|
106
|
+
padding-right: 8px;
|
|
107
|
+
margin-right: 16px;
|
|
108
|
+
@apply font-mono text-right text-gray-400 flex-none text-xs absolute left-0;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
.code .line-content {
|
|
112
|
+
@apply flex-none pr-4;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
.resize-handle {
|
|
116
|
+
@apply flex items-center justify-center h-full w-full border-gray-300 bg-white hover:bg-indigo-100 hover:bg-opacity-20 text-gray-400 hover:text-gray-700 transition select-none touch-none;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
@layer utilities {
|
|
68
121
|
.form-input {
|
|
69
122
|
@apply border-gray-300 text-gray-700 focus:ring-indigo-300 focus:border-indigo-300 rounded-sm text-sm w-full;
|
|
70
123
|
}
|
|
124
|
+
|
|
125
|
+
.checked-bg {
|
|
126
|
+
background-color: #ffffff;
|
|
127
|
+
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3E%3Cg fill='%23f3f3f3' fill-opacity='1'%3E%3Cpath fill-rule='evenodd' d='M0 0h4v4H0V0zm4 4h4v4H4V4z'/%3E%3C/g%3E%3C/svg%3E");
|
|
128
|
+
}
|
|
71
129
|
}
|
|
@@ -4,13 +4,41 @@
|
|
|
4
4
|
&[data-placement^="top"] > .tippy-arrow::before {
|
|
5
5
|
border-top-color: theme("colors.indigo.500");
|
|
6
6
|
}
|
|
7
|
+
|
|
7
8
|
&[data-placement^="bottom"] > .tippy-arrow::before {
|
|
8
9
|
border-bottom-color: theme("colors.indigo.500");
|
|
9
10
|
}
|
|
11
|
+
|
|
10
12
|
&[data-placement^="left"] > .tippy-arrow::before {
|
|
11
13
|
border-left-color: theme("colors.indigo.500");
|
|
12
14
|
}
|
|
15
|
+
|
|
13
16
|
&[data-placement^="right"] > .tippy-arrow::before {
|
|
14
17
|
border-right-color: theme("colors.indigo.500");
|
|
15
18
|
}
|
|
16
19
|
}
|
|
20
|
+
|
|
21
|
+
.tippy-box[data-theme~="menu"] {
|
|
22
|
+
border: 1px solid theme("colors.gray.300");
|
|
23
|
+
@apply bg-white text-gray-600 shadow-md rounded;
|
|
24
|
+
|
|
25
|
+
& > .tippy-content {
|
|
26
|
+
padding: 0;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
&[data-placement^="top"] > .tippy-arrow::before {
|
|
30
|
+
border-top-color: white;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
&[data-placement^="bottom"] > .tippy-arrow::before {
|
|
34
|
+
border-bottom-color: white;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
&[data-placement^="left"] > .tippy-arrow::before {
|
|
38
|
+
border-left-color: white;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
&[data-placement^="right"] > .tippy-arrow::before {
|
|
42
|
+
border-right-color: white;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -1,66 +1,56 @@
|
|
|
1
1
|
import { install } from "@github/hotkey";
|
|
2
2
|
import Alpine from "alpinejs";
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
|
|
7
|
-
import
|
|
8
|
-
import
|
|
9
|
-
import
|
|
10
|
-
import
|
|
11
|
-
import
|
|
12
|
-
import
|
|
13
|
-
import
|
|
14
|
-
import
|
|
15
|
-
import
|
|
16
|
-
import
|
|
17
|
-
import
|
|
18
|
-
import
|
|
19
|
-
|
|
20
|
-
|
|
3
|
+
import Persist from "@alpinejs/persist";
|
|
4
|
+
import Morph from "@alpinejs/morph";
|
|
5
|
+
import Tooltip from "@ryangjchandler/alpine-tooltip";
|
|
6
|
+
|
|
7
|
+
import page from "./components/page";
|
|
8
|
+
import inspector from "./components/inspector";
|
|
9
|
+
import previewWindow from "./components/preview-window";
|
|
10
|
+
import filter from "./components/filter";
|
|
11
|
+
import param from "./components/param";
|
|
12
|
+
import nav from "./components/nav";
|
|
13
|
+
import navItem from "./components/nav-item";
|
|
14
|
+
import navGroup from "./components/nav-group";
|
|
15
|
+
import splitter from "./components/splitter";
|
|
16
|
+
import tabs from "./components/tabs";
|
|
17
|
+
import copy from "./components/copy";
|
|
18
|
+
import sizes from "./components/sizes";
|
|
19
|
+
|
|
20
|
+
import initFilterStore from "./stores/filter";
|
|
21
|
+
import initLayoutStore from "./stores/layout";
|
|
22
|
+
import initNavStore from "./stores/nav";
|
|
23
|
+
import initSidebarStore from "./stores/sidebar";
|
|
24
|
+
import initInspectorStore from "./stores/inspector";
|
|
21
25
|
|
|
22
26
|
// Plugins
|
|
23
27
|
|
|
24
|
-
Alpine.plugin(
|
|
25
|
-
Alpine.plugin(
|
|
26
|
-
Alpine.plugin(
|
|
27
|
-
Alpine.plugin(Screen);
|
|
28
|
+
Alpine.plugin(Persist);
|
|
29
|
+
Alpine.plugin(Morph);
|
|
30
|
+
Alpine.plugin(Tooltip);
|
|
28
31
|
|
|
29
32
|
// Stores
|
|
30
33
|
|
|
31
|
-
Alpine.store("
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
Alpine.persistedStore("nav", {
|
|
37
|
-
width: 280,
|
|
38
|
-
filter: "",
|
|
39
|
-
open: {},
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
Alpine.persistedStore("inspector", {
|
|
43
|
-
height: 200,
|
|
44
|
-
active: "source",
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
Alpine.persistedStore("preview", {
|
|
48
|
-
width: "100%",
|
|
49
|
-
});
|
|
34
|
+
Alpine.store("filter", initFilterStore(Alpine));
|
|
35
|
+
Alpine.store("layout", initLayoutStore(Alpine));
|
|
36
|
+
Alpine.store("nav", initNavStore(Alpine));
|
|
37
|
+
Alpine.store("sidebar", initSidebarStore(Alpine));
|
|
38
|
+
Alpine.store("inspector", initInspectorStore(Alpine));
|
|
50
39
|
|
|
51
|
-
// Components
|
|
40
|
+
// Components
|
|
52
41
|
|
|
53
42
|
Alpine.data("page", page);
|
|
54
|
-
Alpine.data("
|
|
55
|
-
Alpine.data("
|
|
56
|
-
Alpine.data("
|
|
57
|
-
Alpine.data("workbench", workbench);
|
|
58
|
-
Alpine.data("preview", preview);
|
|
43
|
+
Alpine.data("splitter", splitter);
|
|
44
|
+
Alpine.data("previewWindow", previewWindow);
|
|
45
|
+
Alpine.data("copy", copy);
|
|
59
46
|
Alpine.data("inspector", inspector);
|
|
47
|
+
Alpine.data("filter", filter);
|
|
60
48
|
Alpine.data("param", param);
|
|
61
|
-
Alpine.data("
|
|
62
|
-
Alpine.data("
|
|
63
|
-
Alpine.data("
|
|
49
|
+
Alpine.data("sizes", sizes);
|
|
50
|
+
Alpine.data("nav", nav);
|
|
51
|
+
Alpine.data("tabs", tabs);
|
|
52
|
+
Alpine.data("navItem", navItem);
|
|
53
|
+
Alpine.data("navGroup", navGroup);
|
|
64
54
|
|
|
65
55
|
// Init
|
|
66
56
|
|
|
@@ -68,9 +58,5 @@ for (const el of document.querySelectorAll("[data-hotkey]")) {
|
|
|
68
58
|
install(el);
|
|
69
59
|
}
|
|
70
60
|
|
|
71
|
-
if (window.SOCKET_PATH) {
|
|
72
|
-
reloader(window.SOCKET_PATH).start();
|
|
73
|
-
}
|
|
74
|
-
|
|
75
61
|
window.Alpine = Alpine;
|
|
76
62
|
Alpine.start();
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export default function copy(id) {
|
|
2
|
+
return {
|
|
3
|
+
get content() {
|
|
4
|
+
const target = document.getElementById(id);
|
|
5
|
+
return (target ? target.innerHTML : "").trim();
|
|
6
|
+
},
|
|
7
|
+
done: false,
|
|
8
|
+
async save() {
|
|
9
|
+
await window.navigator.clipboard.writeText(this.content);
|
|
10
|
+
this.done = true;
|
|
11
|
+
setTimeout(() => {
|
|
12
|
+
this.done = false;
|
|
13
|
+
}, 1000);
|
|
14
|
+
},
|
|
15
|
+
};
|
|
16
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export default function filter() {
|
|
2
|
+
return {
|
|
3
|
+
get active() {
|
|
4
|
+
return this.$store.filter.active;
|
|
5
|
+
},
|
|
6
|
+
checkEsc($event) {
|
|
7
|
+
if ($event.key === "Escape") {
|
|
8
|
+
this.active ? this.clear() : this.blur();
|
|
9
|
+
}
|
|
10
|
+
},
|
|
11
|
+
clear() {
|
|
12
|
+
this.$store.filter.raw = "";
|
|
13
|
+
},
|
|
14
|
+
focus($event) {
|
|
15
|
+
if ($event && $event.target.tagName === "INPUT") {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
setTimeout(() => this.$refs.input.focus(), 0);
|
|
19
|
+
},
|
|
20
|
+
blur() {
|
|
21
|
+
setTimeout(() => this.$refs.input.blur(), 0);
|
|
22
|
+
},
|
|
23
|
+
};
|
|
24
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import sizeObserver from "./sizes";
|
|
2
|
+
|
|
3
|
+
export default function inspector() {
|
|
4
|
+
return {
|
|
5
|
+
width: 0,
|
|
6
|
+
height: 0,
|
|
7
|
+
init() {
|
|
8
|
+
const ro = new ResizeObserver((entries) => {
|
|
9
|
+
const rect = entries[0].contentRect;
|
|
10
|
+
this.width = Math.round(rect.width);
|
|
11
|
+
this.height = Math.round(rect.height);
|
|
12
|
+
});
|
|
13
|
+
ro.observe(this.$el);
|
|
14
|
+
this.width = Math.round(this.$el.clientWidth);
|
|
15
|
+
this.height = Math.round(this.$el.clientHeight);
|
|
16
|
+
},
|
|
17
|
+
get orientation() {
|
|
18
|
+
return this.$store.inspector.drawer.orientation;
|
|
19
|
+
},
|
|
20
|
+
get view() {
|
|
21
|
+
return this.$store.inspector.preview.view;
|
|
22
|
+
},
|
|
23
|
+
get horizontal() {
|
|
24
|
+
return this.canBeVertical ? this.orientation === "horizontal" : true;
|
|
25
|
+
},
|
|
26
|
+
get vertical() {
|
|
27
|
+
return !this.horizontal;
|
|
28
|
+
},
|
|
29
|
+
get canBeVertical() {
|
|
30
|
+
return this.width > 800;
|
|
31
|
+
},
|
|
32
|
+
get drawerHidden() {
|
|
33
|
+
return this.$store.inspector.drawer.hidden;
|
|
34
|
+
},
|
|
35
|
+
isActivePanel(panel) {
|
|
36
|
+
return this.$store.inspector.drawer.active == panel;
|
|
37
|
+
},
|
|
38
|
+
switchPanel(panel) {
|
|
39
|
+
this.$store.inspector.drawer.active = panel;
|
|
40
|
+
},
|
|
41
|
+
toggleView() {
|
|
42
|
+
this.$store.inspector.preview.view =
|
|
43
|
+
this.view === "html" ? "preview" : "html";
|
|
44
|
+
},
|
|
45
|
+
toggleOrientation() {
|
|
46
|
+
this.$store.inspector.drawer.orientation =
|
|
47
|
+
this.orientation === "horizontal" ? "vertical" : "horizontal";
|
|
48
|
+
},
|
|
49
|
+
toggleDrawer() {
|
|
50
|
+
this.$store.inspector.drawer.hidden =
|
|
51
|
+
!this.$store.inspector.drawer.hidden;
|
|
52
|
+
},
|
|
53
|
+
preview: {
|
|
54
|
+
width: null,
|
|
55
|
+
height: null,
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
}
|
|
@@ -1,43 +1,44 @@
|
|
|
1
|
-
|
|
1
|
+
import { getAlpineData } from "../lib/utils";
|
|
2
|
+
|
|
3
|
+
export default function navGroup() {
|
|
2
4
|
return {
|
|
3
|
-
|
|
4
|
-
hidden: true,
|
|
5
|
+
hidden: false,
|
|
5
6
|
children: [],
|
|
6
|
-
|
|
7
|
-
|
|
7
|
+
get id() {
|
|
8
|
+
return this.$root.id;
|
|
8
9
|
},
|
|
9
|
-
open() {
|
|
10
|
-
return this.$store.nav.
|
|
10
|
+
get open() {
|
|
11
|
+
return this.$store.nav.isOpen(this.id);
|
|
12
|
+
},
|
|
13
|
+
toggle() {
|
|
14
|
+
this.$store.nav.toggle(this.id);
|
|
11
15
|
},
|
|
12
16
|
getChildren() {
|
|
13
17
|
return this.$refs.items
|
|
14
|
-
? Array.from(this.$refs.items.querySelectorAll(":scope > li"))
|
|
18
|
+
? Array.from(this.$refs.items.querySelectorAll(":scope > li > div"))
|
|
15
19
|
: [];
|
|
16
20
|
},
|
|
17
21
|
navigateToFirstChild() {
|
|
18
|
-
if (this.open
|
|
22
|
+
if (this.open) {
|
|
19
23
|
const child = this.firstVisibleChild();
|
|
20
24
|
if (child) {
|
|
21
25
|
const link = child.querySelector(":scope > a.nav-link");
|
|
22
26
|
if (link) {
|
|
23
|
-
this.
|
|
27
|
+
this.setLocation(link.getAttribute("href"));
|
|
24
28
|
}
|
|
25
29
|
}
|
|
26
30
|
}
|
|
27
31
|
},
|
|
28
|
-
filter() {
|
|
32
|
+
filter(text) {
|
|
29
33
|
this.hidden = true;
|
|
30
34
|
this.getChildren().forEach((child) => {
|
|
31
|
-
const data = child
|
|
32
|
-
data.filter();
|
|
35
|
+
const data = getAlpineData(child);
|
|
36
|
+
data.filter(text);
|
|
33
37
|
if (!data.hidden) {
|
|
34
38
|
this.hidden = false;
|
|
35
39
|
}
|
|
36
40
|
});
|
|
37
41
|
},
|
|
38
|
-
toggle() {
|
|
39
|
-
this.$store.nav.open[this.id] = !this.$store.nav.open[this.id];
|
|
40
|
-
},
|
|
41
42
|
firstVisibleChild() {
|
|
42
43
|
return this.getChildren().find((child) => {
|
|
43
44
|
return child._x_dataStack
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export default function navItem(matchers) {
|
|
2
|
+
return {
|
|
3
|
+
hidden: false,
|
|
4
|
+
get id() {
|
|
5
|
+
return this.$root.id;
|
|
6
|
+
},
|
|
7
|
+
get path() {
|
|
8
|
+
return this.$root.getAttribute("data-path");
|
|
9
|
+
},
|
|
10
|
+
get active() {
|
|
11
|
+
return this.$store.nav.active === this.id;
|
|
12
|
+
},
|
|
13
|
+
navigate() {
|
|
14
|
+
this.setLocation(this.path);
|
|
15
|
+
this.$store.sidebar.open = false;
|
|
16
|
+
},
|
|
17
|
+
filter(text) {
|
|
18
|
+
this.hidden = false;
|
|
19
|
+
if (text.length) {
|
|
20
|
+
const matched = matchers.map((m) => m.includes(text));
|
|
21
|
+
this.hidden = !matched.filter((m) => m).length;
|
|
22
|
+
} else {
|
|
23
|
+
this.hidden = false;
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { getAlpineData } from "../lib/utils";
|
|
2
|
+
|
|
3
|
+
export default function nav() {
|
|
4
|
+
return {
|
|
5
|
+
empty: false,
|
|
6
|
+
init() {
|
|
7
|
+
this.$watch("$store.filter.text", () => this.filter());
|
|
8
|
+
this.$nextTick(() => {
|
|
9
|
+
this.setActive();
|
|
10
|
+
this.filter();
|
|
11
|
+
});
|
|
12
|
+
},
|
|
13
|
+
filter() {
|
|
14
|
+
this.empty = true;
|
|
15
|
+
this.getChildren().forEach((child) => {
|
|
16
|
+
const data = getAlpineData(child);
|
|
17
|
+
data.filter(this.$store.filter.text);
|
|
18
|
+
if (!data.hidden) {
|
|
19
|
+
this.empty = false;
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
},
|
|
23
|
+
getChildren() {
|
|
24
|
+
return this.$refs.items
|
|
25
|
+
? Array.from(this.$refs.items.querySelectorAll(":scope > li > div"))
|
|
26
|
+
: [];
|
|
27
|
+
},
|
|
28
|
+
setActive() {
|
|
29
|
+
const target = this.$el.querySelector(
|
|
30
|
+
`[data-path="${window.location.pathname}"]`
|
|
31
|
+
);
|
|
32
|
+
this.$store.nav.active = target ? target.id : "";
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import createSocket from "../lib/socket";
|
|
2
|
+
|
|
3
|
+
const morphOpts = {
|
|
4
|
+
key(el) {
|
|
5
|
+
return el.getAttribute("key") ? el.getAttribute("key") : el.id;
|
|
6
|
+
},
|
|
7
|
+
updating(el, toEl, childrenOnly, skip) {
|
|
8
|
+
if (
|
|
9
|
+
el.getAttribute &&
|
|
10
|
+
el.getAttribute("data-morph-strategy") === "replace"
|
|
11
|
+
) {
|
|
12
|
+
el.innerHTML = toEl.innerHTML;
|
|
13
|
+
return skip();
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
lookahead: true,
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export default function page() {
|
|
20
|
+
return {
|
|
21
|
+
init() {
|
|
22
|
+
const socket = createSocket(window.SOCKET_PATH);
|
|
23
|
+
socket.addListener("Lookbook::ReloadChannel", () => this.refresh());
|
|
24
|
+
},
|
|
25
|
+
async update() {
|
|
26
|
+
const response = await fetch(window.document.location);
|
|
27
|
+
if (!response.ok) return window.location.reload();
|
|
28
|
+
const html = await response.text();
|
|
29
|
+
this.morph(new DOMParser().parseFromString(html, "text/html"));
|
|
30
|
+
},
|
|
31
|
+
setLocation(loc) {
|
|
32
|
+
const path = loc instanceof Event ? loc.currentTarget.href : loc;
|
|
33
|
+
history.pushState({}, null, path);
|
|
34
|
+
this.$dispatch("popstate");
|
|
35
|
+
},
|
|
36
|
+
refresh() {
|
|
37
|
+
this.$dispatch("popstate");
|
|
38
|
+
},
|
|
39
|
+
morph(dom) {
|
|
40
|
+
const pageHtml = dom.getElementById(this.$root.id).outerHTML;
|
|
41
|
+
Alpine.morph(this.$root, pageHtml, morphOpts);
|
|
42
|
+
this.$dispatch("page:morphed");
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import debounce from "debounce";
|
|
2
|
+
|
|
3
|
+
export default function param(name, value) {
|
|
4
|
+
return {
|
|
5
|
+
name,
|
|
6
|
+
value,
|
|
7
|
+
init() {
|
|
8
|
+
this.$watch(
|
|
9
|
+
"value",
|
|
10
|
+
debounce(() => {
|
|
11
|
+
if (this.validate()) {
|
|
12
|
+
this.update();
|
|
13
|
+
}
|
|
14
|
+
}, 300)
|
|
15
|
+
);
|
|
16
|
+
},
|
|
17
|
+
setFocus() {
|
|
18
|
+
if (this.$refs.input) {
|
|
19
|
+
setTimeout(() => this.$refs.input.focus(), 0);
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
update() {
|
|
23
|
+
const searchParams = new URLSearchParams(window.location.search);
|
|
24
|
+
searchParams.set(this.name, this.value);
|
|
25
|
+
const path = location.href.replace(location.search, "");
|
|
26
|
+
this.setLocation(`${path}?${searchParams.toString()}`);
|
|
27
|
+
},
|
|
28
|
+
validate() {
|
|
29
|
+
return this.$el.reportValidity ? this.$el.reportValidity() : true;
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
}
|