lookbook 0.4.8 → 0.5.0.beta.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +5 -3
  3. data/app/assets/lookbook/css/app.css +21 -13
  4. data/app/assets/lookbook/css/tooltip_theme.css +28 -0
  5. data/app/assets/lookbook/js/app.js +2 -0
  6. data/app/assets/lookbook/js/components/filter.js +1 -1
  7. data/app/assets/lookbook/js/components/inspector.js +44 -7
  8. data/app/assets/lookbook/js/components/nav-group.js +1 -1
  9. data/app/assets/lookbook/js/components/nav-item.js +1 -0
  10. data/app/assets/lookbook/js/components/nav.js +1 -1
  11. data/app/assets/lookbook/js/components/page.js +17 -5
  12. data/app/assets/lookbook/js/components/param.js +17 -3
  13. data/app/assets/lookbook/js/components/preview-window.js +95 -26
  14. data/app/assets/lookbook/js/components/tabs.js +50 -0
  15. data/app/assets/lookbook/js/config.js +9 -3
  16. data/app/assets/lookbook/js/stores/inspector.js +12 -5
  17. data/app/controllers/lookbook/app_controller.rb +3 -1
  18. data/app/views/layouts/lookbook/app.html.erb +6 -2
  19. data/app/views/lookbook/components/_copy.html.erb +7 -3
  20. data/app/views/lookbook/components/_drawer.html.erb +121 -0
  21. data/app/views/lookbook/components/_filter.html.erb +1 -1
  22. data/app/views/lookbook/components/_header.html.erb +1 -1
  23. data/app/views/lookbook/components/_nav.html.erb +1 -1
  24. data/app/views/lookbook/components/_nav_group.html.erb +11 -14
  25. data/app/views/lookbook/components/_nav_item.html.erb +17 -15
  26. data/app/views/lookbook/components/_param.html.erb +8 -4
  27. data/app/views/lookbook/components/_preview.html.erb +49 -21
  28. data/app/views/lookbook/inputs/_select.html.erb +1 -1
  29. data/app/views/lookbook/inputs/_text.html.erb +2 -1
  30. data/app/views/lookbook/inputs/_textarea.html.erb +2 -1
  31. data/app/views/lookbook/inputs/_toggle.html.erb +5 -5
  32. data/app/views/lookbook/panels/_notes.html.erb +1 -1
  33. data/app/views/lookbook/panels/_output.html.erb +1 -1
  34. data/app/views/lookbook/panels/_params.html.erb +1 -1
  35. data/app/views/lookbook/panels/_source.html.erb +1 -1
  36. data/app/views/lookbook/show.html.erb +64 -81
  37. data/lib/lookbook/code_formatter.rb +3 -3
  38. data/lib/lookbook/preview.rb +1 -1
  39. data/lib/lookbook/version.rb +1 -1
  40. data/public/lookbook-assets/css/app.css +3 -1
  41. data/public/lookbook-assets/css/app.css.map +1 -1
  42. data/public/lookbook-assets/js/app.js +1 -1
  43. data/public/lookbook-assets/js/app.js.map +1 -1
  44. metadata +6 -4
