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.
Files changed (102) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +8 -4
  3. data/app/assets/lookbook/css/app.css +63 -5
  4. data/app/assets/lookbook/css/tooltip_theme.css +28 -0
  5. data/app/assets/lookbook/js/app.js +40 -54
  6. data/app/assets/lookbook/js/components/copy.js +16 -0
  7. data/app/assets/lookbook/js/components/filter.js +24 -0
  8. data/app/assets/lookbook/js/components/inspector.js +58 -0
  9. data/app/assets/lookbook/js/{nav/node.js → components/nav-group.js} +17 -16
  10. data/app/assets/lookbook/js/components/nav-item.js +27 -0
  11. data/app/assets/lookbook/js/components/nav.js +35 -0
  12. data/app/assets/lookbook/js/components/page.js +45 -0
  13. data/app/assets/lookbook/js/components/param.js +32 -0
  14. data/app/assets/lookbook/js/components/preview-window.js +107 -0
  15. data/app/assets/lookbook/js/components/sidebar.js +3 -0
  16. data/app/assets/lookbook/js/components/sizes.js +16 -0
  17. data/app/assets/lookbook/js/components/splitter.js +25 -0
  18. data/app/assets/lookbook/js/components/tabs.js +50 -0
  19. data/app/assets/lookbook/js/config.js +20 -0
  20. data/app/assets/lookbook/js/{utils/reloader.js → lib/socket.js} +7 -12
  21. data/app/assets/lookbook/js/lib/split.js +21 -0
  22. data/app/assets/lookbook/js/lib/utils.js +3 -0
  23. data/app/assets/lookbook/js/stores/filter.js +11 -0
  24. data/app/assets/lookbook/js/stores/inspector.js +24 -0
  25. data/app/assets/lookbook/js/stores/layout.js +12 -0
  26. data/app/assets/lookbook/js/stores/nav.js +21 -0
  27. data/app/assets/lookbook/js/stores/sidebar.js +14 -0
  28. data/app/controllers/lookbook/app_controller.rb +71 -96
  29. data/app/helpers/lookbook/application_helper.rb +48 -4
  30. data/app/views/layouts/lookbook/app.html.erb +58 -0
  31. data/app/views/layouts/lookbook/preview.html.erb +12 -0
  32. data/app/views/lookbook/components/_code.html.erb +8 -0
  33. data/app/views/lookbook/components/_copy.html.erb +14 -0
  34. data/app/views/lookbook/components/_drawer.html.erb +121 -0
  35. data/app/views/lookbook/components/_filter.html.erb +15 -0
  36. data/app/views/lookbook/{shared → components}/_header.html.erb +3 -3
  37. data/app/views/lookbook/components/_icon.html.erb +5 -0
  38. data/app/views/lookbook/components/_nav.html.erb +17 -0
  39. data/app/views/lookbook/components/_nav_collection.html.erb +5 -0
  40. data/app/views/lookbook/components/_nav_group.html.erb +14 -0
  41. data/app/views/lookbook/components/_nav_item.html.erb +23 -0
  42. data/app/views/lookbook/components/_nav_preview.html.erb +11 -0
  43. data/app/views/lookbook/components/_param.html.erb +24 -0
  44. data/app/views/lookbook/components/_preview.html.erb +52 -0
  45. data/app/views/lookbook/{app/error.html.erb → error.html.erb} +0 -0
  46. data/app/views/lookbook/index.html.erb +9 -0
  47. data/app/views/lookbook/{workbench/inspector/params → inputs}/_select.html.erb +2 -2
  48. data/app/views/lookbook/{workbench/inspector/params → inputs}/_text.html.erb +3 -2
  49. data/app/views/lookbook/inputs/_textarea.html.erb +9 -0
  50. data/app/views/lookbook/{workbench/inspector/params → inputs}/_toggle.html.erb +5 -5
  51. data/app/views/lookbook/{app/not_found.html.erb → not_found.html.erb} +2 -4
  52. data/app/views/lookbook/panels/_notes.html.erb +25 -0
  53. data/app/views/lookbook/panels/_output.html.erb +18 -0
  54. data/app/views/lookbook/panels/_params.html.erb +17 -0
  55. data/app/views/lookbook/panels/_source.html.erb +20 -0
  56. data/app/views/lookbook/show.html.erb +73 -0
  57. data/lib/lookbook/code_formatter.rb +20 -0
  58. data/lib/lookbook/engine.rb +8 -1
  59. data/lib/lookbook/lang.rb +10 -5
  60. data/lib/lookbook/preview.rb +1 -1
  61. data/lib/lookbook/preview_controller.rb +1 -1
  62. data/lib/lookbook/preview_group.rb +5 -1
  63. data/lib/lookbook/version.rb +1 -1
  64. data/lib/lookbook.rb +2 -0
  65. data/public/lookbook-assets/css/app.css +4 -0
  66. data/public/lookbook-assets/css/app.css.map +1 -0
  67. data/public/lookbook-assets/js/app.js +2 -0
  68. data/public/lookbook-assets/js/app.js.map +1 -0
  69. metadata +58 -45
  70. data/app/assets/lookbook/js/nav/leaf.js +0 -20
  71. data/app/assets/lookbook/js/nav.js +0 -38
  72. data/app/assets/lookbook/js/page.js +0 -38
  73. data/app/assets/lookbook/js/utils/clipboard.js +0 -13
  74. data/app/assets/lookbook/js/utils/morph.js +0 -19
  75. data/app/assets/lookbook/js/utils/screen.js +0 -44
  76. data/app/assets/lookbook/js/utils/size_observer.js +0 -16
  77. data/app/assets/lookbook/js/utils/split.js +0 -26
  78. data/app/assets/lookbook/js/workbench/inspector.js +0 -11
  79. data/app/assets/lookbook/js/workbench/param.js +0 -19
  80. data/app/assets/lookbook/js/workbench/preview.js +0 -39
  81. data/app/assets/lookbook/js/workbench.js +0 -14
  82. data/app/views/lookbook/app/index.html.erb +0 -11
  83. data/app/views/lookbook/app/show.html.erb +0 -1
  84. data/app/views/lookbook/layouts/app.html.erb +0 -41
  85. data/app/views/lookbook/nav/_collection.html.erb +0 -5
  86. data/app/views/lookbook/nav/_leaf.html.erb +0 -22
  87. data/app/views/lookbook/nav/_node.html.erb +0 -19
  88. data/app/views/lookbook/nav/_preview.html.erb +0 -11
  89. data/app/views/lookbook/preview/group.html.erb +0 -8
  90. data/app/views/lookbook/shared/_clipboard.html.erb +0 -11
  91. data/app/views/lookbook/shared/_sidebar.html.erb +0 -45
  92. data/app/views/lookbook/shared/_workbench.html.erb +0 -12
  93. data/app/views/lookbook/workbench/_header.html.erb +0 -39
  94. data/app/views/lookbook/workbench/_inspector.html.erb +0 -38
  95. data/app/views/lookbook/workbench/_preview.html.erb +0 -24
  96. data/app/views/lookbook/workbench/inspector/_code.html.erb +0 -3
  97. data/app/views/lookbook/workbench/inspector/_notes.html.erb +0 -24
  98. data/app/views/lookbook/workbench/inspector/_params.html.erb +0 -28
  99. data/app/views/lookbook/workbench/inspector/_plain.html.erb +0 -3
  100. data/app/views/lookbook/workbench/inspector/params/_textarea.html.erb +0 -8
  101. data/public/lookbook-assets/app.css +0 -2626
  102. data/public/lookbook-assets/app.js +0 -8718
