lookbook 0.5.0.beta.2 → 0.6.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 +30 -32
- data/app/assets/lookbook/js/components/copy.js +7 -3
- data/app/assets/lookbook/js/components/inspector.js +15 -7
- data/app/assets/lookbook/js/components/page.js +3 -1
- data/app/assets/lookbook/js/config.js +3 -2
- data/app/assets/lookbook/js/stores/inspector.js +3 -2
- data/app/controllers/lookbook/app_controller.rb +23 -11
- data/app/views/layouts/lookbook/app.html.erb +3 -1
- data/app/views/lookbook/components/_drawer.html.erb +38 -35
- data/app/views/lookbook/components/_header.html.erb +2 -2
- data/app/views/lookbook/components/_nav_preview.html.erb +4 -2
- data/app/views/lookbook/components/_preview.html.erb +65 -46
- data/app/views/lookbook/panels/_output.html.erb +1 -1
- data/app/views/lookbook/panels/_preview.html.erb +52 -0
- data/app/views/lookbook/show.html.erb +5 -54
- data/lib/lookbook/engine.rb +1 -1
- data/lib/lookbook/features.rb +1 -1
- data/lib/lookbook/preview.rb +1 -1
- data/lib/lookbook/version.rb +1 -1
- data/public/lookbook-assets/css/app.css +1 -1
- data/public/lookbook-assets/css/app.css.map +1 -1
- data/public/lookbook-assets/js/app.js +1 -1
- data/public/lookbook-assets/js/app.js.map +1 -1
- metadata +20 -6
- data/app/views/lookbook/components/_copy.html.erb +0 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 77ec54d7371b46e26f850afe422f94a008bd40a11dd861db81763bf16b4a3776
|
4
|
+
data.tar.gz: 0755cfd84d1be9b1979a528619a69a127c376268b8015d7f6ee2e55c8d6b4dac
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ee0dabd03d84efd6598bab86a4e2a7298126f4ade488aaf535dc12de7b2fd7334224f40b45c5482afba4a3e4196713d165efc56ea3f859e085b2b216ccb1e3f7
|
7
|
+
data.tar.gz: 97d9d33c6cad98c8c9c4224cb5ecfbf4676902a2b7980ef7122f1547ac626c6b4727204772090d9d0702fbb368032b1b5f496d3e6f4f5e9ba22d93be28675f01
|
data/README.md
CHANGED
@@ -28,7 +28,7 @@ Lookbook uses [RDoc/Yard-style comment tags](#annotating-preview-files) to exten
|
|
28
28
|
- Auto-updating UI when component or preview files are updated _(Rails v6.0+ only)_
|
29
29
|
- Use comment tag annotations for granular customisation of the preview experience
|
30
30
|
- Fully compatible with standard the ViewComponent preview system
|
31
|
-
-
|
31
|
+
- In-browser live-editable preview parameters (similar to basic Storybook Controls/Knobs)
|
32
32
|
|
33
33
|
## Lookbook demo
|
34
34
|
|
@@ -63,10 +63,16 @@ end
|
|
63
63
|
|
64
64
|
The `at` property determines the root URL that the Lookbook UI will be served at.
|
65
65
|
|
66
|
-
> If you would like to expose the Lookbook UI in production as well as in development, just remove the `if Rails.env.development?` condition from around the mount statement.
|
67
|
-
|
68
66
|
Then you can start your app as normal and navigate to `http://localhost:3000/lookbook` (or whatever mount path you specified) to view your component previews in the Lookbook UI.
|
69
67
|
|
68
|
+
#### Mounting in Production
|
69
|
+
|
70
|
+
If you would like to expose the Lookbook UI in production as well as in development
|
71
|
+
|
72
|
+
1. Remove the `if Rails.env.development?` condition from around the mount statement in `routes.rb`
|
73
|
+
2. Add `config.view_component.show_previews = true` to `config/environments/production.rb`
|
74
|
+
|
75
|
+
|
70
76
|
## Usage
|
71
77
|
|
72
78
|
You don't need to do anything special to see your ViewComponent previews and examples in Lookbook - just create them as normal and they'll automatically appear in the Lookbook UI. Preview templates, custom layouts and even bespoke [preview controllers](https://viewcomponent.org/guide/previews.html#configuring-preview-controller) should all work as you would expect.
|
@@ -96,7 +102,7 @@ class ButtonComponentPreview < ViewComponent::Preview
|
|
96
102
|
# Button with icon
|
97
103
|
# ----------------
|
98
104
|
# This example uses dynamic preview parameters
|
99
|
-
# which can be edited live in the Lookbook UI
|
105
|
+
# which can be edited live in the Lookbook UI
|
100
106
|
#
|
101
107
|
# @param text
|
102
108
|
# @param icon select [heart, cog, alert]
|
@@ -161,7 +167,7 @@ The following Lookbook-specific tags are available for use:
|
|
161
167
|
* [`@display`](#display-tag)
|
162
168
|
* [`@!group ... @!endgroup`](#group-tag)
|
163
169
|
* [`@hidden`](#hidden-tag)
|
164
|
-
* [`@param`](#param-tag)
|
170
|
+
* [`@param`](#param-tag)
|
165
171
|
|
166
172
|
<h3 id="label-tag">🏷 @label</h3>
|
167
173
|
|
@@ -311,9 +317,7 @@ class FooComponentPreview < ViewComponent::Preview
|
|
311
317
|
end
|
312
318
|
```
|
313
319
|
|
314
|
-
<h3 id="param-tag"
|
315
|
-
|
316
|
-
> ⚠️ This feature is currently flagged as an **experimental** feature which requires [feature opt-in](#experimental-features) to use. Its API and implementation may change in the future.
|
320
|
+
<h3 id="param-tag">@param</h3>
|
317
321
|
|
318
322
|
The `@param` tag provides the ability to specify **editable preview parameters** which can be changed in the Lookbook UI in order to customise the rendered output on the fly, much like the [Controls (knobs) addon](https://storybook.js.org/addons/@storybook/addon-controls) for Storybook.
|
319
323
|
|
@@ -326,7 +330,7 @@ The `@param` tag takes the following format:
|
|
326
330
|
```
|
327
331
|
|
328
332
|
- `<name>` - name of the dynamic preview param
|
329
|
-
- `<input_type>` - input field type to generate in the UI
|
333
|
+
- `<input_type>` - input field type to generate in the UI
|
330
334
|
- `<opts?>` - YAML-encoded field options, used for some field types
|
331
335
|
|
332
336
|
#### Input types
|
@@ -357,7 +361,7 @@ The following **input field types** are available for use:
|
|
357
361
|
@param <name> select <options>
|
358
362
|
```
|
359
363
|
|
360
|
-
`<options>` should be a [YAML array](https://yaml.org/YAML_for_ruby.html#simple_inline_array) of options which must be formatted in the same style as the input for Rails' [`options_for_select`](https://apidock.com/rails/v6.0.0/ActionView/Helpers/FormOptionsHelper/options_for_select) helper:
|
364
|
+
`<options>` should be a [YAML array](https://yaml.org/YAML_for_ruby.html#simple_inline_array) of options which must be formatted in the same style as the input for Rails' [`options_for_select`](https://apidock.com/rails/v6.0.0/ActionView/Helpers/FormOptionsHelper/options_for_select) helper:
|
361
365
|
|
362
366
|
```ruby
|
363
367
|
# Basic options:
|
@@ -437,7 +441,7 @@ The following structured types are also available but should be considered **exp
|
|
437
441
|
|
438
442
|
```ruby
|
439
443
|
class ButtonComponentPreview < ViewComponent::Preview
|
440
|
-
|
444
|
+
|
441
445
|
# The params defined below will be editable in the UI:
|
442
446
|
#
|
443
447
|
# @param content text
|
@@ -470,8 +474,6 @@ class ProfileCardComponentPreview < ViewComponent::Preview
|
|
470
474
|
end
|
471
475
|
```
|
472
476
|
|
473
|
-
<img src=".github/assets/preview_example_notes.png" width="400">
|
474
|
-
|
475
477
|
## Configuration
|
476
478
|
|
477
479
|
Lookbook will use the ViewComponent [configuration](https://viewcomponent.org/api.html#configuration) for your project to find and render your previews so you generally you won't need to configure anything separately.
|
@@ -496,6 +498,17 @@ If you wish to add additional paths to listen for changes in, you can use the `l
|
|
496
498
|
config.lookbook.listen_paths << Rails.root.join('app/other/directory')
|
497
499
|
```
|
498
500
|
|
501
|
+
### Custom favicon
|
502
|
+
|
503
|
+
If you want to change the favicon used by the Lookbook UI, you can provide a path to your own (or a data-uri string) using the `ui_favicon` option:
|
504
|
+
|
505
|
+
```ruby
|
506
|
+
config.lookbook.ui_favicon = "/path/to/my/favicon.png"
|
507
|
+
```
|
508
|
+
|
509
|
+
> To disable the favicon entirely, set the value to `false`.
|
510
|
+
|
511
|
+
|
499
512
|
<h3 id="experimental-features">Experimental features opt-in</h3>
|
500
513
|
|
501
514
|
Some features may occasionally be released behind a 'experimental' feature flag while they are being tested and refined, to allow people to try them out and provide feedback.
|
@@ -510,10 +523,6 @@ To opt into individual experimental features, include the name of the feature in
|
|
510
523
|
config.lookbook.experimental_features = ["feature_name"]
|
511
524
|
```
|
512
525
|
|
513
|
-
The current experimental features that can be opted into are:
|
514
|
-
|
515
|
-
- `params`: Live-editable, dynamic preview parameters ([read more](#param-tag)). Include `"params"` in the `experimental_features` config option to opt in.
|
516
|
-
|
517
526
|
#### Opting into all experimental features (not recommended!)
|
518
527
|
|
519
528
|
If you want to live life on the bleeding-edge you can opt-in to all current **and future** experimental features (usual caveats apply):
|
@@ -529,24 +538,13 @@ Lookbook provides a few keyboard shortcuts to help you quickly move around the U
|
|
529
538
|
|
530
539
|
- `f` - move focus to the nav filter box
|
531
540
|
- `Esc` [when focus is in nav filter box] - Clear contents if text is present, or return focus to the UI if the box is already empty
|
532
|
-
- `s` - Switch to Source tab in the
|
533
|
-
- `
|
534
|
-
- `
|
541
|
+
- `s` - Switch to Source tab in the drawer
|
542
|
+
- `n` - Switch to Notes tab in the drawer
|
543
|
+
- `v` - Switch to the rendered preview
|
544
|
+
- `o` - Switch to the code preview
|
535
545
|
- `r` - Refresh the preview (useful if using something like Faker to generate randomised data for the preview)
|
536
546
|
- `w` - Open the standalone rendered preview in a new window
|
537
547
|
|
538
|
-
## Troubleshooting
|
539
|
-
|
540
|
-
#### Blank preview window
|
541
|
-
|
542
|
-
Certain setups (for example when using `Rack::LiveReload`) can cause an issue with the way that the preview iframe displays the rendered component preview (i.e. using the `srcdoc` attribute to avoid extra requests).
|
543
|
-
|
544
|
-
If you are seeing a blank preview window, but the source and output tabs are both displaying code as expected, you can disable the use of the `srcdoc` attribute using the following configuration option:
|
545
|
-
|
546
|
-
```ruby
|
547
|
-
config.lookbook.preview_srcdoc = false
|
548
|
-
```
|
549
|
-
|
550
548
|
## Contributing
|
551
549
|
|
552
550
|
Lookbook is very much a small hobby/side project at the moment. I'd love to hear from anyone who is interested in contributing but I'm terrible at replying to emails or messages, so don't be surprised if I take forever to get back to you. It's not personal 😜
|
@@ -1,8 +1,12 @@
|
|
1
|
-
export default function copy(
|
1
|
+
export default function copy() {
|
2
2
|
return {
|
3
3
|
get content() {
|
4
|
-
const target = document.getElementById(
|
5
|
-
|
4
|
+
const target = document.getElementById(
|
5
|
+
this.$root.getAttribute("data-target")
|
6
|
+
);
|
7
|
+
const decoder = document.createElement("textarea");
|
8
|
+
decoder.innerHTML = target ? target.innerHTML : "";
|
9
|
+
return decoder.value.trim();
|
6
10
|
},
|
7
11
|
done: false,
|
8
12
|
async save() {
|
@@ -32,15 +32,23 @@ export default function inspector() {
|
|
32
32
|
get drawerHidden() {
|
33
33
|
return this.$store.inspector.drawer.hidden;
|
34
34
|
},
|
35
|
-
|
36
|
-
return this
|
35
|
+
get maxDrawerHeight() {
|
36
|
+
return Math.round(this.height * 0.7);
|
37
37
|
},
|
38
|
-
|
39
|
-
this
|
38
|
+
get maxDrawerWidth() {
|
39
|
+
return Math.round(this.width * 0.7);
|
40
40
|
},
|
41
|
-
|
42
|
-
this.$store.inspector.
|
43
|
-
|
41
|
+
isActiveDrawerPanel(panel) {
|
42
|
+
return this.$store.inspector.drawer.panel === panel;
|
43
|
+
},
|
44
|
+
switchDrawerPanel(panel) {
|
45
|
+
this.$store.inspector.drawer.panel = panel;
|
46
|
+
},
|
47
|
+
isActivePreviewPanel(panel) {
|
48
|
+
return this.$store.inspector.preview.panel === panel;
|
49
|
+
},
|
50
|
+
switchPreviewPanel(panel) {
|
51
|
+
this.$store.inspector.preview.panel = panel;
|
44
52
|
},
|
45
53
|
toggleOrientation() {
|
46
54
|
this.$store.inspector.drawer.orientation =
|
@@ -26,7 +26,9 @@ export default function page() {
|
|
26
26
|
const response = await fetch(window.document.location);
|
27
27
|
if (!response.ok) return window.location.reload();
|
28
28
|
const html = await response.text();
|
29
|
-
|
29
|
+
const newDoc = new DOMParser().parseFromString(html, "text/html");
|
30
|
+
this.morph(newDoc);
|
31
|
+
document.title = newDoc.title;
|
30
32
|
},
|
31
33
|
setLocation(loc) {
|
32
34
|
const path = loc instanceof Event ? loc.currentTarget.href : loc;
|
@@ -9,12 +9,13 @@ export default {
|
|
9
9
|
drawer: {
|
10
10
|
orientation: "horizontal",
|
11
11
|
defaultPanel: "source",
|
12
|
-
defaultHeight:
|
12
|
+
defaultHeight: 300,
|
13
13
|
defaultWidth: 500,
|
14
14
|
minWidth: 350,
|
15
|
+
minHeight: 200,
|
15
16
|
},
|
16
17
|
preview: {
|
17
|
-
|
18
|
+
defaultPanel: "preview",
|
18
19
|
},
|
19
20
|
},
|
20
21
|
};
|
@@ -6,16 +6,17 @@ export default function createInspectorStore(Alpine) {
|
|
6
6
|
drawer: {
|
7
7
|
hidden: Alpine.$persist(false).as("drawer-hidden"),
|
8
8
|
orientation: Alpine.$persist(drawer.orientation).as("drawer-orientation"),
|
9
|
-
|
9
|
+
panel: Alpine.$persist(drawer.defaultPanel).as("drawer-panel"),
|
10
10
|
height: Alpine.$persist(drawer.defaultHeight).as("drawer-height"),
|
11
11
|
width: Alpine.$persist(drawer.defaultWidth).as("drawer-width"),
|
12
12
|
minWidth: drawer.minWidth,
|
13
|
+
minHeight: drawer.minHeight,
|
13
14
|
visibleTabCount: Infinity,
|
14
15
|
},
|
15
16
|
preview: {
|
16
17
|
width: Alpine.$persist("100%").as("preview-width"),
|
17
18
|
height: Alpine.$persist("100%").as("preview-height"),
|
18
|
-
|
19
|
+
panel: Alpine.$persist(preview.defaultPanel).as("preview-panel"),
|
19
20
|
lastWidth: null,
|
20
21
|
lastHeight: null,
|
21
22
|
resizing: false,
|
@@ -27,10 +27,8 @@ module Lookbook
|
|
27
27
|
begin
|
28
28
|
set_params
|
29
29
|
@examples = examples_data
|
30
|
-
@
|
31
|
-
|
32
|
-
end
|
33
|
-
@panels = panels.filter { |name, panel| panel[:show] }
|
30
|
+
@drawer_panels = drawer_panels.filter { |name, panel| panel[:show] }
|
31
|
+
@preview_panels = preview_panels.filter { |name, panel| panel[:show] }
|
34
32
|
rescue *EXCEPTIONS
|
35
33
|
render "error"
|
36
34
|
end
|
@@ -119,23 +117,37 @@ module Lookbook
|
|
119
117
|
@nav
|
120
118
|
end
|
121
119
|
|
122
|
-
def
|
120
|
+
def preview_panels
|
123
121
|
{
|
124
|
-
|
125
|
-
label: "
|
126
|
-
template: "lookbook/panels/
|
127
|
-
|
122
|
+
preview: {
|
123
|
+
label: "Preview",
|
124
|
+
template: "lookbook/panels/preview",
|
125
|
+
srcdoc: Lookbook.config.preview_srcdoc ? render_examples(examples_data).gsub("\"", """) : nil,
|
126
|
+
hotkey: "v",
|
128
127
|
show: true,
|
129
128
|
disabled: false,
|
130
|
-
copy:
|
129
|
+
copy: false
|
131
130
|
},
|
132
131
|
output: {
|
133
|
-
label: "
|
132
|
+
label: "HTML",
|
134
133
|
template: "lookbook/panels/output",
|
135
134
|
hotkey: "o",
|
136
135
|
show: true,
|
137
136
|
disabled: false,
|
138
137
|
copy: true
|
138
|
+
}
|
139
|
+
}
|
140
|
+
end
|
141
|
+
|
142
|
+
def drawer_panels
|
143
|
+
{
|
144
|
+
source: {
|
145
|
+
label: "Source",
|
146
|
+
template: "lookbook/panels/source",
|
147
|
+
hotkey: "s",
|
148
|
+
show: true,
|
149
|
+
disabled: false,
|
150
|
+
copy: true
|
139
151
|
},
|
140
152
|
notes: {
|
141
153
|
label: "Notes",
|
@@ -6,7 +6,9 @@
|
|
6
6
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
|
7
7
|
|
8
8
|
<link href="/lookbook-assets/css/app.css?v=<%= Lookbook::VERSION %>" rel="stylesheet">
|
9
|
-
|
9
|
+
<% if config.ui_favicon != false %>
|
10
|
+
<link rel="icon" href="<%= config.ui_favicon || "data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>👀</text></svg>" %>">
|
11
|
+
<% end %>
|
10
12
|
|
11
13
|
<% if config.auto_refresh %>
|
12
14
|
<script>
|
@@ -1,10 +1,10 @@
|
|
1
1
|
<div id="drawer" class="bg-white w-full h-full flex flex-col min-w-0">
|
2
|
-
<div class="
|
3
|
-
<div class="
|
2
|
+
<div class="pl-4 border-b border-gray-300 select-none flex-none" x-show="!drawerHidden">
|
3
|
+
<div class="flex cursor-auto relative">
|
4
4
|
<div
|
5
5
|
id="inspector-tabs-<%= example.id %>"
|
6
6
|
x-data="tabs"
|
7
|
-
class="min-w-0"
|
7
|
+
class="min-w-0 -mb-px"
|
8
8
|
x-effect="$store.inspector.drawer.visibleTabCount = visibleTabCount"
|
9
9
|
>
|
10
10
|
<nav x-ref="tabs" class="flex h-10 space-x-8 flex-grow pr-8">
|
@@ -14,11 +14,11 @@
|
|
14
14
|
href="#inspector-panel-<%= key %>"
|
15
15
|
class="whitespace-nowrap pt-2.5 pb-1.5 px-1 border-b-2 cursor-pointer <%= "!text-gray-300" if props[:disabled] %>"
|
16
16
|
:class="{
|
17
|
-
'border-indigo-400':
|
18
|
-
'border-transparent text-gray-500 hover:text-gray-700': !
|
17
|
+
'border-indigo-400': isActiveDrawerPanel('<%= key %>'),
|
18
|
+
'border-transparent text-gray-500 hover:text-gray-700': !isActiveDrawerPanel('<%= key %>'),
|
19
19
|
'invisible': (<%= i %> > visibleTabCount)
|
20
20
|
}"
|
21
|
-
@click.stop.prevent="
|
21
|
+
@click.stop.prevent="switchDrawerPanel('<%= key %>')"
|
22
22
|
<% if props[:hotkey] %>data-hotkey="<%= props[:hotkey] %>"<% end %>
|
23
23
|
>
|
24
24
|
<%== props[:label] %>
|
@@ -41,14 +41,13 @@
|
|
41
41
|
<template id="inspector-dropdown-tab-<%= key %>-<%= example.id %>" x-if="<%= i %> > $store.inspector.drawer.visibleTabCount">
|
42
42
|
<div :class="{'border-t border-gray-300': (<%= i %> > $store.inspector.drawer.visibleTabCount + 1)}">
|
43
43
|
<a
|
44
|
-
|
45
44
|
href="#inspector-panel-<%= key %>"
|
46
45
|
class="block whitespace-nowrap py-2 px-4 border-l-2 cursor-pointer <%= "!text-gray-300" if props[:disabled] %>"
|
47
46
|
:class="{
|
48
|
-
'border-indigo-400': $store.inspector.drawer.
|
49
|
-
'border-transparent text-gray-500 hover:text-gray-700': $store.inspector.drawer.
|
47
|
+
'border-indigo-400': $store.inspector.drawer.panel === '<%= key %>',
|
48
|
+
'border-transparent text-gray-500 hover:text-gray-700': $store.inspector.drawer.panel !== '<%= key %>',
|
50
49
|
}"
|
51
|
-
@click.stop.prevent=" hideDropdown();
|
50
|
+
@click.stop.prevent=" hideDropdown(); switchDrawerPanel('<%= key %>')"
|
52
51
|
>
|
53
52
|
<%== props[:label] %>
|
54
53
|
</a>
|
@@ -58,31 +57,35 @@
|
|
58
57
|
</div>
|
59
58
|
</nav>
|
60
59
|
</div>
|
61
|
-
<div class="flex items-center ml-auto
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
<button
|
70
|
-
class="text-gray-400 transition"
|
71
|
-
x-data="copy('<%= "inspector-panel-#{example.id}-#{key}-clipboard" %>')"
|
72
|
-
x-tooltip.theme.lookbook="done ? 'copied!' : 'copy to clipboard'"
|
73
|
-
@click="save"
|
74
|
-
:class="{
|
75
|
-
'!text-green-600 hover:text-green-600': done,
|
76
|
-
'hover:text-indigo-500': !done}"
|
60
|
+
<div class="flex items-center bg-white border-l border-gray-200 ml-auto space-x-3 px-3">
|
61
|
+
<div>
|
62
|
+
<% panels.each do |key, props| %>
|
63
|
+
<div
|
64
|
+
ref="<%= "inspector-panel-#{example.id}-#{key}-copy" %>"
|
65
|
+
class="flex items-center"
|
66
|
+
:class="{'pointer-events-none opacity-30': <%= !props[:copy].present? %>}"
|
67
|
+
x-show="isActiveDrawerPanel('<%= key %>')"
|
77
68
|
x-cloak
|
78
|
-
<% unless props[:copy].present? %>disabled<% end %>
|
79
69
|
>
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
70
|
+
<button
|
71
|
+
data-target="<%= "inspector-panel-#{example.id}-#{key}-clipboard" %>"
|
72
|
+
class="text-gray-400 transition"
|
73
|
+
x-data="copy"
|
74
|
+
x-tooltip.theme.lookbook="done ? 'copied!' : 'copy to clipboard'"
|
75
|
+
@click="save"
|
76
|
+
:class="{
|
77
|
+
'!text-green-600 hover:text-green-600': done,
|
78
|
+
'hover:text-indigo-500': !done}"
|
79
|
+
x-cloak
|
80
|
+
<% unless props[:copy].present? %>disabled<% end %>
|
81
|
+
>
|
82
|
+
<%= icon "${done ? 'check' : 'clipboard'}", size: 4 %>
|
83
|
+
</button>
|
84
|
+
</div>
|
85
|
+
<% end %>
|
86
|
+
</div>
|
84
87
|
<button
|
85
|
-
x-tooltip.theme.lookbook="
|
88
|
+
x-tooltip.theme.lookbook="`${horizontal ? 'pin drawer on right' : 'pin drawer on bottom'}`"
|
86
89
|
@click="toggleOrientation"
|
87
90
|
:class="{'pointer-events-none opacity-30': !canBeVertical}"
|
88
91
|
>
|
@@ -91,10 +94,10 @@
|
|
91
94
|
class: "scale-[-1] text-gray-400 hover:text-indigo-800" %>
|
92
95
|
</button>
|
93
96
|
<button
|
94
|
-
x-tooltip.theme.lookbook="`
|
97
|
+
x-tooltip.theme.lookbook="`hide drawer`"
|
95
98
|
@click="toggleDrawer"
|
96
99
|
>
|
97
|
-
<%= icon "x",
|
100
|
+
<%= icon "x-circle",
|
98
101
|
size: 4,
|
99
102
|
class: "text-gray-400 hover:text-indigo-800" %>
|
100
103
|
</button>
|
@@ -105,7 +108,7 @@
|
|
105
108
|
<% panels.each do |key, props| %>
|
106
109
|
<div
|
107
110
|
class="h-full w-full absolute inset-0"
|
108
|
-
x-show="
|
111
|
+
x-show="isActiveDrawerPanel('<%= key %>')"
|
109
112
|
x-cloak
|
110
113
|
>
|
111
114
|
<div id="inspector-panel-<%= example.id %>-<%= key %>" class="h-full">
|
@@ -1,5 +1,5 @@
|
|
1
|
-
<header class="
|
2
|
-
<button class="flex-none mr-
|
1
|
+
<header class="pl-4 w-full flex-none bg-white border-b border-gray-300 flex items-center h-10 select-none min-w-0">
|
2
|
+
<button class="flex-none mr-6" x-show="!$store.layout.desktop" @click="$store.sidebar.toggle">
|
3
3
|
<svg class="feather w-5 h-5 hover:text-indigo-500 transition">
|
4
4
|
<use xlink:href="/lookbook-assets/feather-sprite.svg#menu" />
|
5
5
|
</svg>
|
@@ -6,6 +6,8 @@
|
|
6
6
|
<% end %>
|
7
7
|
<% end %>
|
8
8
|
<% else %>
|
9
|
-
<%
|
10
|
-
|
9
|
+
<% if examples.any? %>
|
10
|
+
<% example = examples.first %>
|
11
|
+
<%= component "nav_item", item: example, depth: example.hierarchy_depth, label: node.label, display: :node %>
|
12
|
+
<% end %>
|
11
13
|
<% end %>
|
@@ -1,52 +1,71 @@
|
|
1
|
-
<div id="preview" class="
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
1
|
+
<div id="preview" class="grid grid-rows-[40px_1fr]">
|
2
|
+
<%= component "header" do %>
|
3
|
+
<div
|
4
|
+
id="preview-tabs-<%= @example.id %>" class="min-w-0 -mb-px">
|
5
|
+
<nav class="flex h-10 space-x-8 flex-grow pr-8">
|
6
|
+
<% panels.each do |key, props| %>
|
7
|
+
<a
|
8
|
+
id="preview-tab-<%= key %>-<%= @example.id %>"
|
9
|
+
href="#preview-panel-<%= key %>"
|
10
|
+
class="whitespace-nowrap pt-2.5 pb-1.5 px-1 border-b-2 cursor-pointer"
|
11
|
+
:class="{
|
12
|
+
'border-indigo-400': isActivePreviewPanel('<%= key %>'),
|
13
|
+
'border-transparent text-gray-500 hover:text-gray-700': !isActivePreviewPanel('<%= key %>'),
|
14
|
+
}"
|
15
|
+
@click.stop.prevent="switchPreviewPanel('<%= key %>')"
|
16
|
+
<% if props[:hotkey] %>data-hotkey="<%= props[:hotkey] %>"<% end %>
|
17
|
+
>
|
18
|
+
<%== props[:label] %>
|
19
|
+
</a>
|
20
|
+
<% end %>
|
21
|
+
</nav>
|
22
|
+
</div>
|
23
|
+
<div class="flex items-stretch h-full ml-auto space-x-3">
|
19
24
|
<div
|
20
|
-
class="
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
<
|
25
|
-
|
26
|
-
</svg>
|
25
|
+
class="flex items-center text-xs font-monospace text-gray-700 space-x-1 opacity-50 hover:opacity-100 transition"
|
26
|
+
:class="{'opacity-100': $store.inspector.preview.resizing}"
|
27
|
+
x-show="isActivePreviewPanel('preview')">
|
28
|
+
<span x-text="`${preview.width}px`"></span>
|
29
|
+
<span class="text-gray-500">x</span>
|
30
|
+
<span x-text="`${preview.height}px`"></span>
|
27
31
|
</div>
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
32
|
+
<div class="flex items-center bg-white border-l border-gray-200 space-x-3 text-gray-400 divide-x divide-gray-300 px-3">
|
33
|
+
<div class="flex items-center space-x-3">
|
34
|
+
<button
|
35
|
+
x-tooltip.theme.lookbook="`Refresh preview`"
|
36
|
+
@click.prevent.stop="refresh"
|
37
|
+
data-hotkey="r"
|
38
|
+
>
|
39
|
+
<%= icon "refresh-cw", size: 4, class: "hover:text-indigo-800" %>
|
40
|
+
</button>
|
41
|
+
<a
|
42
|
+
href="<%= preview_path %>"
|
43
|
+
target="_blank"
|
44
|
+
x-tooltip.theme.lookbook="`Open in new window`"
|
45
|
+
data-hotkey="w"
|
46
|
+
>
|
47
|
+
<%= icon "external-link", size: 4, class: "hover:text-indigo-800" %>
|
48
|
+
</a>
|
49
|
+
<button
|
50
|
+
x-tooltip.theme.lookbook="`${drawerHidden ? 'show' : 'hide'} drawer`"
|
51
|
+
@click="toggleDrawer"
|
52
|
+
x-show="drawerHidden"
|
53
|
+
data-hotkey="i"
|
54
|
+
>
|
55
|
+
<%= icon "${horizontal ? 'credit-card' : 'sidebar'}", size: 4, class: "hover:text-indigo-800 scale-[-1]" %>
|
56
|
+
</button>
|
57
|
+
</div>
|
58
|
+
|
37
59
|
</div>
|
38
|
-
|
39
|
-
<div
|
40
|
-
class="resize-handle border-r border-b cursor-[nwse-resize]"
|
41
|
-
@pointerdown="onResizeStart"
|
42
|
-
@dblclick="toggleFullSize"
|
43
|
-
>
|
44
|
-
<svg class="h-3.5 w-3.5 pointer-events-none rotate-45 relative -top-px -left-px" fill="currentColor" viewBox="0 0 24 24" >
|
45
|
-
<path d="M8 5h2v14H8zM14 5h2v14h-2z"></path>
|
46
|
-
</svg>
|
47
|
-
</div>
|
48
|
-
|
49
60
|
</div>
|
50
|
-
|
61
|
+
<% end %>
|
62
|
+
<div class="bg-white relative flex-grow">
|
63
|
+
<% panels.each do |key, props| %>
|
64
|
+
<div class="h-full w-full absolute inset-0" x-show="isActivePreviewPanel('<%= key %>')" x-cloak>
|
65
|
+
<div id="preview-panel-<%= example.id %>-<%= key %>" class="h-full">
|
66
|
+
<%= render props[:template], key: key, examples: examples, **props %>
|
67
|
+
</div>
|
68
|
+
</div>
|
69
|
+
<% end %>
|
51
70
|
</div>
|
52
71
|
</div>
|