@@ -0,0 +1,121 @@
1
+ <div id="drawer" class="bg-white w-full h-full flex flex-col min-w-0">
2
+ <div class="px-4 border-b border-gray-200 select-none flex-none" x-show="!drawerHidden">
3
+ <div class="-mb-px flex cursor-auto relative">
4
+ <div
5
+ id="inspector-tabs-<%= example.id %>"
6
+ x-data="tabs"
7
+ class="min-w-0"
8
+ x-effect="$store.inspector.drawer.visibleTabCount = visibleTabCount"
9
+ >
10
+ <nav x-ref="tabs" class="flex h-10 space-x-8 flex-grow pr-8">
11
+ <% panels.each.with_index(1) do |(key,props),i| %>
12
+ <a
13
+ id="inspector-tab-<%= key %>-<%= example.id %>"
14
+ href="#inspector-panel-<%= key %>"
15
+ class="whitespace-nowrap pt-2.5 pb-1.5 px-1 border-b-2 cursor-pointer <%= "!text-gray-300" if props[:disabled] %>"
16
+ :class="{
17
+ 'border-indigo-400': isActivePanel('<%= key %>'),
18
+ 'border-transparent text-gray-500 hover:text-gray-700': !isActivePanel('<%= key %>'),
19
+ 'invisible': (<%= i %> > visibleTabCount)
20
+ }"
21
+ @click.stop.prevent="switchPanel('<%= key %>')"
22
+ <% if props[:hotkey] %>data-hotkey="<%= props[:hotkey] %>"<% end %>
23
+ >
24
+ <%== props[:label] %>
25
+ </a>
26
+ <% end %>
27
+ <div
28
+ x-ref="toggle"
29
+ x-show="visibleTabCount !== tabs.length"
30
+ class="flex-none absolute top-[9px]"
31
+ :style="`left: ${tabsWidth - 48}px`"
32
+ >
33
+ <button class="py-1 px-2 text-gray-500 hover:text-indigo-800">
34
+ <%= icon "chevrons-right", size: 3.5 %>
35
+ </button>
36
+ </div>
37
+ </nav>
38
+ <nav class="hidden">
39
+ <div x-ref="dropdown" class="min-w-[120px]">
40
+ <% panels.each.with_index(1) do |(key,props),i| %>
41
+ <template id="inspector-dropdown-tab-<%= key %>-<%= example.id %>" x-if="<%= i %> > $store.inspector.drawer.visibleTabCount">
42
+ <div :class="{'border-t border-gray-300': (<%= i %> > $store.inspector.drawer.visibleTabCount + 1)}">
43
+ <a
44
+
45
+ href="#inspector-panel-<%= key %>"
46
+ class="block whitespace-nowrap py-2 px-4 border-l-2 cursor-pointer <%= "!text-gray-300" if props[:disabled] %>"
47
+ :class="{
48
+ 'border-indigo-400': $store.inspector.drawer.active === '<%= key %>',
49
+ 'border-transparent text-gray-500 hover:text-gray-700': $store.inspector.drawer.active !== '<%= key %>',
50
+ }"
51
+ @click.stop.prevent=" hideDropdown(); switchPanel('<%= key %>')"
52
+ >
53
+ <%== props[:label] %>
54
+ </a>
55
+ </div>
56
+ </template>
57
+ <% end %>
58
+ </div>
59
+ </nav>
60
+ </div>
61
+ <div class="flex items-center ml-auto pl-8 space-x-3">
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="isActivePanel('<%= key %>')"
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}"
77
+ x-cloak
78
+ <% unless props[:copy].present? %>disabled<% end %>
79
+ >
80
+ <%= icon "${done ? 'check' : 'clipboard'}", size: 4 %>
81
+ </button>
82
+ </div>
83
+ <% end %>
84
+ <button
85
+ x-tooltip.theme.lookbook="`switch orientation`"
86
+ @click="toggleOrientation"
87
+ :class="{'pointer-events-none opacity-30': !canBeVertical}"
88
+ >
89
+ <%= icon "${horizontal ? 'sidebar' : 'credit-card'}",
90
+ size: 4,
91
+ class: "scale-[-1] text-gray-400 hover:text-indigo-800" %>
92
+ </button>
93
+ <button
94
+ x-tooltip.theme.lookbook="`close drawer`"
95
+ @click="toggleDrawer"
96
+ >
97
+ <%= icon "x",
98
+ size: 4,
99
+ class: "text-gray-400 hover:text-indigo-800" %>
100
+ </button>
101
+ </div>
102
+ </div>
103
+ </div>
104
+ <div class="bg-white relative flex-grow">
105
+ <% panels.each do |key, props| %>
106
+ <div
107
+ class="h-full w-full absolute inset-0"
108
+ x-show="$store.inspector.drawer.active === '<%= key %>'"
109
+ x-cloak
110
+ >
111
+ <div id="inspector-panel-<%= example.id %>-<%= key %>" class="h-full">
112
+ <%= render props[:template],
113
+ key: key,
114
+ examples: examples,
115
+ clipboard_id: "inspector-panel-#{example.id}-#{key}-clipboard",
116
+ **props %>
117
+ </div>
118
+ </div>
119
+ <% end %>
120
+ </div>
121
+ </div>
@@ -9,7 +9,7 @@
9
9
  @keyup.stop="checkEsc"