@@ -0,0 +1,58 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en" class="h-screen">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
7
+
8
+ <link href="/lookbook-assets/css/app.css?v=<%= Lookbook::VERSION %>" rel="stylesheet">
9
+ <link rel="icon" href="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>">
10
+
11
+ <% if config.auto_refresh %>
12
+ <script>
13
+ window.SOCKET_PATH = "<%= Lookbook::Engine.websocket_mount_path %>";
14
+ </script>
15
+ <% end %>
16
+ <script src="/lookbook-assets/js/app.js?v=<%= Lookbook.version %>" defer></script>
17
+
18
+ <title><%= [@example&.label, @preview&.label, "Lookbook"].compact.join(" :: ") %></title>
19
+ </head>
20
+ <body class="text-gray-800 font-sans text-sm antialiased overflow-hidden">
21
+ <div
22
+ id="page"
23
+ x-data="page"
24
+ :style="`grid-template-columns: ${$store.sidebar.width}px 1px 1fr;`"
25
+ @popstate.window="update"
26
+ @resize.window="$store.layout.desktop = window.innerWidth >= $store.layout.desktopWidth"
27
+ class="md:grid w-screen h-screen"
28
+ >
29
+ <div class="h-full bg-gray-100 overflow-hidden flex flex-col" x-show="$store.layout.desktop || $store.sidebar.open" x-cloak>
30
+ <div class="bg-white h-10 border-b border-gray-300 flex flex-none items-center relative">
31
+ <button class="flex-none ml-4 md:hidden" @click="$store.sidebar.toggle">
32
+ <%= icon "x", size: 4, class: "hover:text-indigo-500" %>
33
+ </button>
34
+ <%= component "filter" %>
35
+ </div>
36
+ <div class="flex-grow overflow-y-auto">
37
+ <%= component "nav", items: @nav.items %>
38
+ </div>
39
+ </div>
40
+ <div
41
+ x-data="splitter('vertical', {minSize: $store.sidebar.minWidth})"
42
+ class="h-full gutter border-r border-gray-300 relative"
43
+ x-show="$store.layout.desktop"
44
+ x-effect="$store.sidebar.width = Math.min(splits[0] || $store.sidebar.width, $store.sidebar.maxWidth)"
45
+ x-cloak
46
+ >
47
+ <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>
48
+ </div>
49
+ <main
50
+ id="main"
51
+ class="h-full overflow-hidden w-full"
52
+ x-show="$store.layout.desktop || !$store.sidebar.open" x-cloak
53
+ >
54
+ <%= yield %>
55
+ </main>
56
+ </div>
57
+ </body>
58
+ </html>
@@ -0,0 +1,12 @@
1
+ <% if examples.many? %>
2
+ <% examples.each do |example| %>
3
+ <div style="all: unset; margin-bottom: 30px; display: block;">
4
+ <h6 style="all: unset; display: block; color: #999; font-family: sans-serif; font-size: 14px; margin-top: 0; margin-bottom: 10px;">
5
+ <%= example[:label] %>
6
+ </h6>
7
+ <%= example[:html] %>
8
+ </div>
9
+ <% end %>
10
+ <% else %>
11
+ <%= examples.first[:html] %>
12
+ <% end %>
@@ -0,0 +1,8 @@
1
+ <%
2
+ line_numbers ||= false
3
+ language ||= "html"
4
+ %>
5
+ <% code = capture do %><%= yield %><% end %>
6
+ <div class="code <%= "numbered" if line_numbers %> <%= classes %>">
7
+ <pre><code class="highlight"><%= highlight(code.strip, language, line_numbers: line_numbers) %></code></pre>
8
+ </div>
@@ -0,0 +1,14 @@
1
+ <button
2
+ class="text-gray-400 transition"
3
+ x-data="copy('<%= target %>')"
4
+ x-tooltip.theme.lookbook="done ? 'copied!' : 'copy to clipboard'"
5
+ @click="save"
6
+ :class="{'!text-green-600 hover:text-green-600': done, 'hover:text-indigo-500': !done}"
7
+ data-tippy-placement="left"
8
+ <% if defined?(show) %>
9
+ x-show="<%= show %>"
10
+ x-cloak
11
+ <% end %>
12
+ >
13
+ <%= icon "${done ? 'check' : 'clipboard'}", size: 4 %>
14
+ </button>
@@ -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>
@@ -0,0 +1,15 @@
1
+ <div x-data="filter" class="flex items-center w-full">
2
+ <input
3
+ type="text"
4
+ class="text-sm px-4 h-10 w-full border-0 bg-transparent focus:outline-none outline-none focus:ring-0"
5
+ placeholder="Filter previews&hellip;"
6
+ x-ref="input"
7
+ x-model="$store.filter.raw"
8
+ x-effect="if (!$store.layout.desktop && $store.sidebar.open) focus()"
9
+ @keyup.stop="checkEsc"
10
+ @keyup.f.document="focus"
11
+ >
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
+ <%= icon "x", size: 3, class: "hover:text-indigo-500" %>
14
+ </button>
15
+ </div>
@@ -1,8 +1,8 @@
1
- <header class="py-2 px-4 w-full flex-none bg-white border-b border-gray-300 flex items-center h-10">
2
- <button class="flex-none mr-3" x-show="!$screen('md')" @click="$dispatch('sidebar:toggle')">
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
+ <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" />
5
5
  </svg>
