lookbook 0.8.3 → 0.9.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 +38 -9
- data/app/assets/lookbook/css/app.css +1 -1
- data/app/assets/lookbook/js/app.js +2 -0
- data/app/assets/lookbook/js/components/page-tabs.js +9 -0
- data/app/controllers/lookbook/application_controller.rb +1 -1
- data/app/controllers/lookbook/pages_controller.rb +3 -1
- data/app/controllers/lookbook/previews_controller.rb +2 -2
- data/app/helpers/lookbook/application_helper.rb +1 -1
- data/app/helpers/lookbook/page_helper.rb +1 -1
- data/app/views/lookbook/components/_embed.html.erb +4 -4
- data/app/views/lookbook/components/_nav.html.erb +2 -2
- data/app/views/lookbook/components/_nav_item.html.erb +1 -1
- data/app/views/lookbook/components/_nav_page.html.erb +1 -1
- data/app/views/lookbook/components/_nav_preview.html.erb +1 -1
- data/app/views/lookbook/components/_preview.html.erb +1 -1
- data/app/views/lookbook/pages/show.html.erb +26 -0
- data/app/views/lookbook/previews/error.html.erb +1 -1
- data/app/views/lookbook/previews/panels/_preview.html.erb +1 -1
- data/config/routes.rb +5 -5
- data/lib/lookbook/page.rb +34 -8
- data/lib/lookbook/utils.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 +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 71adea21d969026f205c494f5ebdfd5b1546a8dce639733da69bf8eeaa7f371d
|
4
|
+
data.tar.gz: dbd8406a04e3b6be61a97fba2daf96ce1bb005b0c7c0f9bdfc85e7443301d7d1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4913a862f29674edaa775ed2171b37d80f32a7d57b44efea92ee2901a7a122c2bfd941fe776cbc0338de72f0ed2f63c28f108a04d699e944cf93a03456b376c1
|
7
|
+
data.tar.gz: f6f914053d0d2db782537180a6193ce24e19641407c156d46ffe48179ca4d60a4d48609b01da58318e4bb8e727ccc86356269f5e96f7746e961516291c771a8e
|
data/README.md
CHANGED
@@ -13,7 +13,7 @@
|
|
13
13
|
---
|
14
14
|
|
15
15
|
<div align="center">
|
16
|
-
<a href="#installing">Installing</a> • <a href="#previews">Previews</a> • <a href="#pages">Pages</a> • <a href="#deployment">Deployment</a> • <a href="#config">Config</a>
|
16
|
+
<a href="#installing">Installing</a> • <a href="#previews">Previews</a> • <a href="#pages">Pages</a> • <a href="#deployment">Deployment</a> • <a href="#config">Config</a>
|
17
17
|
</div>
|
18
18
|
|
19
19
|
---
|
@@ -481,10 +481,10 @@ end
|
|
481
481
|
If you need to add more long-form documentation to live alongside your component previews you can do so using Lookbook's markdown-powered `pages` system.
|
482
482
|
|
483
483
|
> ⚠️ This feature is currently flagged as an **experimental** feature which requires [feature opt-in](#experimental-features) to use. Its API and implementation may change before it is released.
|
484
|
-
>
|
484
|
+
>
|
485
485
|
> To enable support for pages in your project, add `config.lookbook.experimental_features = [:pages]` into your application configuration file.
|
486
486
|
|
487
|
-
### Pages demo
|
487
|
+
### Pages demo
|
488
488
|
|
489
489
|
For an example of some pages in Lookbook, check out the [example pages](https://lookbook-demo-app.herokuapp.com/lookbook) in the Lookbook demo app and the associated [page files](https://github.com/allmarkedup/lookbook-demo/tree/main/test/components/docs) in the demo repo.
|
490
490
|
|
@@ -496,7 +496,7 @@ Pages must have either a `.html.erb` or a `.md.erb` file extension. All pages a
|
|
496
496
|
|
497
497
|
Pages can optionally make use of a **YAML frontmatter block** to customise the behaviour and content of the page itself.
|
498
498
|
|
499
|
-
An example page might look like this:
|
499
|
+
An example page might look like this:
|
500
500
|
|
501
501
|
```markdown
|
502
502
|
---
|
@@ -510,7 +510,7 @@ contents will be run through a Markdown parser/renderer before display.
|
|
510
510
|
Fenced code blocks are fully supported and will be highlighted appropriately.
|
511
511
|
|
512
512
|
ERB can be used in here.
|
513
|
-
The template will be rendered **before** being parsed as Markdown.
|
513
|
+
The template will be rendered **before** being parsed as Markdown.
|
514
514
|
|
515
515
|
You can can access data about the page using the `@page` variable.
|
516
516
|
The title of this page is "<%= @page.title %>".
|
@@ -656,6 +656,35 @@ The default language is `ruby`. To highlight a different language you need to sp
|
|
656
656
|
|
657
657
|
> Lookbook uses [Rouge](https://github.com/rouge-ruby/rouge) for syntax highlighting. You can find a [full list of supported languages here](https://github.com/rouge-ruby/rouge/blob/master/docs/Languages.md).
|
658
658
|
|
659
|
+
### Tabs
|
660
|
+
|
661
|
+
You can break up your page's content into tabs. If your avatar page is named `01_avatar.md.erb`, by declaring a page named `01_avatar[web].md.erb` it will create a **web** tab on the page. Tabs like normal Pages can contain embedded previews and code examples.
|
662
|
+
|
663
|
+
```
|
664
|
+
test/components/docs/
|
665
|
+
├── 01_avatar.md.erb
|
666
|
+
├── 01_avatar[design].md.erb
|
667
|
+
├── 01_avatar[mobile].md.erb
|
668
|
+
├── 01_avatar[web].md.erb
|
669
|
+
```
|
670
|
+
|
671
|
+
By declaring the `label` frontmatter you can change the label shown on the tab:
|
672
|
+
|
673
|
+
```
|
674
|
+
---
|
675
|
+
label: Website
|
676
|
+
---
|
677
|
+
```
|
678
|
+
|
679
|
+
If you want the tabs in a different order, you can use the `position` frontmatter:
|
680
|
+
|
681
|
+
```
|
682
|
+
---
|
683
|
+
label: Web
|
684
|
+
position: 1
|
685
|
+
---
|
686
|
+
```
|
687
|
+
|
659
688
|
---
|
660
689
|
|
661
690
|
### Pages configuration
|
@@ -743,10 +772,10 @@ If for some reason you wish to enable file watching or runtime preview annotatio
|
|
743
772
|
# config/environments/production.rb
|
744
773
|
|
745
774
|
# enable file-change listening
|
746
|
-
config.lookbook.listen = true
|
775
|
+
config.lookbook.listen = true
|
747
776
|
|
748
777
|
# enable runtime preview parsing
|
749
|
-
config.lookbook.runtime_parsing = true
|
778
|
+
config.lookbook.runtime_parsing = true
|
750
779
|
```
|
751
780
|
|
752
781
|
<h2 id="config">General Configuration</h2>
|
@@ -778,7 +807,7 @@ config.lookbook.listen_paths << Rails.root.join('app/other/directory')
|
|
778
807
|
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:
|
779
808
|
|
780
809
|
```ruby
|
781
|
-
config.lookbook.ui_favicon = "/path/to/my/favicon.png"
|
810
|
+
config.lookbook.ui_favicon = "/path/to/my/favicon.png"
|
782
811
|
```
|
783
812
|
|
784
813
|
> To disable the favicon entirely, set the value to `false`.
|
@@ -788,7 +817,7 @@ config.lookbook.ui_favicon = "/path/to/my/favicon.png"
|
|
788
817
|
Specify a project name to display in the top left of the UI (instead of the default "Lookbook"):
|
789
818
|
|
790
819
|
```ruby
|
791
|
-
config.lookbook.project_name = "My Project"
|
820
|
+
config.lookbook.project_name = "My Project"
|
792
821
|
```
|
793
822
|
|
794
823
|
> If you don't want to display a project name at all, set the value to `false`.
|
@@ -20,6 +20,7 @@ import copy from "./components/copy";
|
|
20
20
|
import code from "./components/code";
|
21
21
|
import sizes from "./components/sizes";
|
22
22
|
import embed from "./components/embed";
|
23
|
+
import pageTabs from "./components/page-tabs";
|
23
24
|
|
24
25
|
import initFilterStore from "./stores/filter";
|
25
26
|
import initLayoutStore from "./stores/layout";
|
@@ -61,6 +62,7 @@ Alpine.data("tabs", tabs);
|
|
61
62
|
Alpine.data("navItem", navItem);
|
62
63
|
Alpine.data("navGroup", navGroup);
|
63
64
|
Alpine.data("embed", embed);
|
65
|
+
Alpine.data("pageTabs", pageTabs);
|
64
66
|
|
65
67
|
// Init
|
66
68
|
|
@@ -1,5 +1,7 @@
|
|
1
1
|
module Lookbook
|
2
2
|
class PagesController < ApplicationController
|
3
|
+
helper_method :page_controller
|
4
|
+
|
3
5
|
def self.controller_path
|
4
6
|
"lookbook/pages"
|
5
7
|
end
|
@@ -7,7 +9,7 @@ module Lookbook
|
|
7
9
|
def index
|
8
10
|
landing = Lookbook.pages.find(&:landing) || Lookbook.pages.first
|
9
11
|
if landing.present?
|
10
|
-
redirect_to
|
12
|
+
redirect_to lookbook_page_path landing.lookup_path
|
11
13
|
else
|
12
14
|
@title = "Not found"
|
13
15
|
render "not_found"
|
@@ -45,11 +45,11 @@ module Lookbook
|
|
45
45
|
if @example
|
46
46
|
@preview = @example.preview
|
47
47
|
if params[:path] == @preview&.lookup_path
|
48
|
-
redirect_to
|
48
|
+
redirect_to lookbook_inspect_path "#{params[:path]}/#{@preview.default_example.name}"
|
49
49
|
end
|
50
50
|
else
|
51
51
|
first_example = Lookbook.previews.find(params[:path])&.examples&.first
|
52
|
-
redirect_to
|
52
|
+
redirect_to lookbook_inspect_path(first_example.lookup_path) if first_example
|
53
53
|
end
|
54
54
|
end
|
55
55
|
|
@@ -1,14 +1,14 @@
|
|
1
|
-
<div id="<%= id %>" x-data="embed" class="not-prose embed border border-gray-300 rounded-md overflow-hidden" @page:morphed.window="recaclulateIframeHeight">
|
1
|
+
<div id="<%= id %>" x-data="embed" class="not-prose embed border border-gray-300 rounded-md overflow-hidden" @page:morphed.window="recaclulateIframeHeight" @tab-switch.window="recaclulateIframeHeight">
|
2
2
|
<header class="px-3 py-2 flex items-center text-xs text-gray-400 bg-white border-b border-gray-300">
|
3
3
|
<div class="text-gray-500">
|
4
4
|
<%= example.preview.label %> (<%= example.label %>)
|
5
5
|
</div>
|
6
6
|
<div class="ml-auto flex items-center space-x-3">
|
7
|
-
<a href="<%=
|
7
|
+
<a href="<%= lookbook_inspect_path(example.path, params) %>" class="" x-tooltip.theme.lookbook="`View in Inspector`">
|
8
8
|
<%= icon "eye", size: 4, class: "hover:text-indigo-800" %>
|
9
9
|
</a>
|
10
10
|
<a
|
11
|
-
href="<%=
|
11
|
+
href="<%= lookbook_preview_path(example.path, params) %>"
|
12
12
|
target="_blank"
|
13
13
|
class="-top-px relative"
|
14
14
|
x-tooltip.theme.lookbook="`Open in new window`">
|
@@ -21,7 +21,7 @@
|
|
21
21
|
<iframe seamless
|
22
22
|
id="<%= id %>-iframe"
|
23
23
|
x-ref="iframe"
|
24
|
-
src="<%=
|
24
|
+
src="<%= lookbook_preview_path(example.path, params.merge(lookbook_embed: true)) %>"
|
25
25
|
class="min-w-full h-full w-px"
|
26
26
|
:class="{ 'pointer-events-none': reflowing }"
|
27
27
|
@load="recaclulateIframeHeight">
|
@@ -1,6 +1,6 @@
|
|
1
|
-
<nav id="nav" x-data="nav(<%= filterable %>)">
|
1
|
+
<nav id="nav-<%= items.class.describe_as %>" x-data="nav(<%= filterable %>)">
|
2
2
|
<% if items.any? %>
|
3
|
-
<ul x-ref="items" id="nav-<%= items.class.describe_as
|
3
|
+
<ul x-ref="items" id="nav-<%= items.class.describe_as %>-items">
|
4
4
|
<% items.each do |item| %>
|
5
5
|
<%= component "nav_#{item.type}", node: item %>
|
6
6
|
<% end %>
|
@@ -1,6 +1,6 @@
|
|
1
1
|
<% examples = node.examples.reject(&:hidden?) %>
|
2
2
|
<% if examples.many? %>
|
3
|
-
<%= component "nav_group", node: node, path:
|
3
|
+
<%= component "nav_group", node: node, path: lookbook_inspect_path(examples.first.path) do %>
|
4
4
|
<% examples.each do |example| %>
|
5
5
|
<%= component "nav_item", item: example, depth: example.hierarchy_depth + 1 %>
|
6
6
|
<% end %>
|
@@ -43,6 +43,32 @@
|
|
43
43
|
<div id="page-main-<%= @page.id %>" data-morph-strategy="replace">
|
44
44
|
<div class="prose max-w-none prose-a:text-indigo-900">
|
45
45
|
<%= @page_content %>
|
46
|
+
|
47
|
+
<% if @page.tabs.any? %>
|
48
|
+
<div
|
49
|
+
id="page-tabs"
|
50
|
+
x-data="pageTabs"
|
51
|
+
x-init="active = '<%= @page.tabs.first.tab %>'"
|
52
|
+
class="">
|
53
|
+
<nav class="flex border-b border-gray-300">
|
54
|
+
<% @page.tabs.each do |tab| %>
|
55
|
+
<button
|
56
|
+
class="px-5 py-2 font-bold border-b-2 hover:border-gray-500"
|
57
|
+
:class="active === '<%= tab.tab %>' ? '!border-gray-500 !cursor-default' : 'border-gray-50'"
|
58
|
+
x-on:click="changeTab('<%= tab.tab %>');$dispatch('tab-switch')">
|
59
|
+
<%= tab.label %>
|
60
|
+
</button>
|
61
|
+
<% end %>
|
62
|
+
</nav>
|
63
|
+
|
64
|
+
<% @page.tabs.each do |tab| %>
|
65
|
+
<div id="tab-<%= tab.tab %>" x-show="active === '<%= tab.tab %>'">
|
66
|
+
<%= page_controller.render_page(tab) %>
|
67
|
+
</div>
|
68
|
+
<% end %>
|
69
|
+
</div>
|
70
|
+
<% end %>
|
71
|
+
|
46
72
|
</div>
|
47
73
|
</div>
|
48
74
|
<% if @page.footer? %>
|
@@ -1 +1 @@
|
|
1
|
-
<iframe id="error-iframe" src="<%= url_for
|
1
|
+
<iframe id="error-iframe" src="<%= url_for lookbook_preview_path %>" frameborder="0" class=" h-screen w-full" seamless></iframe>
|
@@ -9,7 +9,7 @@
|
|
9
9
|
<iframe seamless
|
10
10
|
class="h-full w-full border border-gray-300"
|
11
11
|
:class="{ 'pointer-events-none': $store.layout.reflowing }"
|
12
|
-
src="<%=
|
12
|
+
src="<%= lookbook_preview_path(request.query_parameters.merge(lookbook_timestamp: Time.now)) %>"
|
13
13
|
<% if config.preview_srcdoc %>srcdoc="<%== srcdoc %>"<% end %>
|
14
14
|
frameborder="0"
|
15
15
|
x-data="sizes"
|
data/config/routes.rb
CHANGED
@@ -3,13 +3,13 @@ Lookbook::Engine.routes.draw do
|
|
3
3
|
mount Lookbook::Engine.websocket => Lookbook.config.cable_mount_path
|
4
4
|
end
|
5
5
|
|
6
|
-
root to: "application#index", as: :
|
6
|
+
root to: "application#index", as: :lookbook_home
|
7
7
|
|
8
8
|
if Lookbook::Features.enabled?(:pages)
|
9
|
-
get "/#{Lookbook.config.page_route}", to: "pages#index", as: :
|
10
|
-
get "/#{Lookbook.config.page_route}/*path", to: "pages#show", as: :
|
9
|
+
get "/#{Lookbook.config.page_route}", to: "pages#index", as: :lookbook_page_index
|
10
|
+
get "/#{Lookbook.config.page_route}/*path", to: "pages#show", as: :lookbook_page
|
11
11
|
end
|
12
12
|
|
13
|
-
get "/preview/*path", to: "previews#preview", as: :
|
14
|
-
get "/*path", to: "previews#show", as: :
|
13
|
+
get "/preview/*path", to: "previews#preview", as: :lookbook_preview
|
14
|
+
get "/*path", to: "previews#show", as: :lookbook_inspect
|
15
15
|
end
|
data/lib/lookbook/page.rb
CHANGED
@@ -16,17 +16,22 @@ module Lookbook
|
|
16
16
|
]
|
17
17
|
|
18
18
|
attr_reader :errors
|
19
|
+
attr_accessor :tabs
|
19
20
|
|
20
21
|
def initialize(path, base_path)
|
21
22
|
@pathname = Pathname.new path
|
22
23
|
@base_path = Pathname.new base_path
|
23
24
|
@options = nil
|
24
25
|
@errors = []
|
26
|
+
@tabs = []
|
25
27
|
end
|
26
28
|
|
27
29
|
def path
|
28
30
|
rel_path = @pathname.relative_path_from(@base_path)
|
29
|
-
|
31
|
+
|
32
|
+
_path = (rel_path.dirname.to_s == "." ? name : "#{rel_path.dirname}/#{name}")
|
33
|
+
_path.gsub!("[#{tab}]", "") if tab?
|
34
|
+
_path
|
30
35
|
end
|
31
36
|
|
32
37
|
def lookup_path
|
@@ -78,7 +83,16 @@ module Lookbook
|
|
78
83
|
end
|
79
84
|
|
80
85
|
def type
|
81
|
-
:page
|
86
|
+
tab? ? :tab : :page
|
87
|
+
end
|
88
|
+
|
89
|
+
def tab
|
90
|
+
matches = full_path.to_s.match(%r{\[(?<tab>\w+)\]})
|
91
|
+
matches ? remove_position_prefix(matches[:tab]) : nil
|
92
|
+
end
|
93
|
+
|
94
|
+
def tab?
|
95
|
+
tab.present?
|
82
96
|
end
|
83
97
|
|
84
98
|
def method_missing(method_name, *args, &block)
|
@@ -114,7 +128,7 @@ module Lookbook
|
|
114
128
|
end
|
115
129
|
@options = Lookbook.config.page_options.deep_merge(frontmatter).with_indifferent_access
|
116
130
|
@options[:id] = @options[:id] ? generate_id(@options[:id]) : generate_id(lookup_path)
|
117
|
-
@options[:label] ||= name.titleize
|
131
|
+
@options[:label] ||= (tab? ? tab : name).titleize
|
118
132
|
@options[:title] ||= @options[:label]
|
119
133
|
@options[:hidden] ||= false
|
120
134
|
@options[:landing] ||= false
|
@@ -143,12 +157,24 @@ module Lookbook
|
|
143
157
|
end
|
144
158
|
|
145
159
|
def all
|
146
|
-
pages =
|
147
|
-
|
148
|
-
|
149
|
-
|
160
|
+
pages, tabs =
|
161
|
+
Array(page_paths).flat_map do |dir|
|
162
|
+
Dir["#{dir}/**/*.html.*", "#{dir}/**/*.md.*"].sort.map do |page|
|
163
|
+
page = Lookbook::Page.new(page, dir)
|
164
|
+
end
|
165
|
+
end.partition { |page| page.type == :page }
|
166
|
+
|
167
|
+
sorted_pages = pages
|
168
|
+
.uniq { |page| page.path }
|
169
|
+
.sort_by { |page| [page.position, page.label] }
|
170
|
+
|
171
|
+
page_dict = sorted_pages.index_by(&:path)
|
172
|
+
sorted_tabs = tabs.sort_by { |tab| [tab.position, tab.label] }
|
173
|
+
|
174
|
+
sorted_tabs.each do |tab|
|
175
|
+
page_dict[tab.path].tabs << tab
|
150
176
|
end
|
151
|
-
|
177
|
+
|
152
178
|
PageCollection.new(sorted_pages)
|
153
179
|
end
|
154
180
|
|
data/lib/lookbook/utils.rb
CHANGED
@@ -6,7 +6,7 @@ module Lookbook
|
|
6
6
|
protected
|
7
7
|
|
8
8
|
def generate_id(*args)
|
9
|
-
parts = args.map { |arg| arg.to_s.parameterize.underscore }
|
9
|
+
parts = args.map { |arg| arg.to_s.force_encoding("UTF-8").parameterize.underscore }
|
10
10
|
parts.join("-").tr("/", "-").tr("_", "-").delete_prefix("-").delete_suffix("-").gsub("--", "-")
|
11
11
|
end
|
12
12
|
|
data/lib/lookbook/version.rb
CHANGED