10
10
  @keyup.f.document="focus"
11
11
  >
12
- <button class="text-gray-400 hover:text-indigo-500 focus:ring-0 focus:outline-none absolute top-1/2 right-2 transform -translate-y-1/2" @click="clear">
12
+ <button class="text-gray-400 hover:text-indigo-500 focus:ring-0 focus:outline-none absolute top-1/2 right-2 -translate-y-1/2" @click="clear">
13
13
  <%= icon "x", size: 3, class: "hover:text-indigo-500" %>
14
14
  </button>
15
15
  </div>
@@ -1,4 +1,4 @@
1
- <header class="py-2 px-4 w-full flex-none bg-white border-b border-gray-300 flex items-center h-10 select-none">
1
+ <header class="py-2 px-4 w-full flex-none bg-white border-b border-gray-300 flex items-center h-10 select-none min-w-0">
2
2
  <button class="flex-none mr-3" 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" />
@@ -1,6 +1,6 @@
1
1
  <nav id="nav" x-data="nav" @popstate.window="setActive">
2
2
  <% if items.any? %>
3
- <ul x-ref="items" class="divide-y divide-gray-300">
3
+ <ul x-ref="items">
4
4
  <% items.each do |node| %>
5
5
  <%= component "nav_#{node.type}", node: node %>
6
6
  <% end %>
@@ -1,17 +1,14 @@
1
- <li id="nav-group-<%= node.id %>" class="<%= classes %>" x-data="navGroup" :class="{hidden}" x-cloak>
2
- <div @click="toggle" class="nav-toggle py-[5px]" style="padding-left: calc((<%= node.hierarchy_depth - 1 %> * 12px) + 0.5rem);">
3
- <%= icon "${open ? 'chevron-down' : 'chevron-right'}", size: 3, class: "mr-1 text-gray-500" %>
4
- <%= icon node.type == :preview ? "layers" : "folder", size: 3.5, class: "mr-1.5 text-indigo-500" %>
5
- <div class="nav-label <%= "font-bold" if node.type == :preview %>" <% if node.type == :preview %> @click.stop="toggle(); navigateToFirstChild()"<% end %>>
6
- <%= node.label %>
1
+ <li key="<%= node.id %>" class="<%= classes %>">
2
+ <div id="nav-group-<%= node.id %>" x-data="navGroup" :class="{hidden}" x-cloak>
3
+ <div @click="toggle" class="nav-toggle py-[5px]" style="padding-left: calc((<%= node.hierarchy_depth - 1 %> * 12px) + 0.5rem);">
4
+ <%= icon "${open ? 'chevron-down' : 'chevron-right'}", size: 3, class: "mr-1 text-gray-500" %>
5
+ <%= icon node.type == :preview ? "layers" : "folder", size: 3.5, class: "mr-1.5 text-indigo-500" %>
6
+ <div class="nav-label <%= "font-bold" if node.type == :preview %>" <% if node.type == :preview %> @click.stop="toggle(); navigateToFirstChild()"<% end %>>
7
+ <%= node.label %>
8
+ </div>
7
9
  </div>
10
+ <ul x-ref="items" x-show="open" x-cloak>
11
+ <%= yield %>
12
+ </ul>
8
13
  </div>
9
- <ul
10
- x-ref="items"
11
- x-show="open"
12
- id="nav-group-<%= node.id %>-children-<%= node.type == :preview ? node.get_examples.reject(&:hidden?).size : node.items.size %> %>"
13
- x-cloak
14
- >
15
- <%= yield %>
16
- </ul>
17
14
  </li>
@@ -3,19 +3,21 @@ path = show_path item.path
3
3
  display ||= :item
4
4
  label ||= item.label
5
5
  %>