6
6
  </button>
7
7
  <%= yield %>
8
- </header>
8
+ </header>
@@ -0,0 +1,5 @@
1
+ <i class="transition block flex-none leading-none w-<%= size %> h-<%= size %> <%= classes %>">
2
+ <svg class="feather w-full h-full">
3
+ <use :href="`/lookbook-assets/feather-sprite.svg#<%= name %>`" x-cloak />
4
+ </svg>
5
+ </i>
@@ -0,0 +1,17 @@
1
+ <nav id="nav" x-data="nav" @popstate.window="setActive">
2
+ <% if items.any? %>
3
+ <ul x-ref="items">
4
+ <% items.each do |node| %>
5
+ <%= component "nav_#{node.type}", node: node %>
6
+ <% end %>
7
+ </ul>
8
+ <div class="p-4 text-center" x-show="empty" x-cloak>
9
+ <em class="text-gray-400">No matching previews found.</em>
10
+ </div>
11
+ <% else %>
12
+ <div class="p-4">
13
+ <h4 class="text-gray-500 mb-1">No previews found.</h4>
14
+ <p class="text-gray-400 text-xs">Have you set your <a class="underline" href="https://viewcomponent.org/api.html#preview_paths">preview paths</a> config correctly?</p>
15
+ </div>
16
+ <% end %>
17
+ </nav>
@@ -0,0 +1,5 @@
1
+ <%= component "nav_group", node: node do %>
2
+ <% node.items.each do |item| %>
3
+ <%= component "nav_#{item.type}", node: item %>
4
+ <% end %>
5
+ <% end %>
@@ -0,0 +1,14 @@
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>
9
+ </div>
10
+ <ul x-ref="items" x-show="open" x-cloak>
11
+ <%= yield %>
12
+ </ul>
13
+ </div>
14
+ </li>
@@ -0,0 +1,23 @@
1
+ <%
2
+ path = show_path item.path
3
+ display ||= :item
4
+ label ||= item.label
5
+ %>
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>
23
+ </li>
@@ -0,0 +1,11 @@
1
+ <% examples = node.get_examples.reject(&:hidden?) %>
2
+ <% if examples.many? %>
3
+ <%= component "nav_group", node: node, path: show_path(examples.first.path) do %>
4
+ <% examples.each do |example| %>
5
+ <%= component "nav_item", item: example, depth: example.hierarchy_depth + 1 %>
6
+ <% end %>
7
+ <% end %>
8
+ <% else %>
9
+ <% example = examples.first %>
10
+ <%= component "nav_item", item: example, depth: example.hierarchy_depth, label: node.label, display: :node %>
11
+ <% end %>
@@ -0,0 +1,24 @@
1
+ <%
2
+ value = params.key?(param[:name]) ? params[param[:name]] : param[:default]
3
+ %>
4
+ <div
5
+ id="<%= @example.id %>-param-<%= param[:name] %>-input"
6
+ class="px-4 py-3"
7
+ x-data="param('<%= param[:name] %>', <%= value.to_json %>)"
8
+ <% if i == 0 %>x-effect="if ($store.inspector.drawer.active === 'params') setFocus()"<% end %>
9
+ >
10
+ <div class="flex items-start max-w-[800px]">
11
+ <div class="flex-none py-2" :style="`width: ${horizontal ? '200' : '120' }px`">
12
+ <label for="param-<%= param[:name] %>" class="font-bold">
13
+ <%= param[:name].titleize %>
14
+ </label>
15
+ </div>
16
+ <div class="flex-grow">
17
+ <%= render "lookbook/inputs/#{param[:input]}",
18
+ **param,
19
+ value: value,
20
+ id: "#{@example.id}-param-#{param[:name]}-input"
21
+ %>
22
+ </div>
23
+ </div>
24
+ </div>
@@ -0,0 +1,52 @@
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
+
49
+ </div>
50
+
51
+ </div>
52
+ </div>
@@ -0,0 +1,9 @@
1
+ <div class="flex flex-col h-full w-full">
2
+ <%= component "header" %>
3
+ <div class="flex flex-col items-center justify-center h-full">
4
+ <div class="p-4 text-center">
5
+ <%= icon "layers", size: 10, class: "text-gray-300 mx-auto" %>
6
+ <h5 class="mt-4 text-gray-400 text-base">Select a preview to get started</h5>
7
+ </div>
8
+ </div>
9
+ </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)"
6
- data-param-input>
5
+ x-model="value"
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)"
8
- data-param-input>
7
+ x-model="value"
8
+ @keyup.stop
9
+ x-ref="input">
@@ -0,0 +1,9 @@
1
+ <textarea
2
+ id="<%= id %>"
3
+ class="form-input"
4
+ name="<%= name %>"
5
+ rows="4"
6
+ @keyup.stop
7
+ x-model="value"
8
+ x-ref="input"
9
+ ><%= value %></textarea>
@@ -1,13 +1,13 @@
1
- <div id="<%= id %>" x-init="checked = <%= value == "true" ? "true" : "false" %>" data-param-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,14 +1,12 @@
1
1
  <div class="bg-white flex flex-col items-center justify-center h-screen w-full">