6
- <li id="nav-item-<%= item.id %>" x-data="navItem(<%= item.matchers.to_json %>)" :class="{hidden}" data-path="<%= path %>" x-cloak>
7
- <a href="<%= path %>"
8
- class="nav-link pr-3 py-[5px] flex items-center w-full group transition hover:bg-gray-200 hover:bg-opacity-50"
9
- style="padding-left: calc((<%= depth - 1 %> * 12px) + 0.5rem);"
10
- x-ref="link"
11
- :class="{'!bg-indigo-100':active}"
12
- @click.stop.prevent="navigate"
13
- >
14
- <div class="relative w-3.5 h-3.5 mr-1.5 <%= "ml-[3px]" if display == :node %> " :class="active ? 'text-gray-900' : 'text-indigo-500'">
15
- <%= icon display == :node ? "layers" : "eye", size: 3.5, class: "group-hover:text-indigo-800" %>
16
- </div>
17
- <div class="truncate whitespace-nowrap select-none <%= "font-bold" if display == :node %>">
18
- <%= label %>
19
- </div>
20
- </a>
6
+ <li key="<%= item.id %>">
7
+ <div id="nav-item-<%= item.id %>" x-data="navItem(<%= item.matchers.to_json %>)" :class="{hidden}" data-path="<%= path %>" x-cloak>
8
+ <a href="<%= path %>"
9
+ class="nav-link pr-3 py-[5px] flex items-center w-full group transition hover:bg-gray-200 hover:bg-opacity-50"
10
+ style="padding-left: calc((<%= depth - 1 %> * 12px) + 0.5rem);"
11
+ x-ref="link"
12
+ :class="{'!bg-indigo-100':active}"
13
+ @click.stop.prevent="navigate"
14
+ >
15
+ <div class="relative w-3.5 h-3.5 mr-1.5 <%= "ml-[3px]" if display == :node %> " :class="active ? 'text-gray-900' : 'text-indigo-500'">
16
+ <%= icon display == :node ? "layers" : "eye", size: 3.5, class: "group-hover:text-indigo-800" %>
17
+ </div>
18
+ <div class="truncate whitespace-nowrap select-none <%= "font-bold" if display == :node %>">
19
+ <%= label %>
20
+ </div>
21
+ </a>
22
+ </div>
21
23
  </li>
@@ -1,10 +1,14 @@
1
+ <%
2
+ value = params.key?(param[:name]) ? params[param[:name]] : param[:default]
3
+ %>
1
4
  <div
5
+ id="<%= @example.id %>-param-<%= param[:name] %>-input"
2
6
  class="px-4 py-3"
3
- x-data="param"
4
- <% if i == 0 %>x-effect="if ($store.inspector.panels.active === 'params') setFocus()"<% end %>
7
+ x-data="param('<%= param[:name] %>', <%= value.to_json %>)"
8
+ <% if i == 0 %>x-effect="if ($store.inspector.drawer.active === 'params') setFocus()"<% end %>
5
9
  >
6
10
  <div class="flex items-start max-w-[800px]">
7
- <div class="w-[200px] flex-none py-2">
11
+ <div class="flex-none py-2" :style="`width: ${horizontal ? '200' : '120' }px`">
8
12
  <label for="param-<%= param[:name] %>" class="font-bold">
9
13
  <%= param[:name].titleize %>
10
14
  </label>
@@ -12,7 +16,7 @@
12
16
  <div class="flex-grow">
13
17
  <%= render "lookbook/inputs/#{param[:input]}",
14
18
  **param,
15
- value: params.key?(param[:name]) ? params[param[:name]] : param[:default],
19
+ value: value,
16
20
  id: "#{@example.id}-param-#{param[:name]}-input"
17
21
  %>
18
22
  </div>
@@ -1,24 +1,52 @@
1
- <div id="preview" class="h-full md:h-auto md:min-h-0 w-full bg-gray-50">
2
- <div class="relative mx-auto bg-white h-full w-full" x-data="previewWindow" :style="`width: ${$store.layout.desktop ? $store.inspector.preview.width : '100%'}`" x-show="!showSource">
3
- <iframe seamless
4
- class="absolute h-full inset-0 w-full border-l border-gray-300 md:pr-4 md:-mx-px"
5
- src="<%= url_for lookbook.preview_path %>"
6
- srcdoc="<%== srcdoc %>"
7
- frameborder="0"
8
- x-data="sizes"
9
- x-effect="preview.width = width; preview.height = height;"
10
- ></iframe>
11
- <div class="absolute opacity-0 inset-0 pointer-events-none" :class="{ 'pointer-events-none': !$store.layout.reflowing }"></div>
12
- <div
13
- class="border-l border-r border-gray-300 bg-white hover:bg-indigo-100 hover:bg-opacity-20 transition absolute right-0 inset-y-0 flex items-center w-4 cursor-[col-resize] select-none"
14
- style="touch-action: none"
15
- @pointerdown="onResizeStart"
16
- @dblclick="toggleFullWidth"
17
- x-show="$store.layout.desktop"
18
- >
19
- <svg class="h-4 w-4 text-gray-600 pointer-events-none" fill="currentColor" viewBox="0 0 24 24">
20
- <path d="M8 5h2v14H8zM14 5h2v14h-2z"></path>
21
- </svg>
1
+ <div id="preview" class="h-auto min-h-0 w-full checked-bg">
2
+ <div
3
+ class="mx-auto h-full w-full"
4
+ :style="`max-width: ${maxWidth}; max-height: ${maxHeight};`"
5
+ x-data="previewWindow"
6
+ >
7
+ <div class="grid bg-white relative grid-cols-[1fr_17px] grid-rows-[1fr_17px] -inset-px" style="width: calc(100% + 2px); height: calc(100% + 2px)">
8
+
9
+ <iframe seamless
10
+ class="h-full w-full border border-gray-300"
11
+ :class="{ 'pointer-events-none': $store.layout.reflowing }"
12
+ src="<%= url_for lookbook.preview_path %>"
13
+ <% if config.preview_srcdoc %>srcdoc="<%== srcdoc %>"<% end %>
14
+ frameborder="0"
15
+ x-data="sizes"
16
+ x-effect="preview.width = width; preview.height = height;"
17
+ ></iframe>
18
+
19
+ <div
20
+ class="resize-handle border-r border-t cursor-[col-resize]"
21
+ @pointerdown="onResizeWidthStart"
22
+ @dblclick="toggleFullWidth"
23
+ >
24
+ <svg class="h-4 w-4 pointer-events-none" fill="currentColor" viewBox="0 0 24 24">
25
+ <path d="M8 5h2v14H8zM14 5h2v14h-2z"></path>
26
+ </svg>
27
+ </div>
28
+
29
+ <div
30
+ class="resize-handle border-b border-l cursor-[col-resize]"
31
+ @pointerdown="onResizeHeightStart"
32
+ @dblclick="toggleFullHeight"
33
+ >
34
+ <svg class="h-4 w-4 pointer-events-none rotate-90" fill="currentColor" viewBox="0 0 24 24" >
35
+ <path d="M8 5h2v14H8zM14 5h2v14h-2z"></path>
36
+ </svg>
37
+ </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
+
22
49
  </div>
50
+
23
51
  </div>
24
52
  </div>
@@ -2,7 +2,7 @@
2
2
  name="<%= name %>"
3
3
  id="<%= id %>"
4
4
  class="form-input"
5
- @change.stop="update($el.name, $el.value)"
5
+ x-model="value"
6
6
  x-ref="input">
7
7
  <%= options_for_select(options, value) %>
8
8
  </select>
@@ -4,5 +4,6 @@
4
4
  type="<%= input_type %>"
5
5
  name="<%= name %>"
6
6
  value="<%= value %>"
7
- @keyup.stop.debounce.400="if (validate()) update($el.name, $el.value)"
7
+ x-model="value"
8
+ @keyup.stop
8
9
  x-ref="input">
@@ -3,6 +3,7 @@
3
3
  class="form-input"
4
4
  name="<%= name %>"
5
5
  rows="4"
6
- @keyup.stop.debounce.300="update($el.name, $el.value)"
6
+ @keyup.stop
7
+ x-model="value"
7
8
  x-ref="input"
8
9
  ><%= value %></textarea>
@@ -1,13 +1,13 @@
1
- <div id="<%= id %>" x-init="checked = <%= value == true || value == "true" ? "true" : "false" %>" x-ref="input">
1
+ <div id="<%= id %>" x-init="value = <%= value == true || value == "true" ? "true" : "false" %>" x-ref="input">
2
2
  <button type="button"