2
2
  <div class="p-4 text-center">
3
- <svg class="feather w-10 h-10 text-red-300 mx-auto">
4
- <use xlink:href="/lookbook-assets/feather-sprite.svg#alert-triangle" />
5
- </svg>
3
+ <%= icon "alert-triangle", size: 10, class: "text-red-300 mx-auto" %>
6
4
  <div class="mt-3 text-gray-700 max-w-xs">
7
5
  <% if @preview %>
8
6
  <div data-role="example-not-found">
9
7
  <h5 class="text-base">Not found</h5>
10
8
  <p class="mt-2 text-gray-400 text-sm">
11
- The "<span class="text-gray-500"><%= @preview.lookbook_label %></span>" preview does not have an example named "<span class="text-gray-500"><%= @example_name %></span>".
9
+ The "<span class="text-gray-500"><%= @preview.label %></span>" preview does not have an example named "<span class="text-gray-500"><%= @example_name %></span>".
12
10
  </p>
13
11
  </div>
14
12
  <% else %>
@@ -0,0 +1,25 @@
1
+ <% items = examples.filter { |example| example[:notes].present? } %>
2
+ <div class="text-gray-600 bg-gray-50 h-full overflow-auto" data-morph-strategy="replace">
3
+ <% if items.many? %>
4
+ <div class="divide-y divide-dashed divide-gray-300">
5
+ <% items.each do |item| %>
6
+ <div class="px-4 pt-3 pb-6 relative">
7
+ <h6 class="text-[11px] text-gray-500 italic inline-block uppercase tracking-wide mb-4">
8
+ <%= item[:label] %>
9
+ </h6>
10
+ <div class="prose prose-sm">
11
+ <%= markdown(item[:notes]) %>
12
+ </div>
13
+ </div>
14
+ <% end %>
15
+ </div>
16
+ <% else %>
17
+ <div class="p-4 prose prose-sm">
18
+ <% if items.any? %>
19
+ <%= markdown(items.first[:notes]) %>
20
+ <% else %>
21
+ <em class='opacity-50'>No notes provided.</em>
22
+ <% end %>
23
+ </div>
24
+ <% end %>
25
+ </div>
@@ -0,0 +1,18 @@
1
+ <div class="p-4 h-full bg-gray-50 overflow-auto" data-morph-strategy="replace">
2
+ <%= component "code" do -%>
3
+ <% if examples.many? %>
4
+ <% examples.each do |example| -%>
5
+ <%== "\n<!-- #{example[:label]} -->\n#{beautify(example[:html])}" %>
6
+ <% end %>
7
+ <% else -%>
8
+ <%== beautify(examples.first[:html]) %>
9
+ <% end %>
10
+ <% end %>
11
+ <% if defined?(clipboard_id) %>
12
+ <template id="<%= clipboard_id %>">
13
+ <% examples.each do |example| -%>
14
+ <%== beautify(example[:html]) %>
15
+ <%- end %>
16
+ </template>
17
+ <% end %>
18
+ </div>
@@ -0,0 +1,17 @@
1
+ <div class="bg-gray-50 h-full">
2
+ <% if @example.type == :group %>
3
+ <div class="p-4 prose prose-sm">
4
+ <em class='opacity-50'>Params are not yet supported for grouped examples.</em>
5
+ </div>
6
+ <% elsif @example.params.none? %>
7
+ <div class="p-4 prose prose-sm">
8
+ <em class='opacity-50'>No params configured.</em>
9
+ </div>
10
+ <% else %>
11
+ <div class="py-3">
12
+ <% @example.params.each_with_index do |param, i| %>
13
+ <%= component "param", param: param, i: i %>
14
+ <% end %>
15
+ </div>
16
+ <% end %>
17
+ </div>
@@ -0,0 +1,20 @@
1
+ <div class="p-4 h-full overflow-auto bg-gray-50 space-y-6" data-morph-strategy="replace">
2
+ <% if examples.many? %>
3
+ <% examples.each do |example| %>
4
+ <%= component "code", language: example[:source_lang][:name] do -%>
5
+ <%== "#{sprintf example[:source_lang][:comment], example[:label]}\n#{example[:source]}" %>
6
+ <% end %>
7
+ <% end %>
8
+ <% else %>
9
+ <%= component "code", language: examples.first[:source_lang][:name] do -%>
10
+ <%== examples.first[:source] %>
11
+ <% end %>
12
+ <% end %>
13
+ <% if defined?(clipboard_id) %>
14
+ <template id="<%= clipboard_id %>">
15
+ <% examples.each do |example| -%>
16
+ <%== example[:source] %>
17
+ <%- end %>
18
+ </template>
19
+ <% end %>
20
+ </div>