3
3
  class="relative inline-flex flex-shrink-0 h-6 w-11 border-2 border-transparent rounded-full cursor-pointer transition-colors ease-in-out duration-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-400"
4
- :class="{'bg-indigo-500': checked, 'bg-gray-300': !checked}"
4
+ :class="{'bg-indigo-500': value, 'bg-gray-300': !value}"
5
5
  role="switch"
6
- @click.stop="checked = !checked; update('<%= name %>', checked)">
6
+ @click.stop="value = !value">
7
7
  <span
8
8
  aria-hidden="true"
9
- class="pointer-events-none inline-block h-5 w-5 rounded-full bg-white shadow transform ring-0 transition ease-in-out duration-200"
10
- :class="{'translate-x-5': checked, 'translate-x-0': !checked}"
9
+ class="pointer-events-none inline-block h-5 w-5 rounded-full bg-white shadow ring-0 transition ease-in-out duration-200"
10
+ :class="{'translate-x-5': value, 'translate-x-0': !value}"
11
11
  ></span>
12
12
  </button>
13
13
  </div>
@@ -1,5 +1,5 @@
1
1
  <% items = examples.filter { |example| example[:notes].present? } %>
2
- <div class="text-gray-600 bg-gray-50 flex-grow min-h-full">
2
+ <div class="text-gray-600 bg-gray-50 h-full overflow-auto" data-morph-strategy="replace">
3
3
  <% if items.many? %>
4
4
  <div class="divide-y divide-dashed divide-gray-300">
5
5
  <% items.each do |item| %>
@@ -1,4 +1,4 @@
1
- <div class="p-4 flex-grow min-h-full">
1
+ <div class="p-4 h-full bg-gray-50 overflow-auto" data-morph-strategy="replace">
2
2
  <%= component "code" do -%>
3
3
  <% if examples.many? %>
4
4
  <% examples.each do |example| -%>
@@ -1,4 +1,4 @@
1
- <div class="bg-gray-50 flex-grow min-h-full">
1
+ <div class="bg-gray-50 h-full">
2
2
  <% if @example.type == :group %>
3
3
  <div class="p-4 prose prose-sm">
4
4
  <em class='opacity-50'>Params are not yet supported for grouped examples.</em>
@@ -1,4 +1,4 @@
1
- <div class="p-4 flex-grow min-h-full space-y-6">
1
+ <div class="p-4 h-full overflow-auto bg-gray-50 space-y-6" data-morph-strategy="replace">
2
2
  <% if examples.many? %>
3
3
  <% examples.each do |example| %>
4
4
  <%= component "code", language: example[:source_lang][:name] do -%>
@@ -1,90 +1,73 @@
1
- <div id="inspector" class="bg-gray-50 h-screen flex flex-col" x-data="inspector">
2
- <%= component "header" do %>
3
- <div class="flex items-center space-x-1" id="inspector-title-<%= @example.id %>">
4
- <strong class="whitespace-nowrap truncate"><%= @preview.label %></strong>
5
- <% if @preview.get_examples.many? %>
6
- <span>/</span>
7
- <span class="whitespace-nowrap truncate"><%= @example.label %></span>
8
- <% end %>
9
- </div>
10
- <div class="flex items-center ml-auto md:divide-x divide-gray-300">
11
- <div class="flex text-xs font-monospace text-gray-700 space-x-1" x-show="$store.layout.desktop && !showSource">
12
- <span x-text="`${preview.width}px`"></span>
13
- <span class="text-gray-500">x</span>
14
- <span x-text="`${preview.height}px`"></span>
1
+ <div
2
+ id="inspector"
3
+ class="bg-gray-50 h-screen grid"
4
+ x-data="inspector"
5
+ :style="`${horizontal ? `grid-template-rows: 1fr 1px ${drawerHidden ? '0' : $store.inspector.drawer.height}px` : `grid-template-columns: 1fr 1px ${drawerHidden ? '0' : $store.inspector.drawer.width}px` }`">
6
+ <div class="grid grid-rows-[40px_1fr]">
7
+ <%= component "header" do %>
8
+ <div class="flex items-center space-x-1 min-w-0 pr-8" id="inspector-title-<%= @example.id %>">
9
+ <strong class="whitespace-nowrap truncate"><%= @preview.label %></strong>
10
+ <% if @preview.get_examples.many? %>
11
+ <span>/</span>
12
+ <span class="whitespace-nowrap truncate"><%= @example.label %></span>
13
+ <% end %>
15
14
  </div>
16
- <div class="flex items-center ml-auto md:ml-3 md:pl-3 space-x-3 text-gray-400">
17
- <a
18
- href="<%= url_for %>"
19
- class="transition hover:text-indigo-800 flex items-center"
20
- x-tooltip.theme.lookbook="`Refresh preview`"
21
- @click.prevent.stop="refresh"
22
- data-hotkey="r"
23
- >
24
- <%= icon "refresh-cw", size: 4 %>
25
- </a>
26
- <a
27
- href="<%= preview_path %>"
28
- class="transition hover:text-indigo-800 flex items-center"
29
- target="_blank"
30
- x-tooltip.theme.lookbook="`Open in new window`"
31
- data-hotkey="w"
15
+ <div class="flex items-center ml-auto divide-x divide-gray-300 space-x-3">
16
+ <div
17
+ class="flex text-xs font-monospace text-gray-700 space-x-1 opacity-50 hover:opacity-100 transition"
18
+ :class="{'opacity-100': $store.inspector.preview.resizing}"
32
19
  >
33
- <%= icon "external-link", size: 4 %>
34
- </a>
35
- </div>
36
- </div>
37
- <% end %>
38
- <div class="md:grid flex-grow" :style="`grid-template-rows: 1fr 1px ${$store.inspector.panels.height}px`">
39
- <%= component "preview", srcdoc: @preview_srcdoc %>
40
- <div
41
- x-data="splitter('horizontal', {minSize: $store.sidebar.minWidth})"
42
- class="w-full gutter border-t border-gray-300 relative"
43
- x-effect="$store.inspector.panels.height = splits[2] || $store.inspector.panels.height"
44
- x-show="$store.layout.desktop"
45
- >
46
- <div class="h-[11px] w-full bg-transparent hover:bg-indigo-100 hover:bg-opacity-20 transition absolute left-0 right-0 transform -translate-y-1/2 cursor-[row-resize]"></div>
47
- </div>
48
- <div id="inspector-panels" class="bg-white w-full overflow-hidden flex flex-col" x-show="$store.layout.desktop">
49
- <div class="px-4 border-b border-gray-200 flex items-center flex-none select-none">
50
- <nav class="-mb-px flex space-x-6 lg:space-x-8 cursor-auto">
51
- <% @panels.each do |key, props| %>
20
+ <span x-text="`${preview.width}px`"></span>
21
+ <span class="text-gray-500">x</span>
22
+ <span x-text="`${preview.height}px`"></span>
23
+ </div>
24
+ <div class="flex items-center space-x-3 text-gray-400 divide-x divide-gray-300 pl-3">
25
+ <div class="flex items-center space-x-3">
26
+ <button
27
+ x-tooltip.theme.lookbook="`Refresh preview`"
28
+ @click.prevent.stop="refresh"
29
+ data-hotkey="r"
30
+ >
31
+ <%= icon "refresh-cw", size: 4, class: "hover:text-indigo-800" %>
32
+ </button>
52
33
  <a
53
- id="inspector-tab-<%= key %>-<%= @example.id %>"
54
- href="#inspector-panel-<%= key %>"
55
- class="whitespace-nowrap py-2 px-1 border-b-2 cursor-pointer <%= "!text-gray-300" if props[:disabled] %>"
56
- :class="{
57
- 'border-indigo-400': isActivePanel('<%= key %>'),
58
- 'border-transparent text-gray-500 hover:text-gray-700': !isActivePanel('<%= key %>')
59
- }"
60
- @click.stop.prevent="switchPanel('<%= key %>')"
61
- <% if props[:hotkey] %>data-hotkey="<%= props[:hotkey] %>"<% end %>
34
+ href="<%= preview_path %>"
35
+ target="_blank"
36
+ x-tooltip.theme.lookbook="`Open in new window`"
37
+ data-hotkey="w"
62
38
  >
63
- <%== props[:label] %>
39
+ <%= icon "external-link", size: 4, class: "hover:text-indigo-800" %>
64
40
  </a>
65
- <% end %>
66
- </nav>
67
- </div>
68
- <div class="flex-auto overflow-auto bg-white">
69
- <% @panels.each do |key, props| %>
70
- <div
71
- class="min-h-full flex flex-col"
72
- x-show="$store.inspector.panels.active === '<%= key %>'"
73
- x-cloak
74
- >
75
- <div id="inspector-panel-<%= @example.id %>-<%= key %>" class="flex flex-col flex-grow h-full relative">
76
- <% if props[:copy].present? %>
77
- <%= component "copy", target: "inspector-panel-#{@example.id}-#{key}-clipboard" %>
78
- <% end %>
79
- <%= render props[:template],
80
- key: key,
81
- examples: @examples,
82
- clipboard_id: "inspector-panel-#{@example.id}-#{key}-clipboard",
83
- **props %>
84
- </div>
85
41
  </div>
86
- <% end %>
42
+ <div class="flex items-center space-x-3 pl-3" x-show="drawerHidden">
43
+ <button
44
+ x-tooltip.theme.lookbook="`${drawerHidden ? 'show' : 'hide'} drawer`"
45
+ @click="toggleDrawer"
46
+ data-hotkey="i"
47
+ >
48
+ <%= icon "${horizontal ? 'credit-card' : 'sidebar'}", size: 4, class: "hover:text-indigo-800 scale-[-1]" %>
49
+ </button>
50
+ </div>
51
+ </div>
87
52
  </div>
88
- </div>
53
+ <% end %>
54
+ <%= component "preview", srcdoc: @preview_srcdoc %>
55
+ </div>
56
+ <div
57
+ x-data="splitter('horizontal')"
58
+ class="w-full gutter border-t border-gray-300 relative"
59
+ x-effect="$store.inspector.drawer.height = splits[2] || $store.inspector.drawer.height"
60
+ x-show="horizontal && !drawerHidden"
61
+ >
62
+ <div class="h-[11px] w-full bg-transparent hover:bg-indigo-100 hover:bg-opacity-20 transition absolute left-0 right-0 -translate-y-1/2 cursor-[row-resize]"></div>
63
+ </div>
64
+ <div
65
+ x-data="splitter('vertical', {minSize: $store.inspector.drawer.minWidth})"
66
+ class="h-full gutter border-r border-gray-300 relative"
67
+ x-effect="$store.inspector.drawer.width = splits[2] || $store.inspector.drawer.width"
68
+ x-show="vertical && !drawerHidden"
69
+ >
70
+ <div class="w-[9px] h-full bg-transparent hover:bg-indigo-100 hover:bg-opacity-20 transition absolute top-0 bottom-0 -translate-x-1/2 cursor-[col-resize] z-10"></div>
89
71
  </div>
72
+ <%= component "drawer", example: @example, examples: @examples, panels: @panels %>
90
73
  </div>
@@ -7,12 +7,12 @@ module Lookbook
7
7
  def stream(tokens, &block)
8
8
  token_lines(tokens).each_with_index do |line_tokens, i|
9
9
  yield "<div class='line'>"
10
- yield "<div class='line-number'>#{i}</div>" if @opts[:line_numbers]
11
- yield "<div class='line-content'>"
10
+ yield "<span class='line-number'>#{i}</span>" if @opts[:line_numbers]
11
+ yield "<span class='line-content'>"
12
12
  line_tokens.each do |token, value|
13
13
  yield span(token, value)
14
14
  end
15
- yield "</div>"
15
+ yield "</span>"
16
16
  yield "</div>"
17
17
  end
18
18
  end
@@ -3,7 +3,7 @@ module Lookbook
3
3
  include Taggable
4
4
 
5
5
  def id
6
- lookbook_path.tr("_", "-")
6
+ lookbook_path.tr("/", "-").tr("_", "-")
7
7
  end
8
8
 
9
9
  # Examples::FooBarComponent::Preview -> "Foo Bar"
@@ -1,3 +1,3 @@
1
1
  module Lookbook
2
- VERSION = "0.4.8"
2
+ VERSION = "0.5.0.beta.0"
3
3
  end