lookbook 1.0.0.beta.0 → 1.0.0.beta.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +84 -2
  3. data/app/assets/lookbook/js/stores/inspector.js +4 -4
  4. data/app/components/lookbook/dimensions_display/component.html.erb +2 -1
  5. data/app/components/lookbook/dimensions_display/component.js +19 -12
  6. data/app/components/lookbook/header/component.html.erb +2 -2
  7. data/app/components/lookbook/page_tabs/component.html.erb +18 -0
  8. data/app/components/lookbook/page_tabs/component.rb +19 -0
  9. data/app/components/lookbook/tab_panels/component.html.erb +5 -0
  10. data/app/components/lookbook/tab_panels/component.js +25 -0
  11. data/app/components/lookbook/tab_panels/component.rb +20 -0
  12. data/app/components/lookbook/{tabbed_content/section → tab_panels/panel}/component.html.erb +2 -2
  13. data/app/components/lookbook/tab_panels/panel/component.rb +9 -0
  14. data/app/components/lookbook/tabs/component.html.erb +8 -2
  15. data/app/components/lookbook/tabs/component.js +11 -3
  16. data/app/components/lookbook/tabs/component.rb +8 -10
  17. data/app/components/lookbook/tabs/dropdown_tab/component.html.erb +8 -2
  18. data/app/components/lookbook/tabs/dropdown_tab/component.rb +4 -3
  19. data/app/components/lookbook/tabs/tab/component.html.erb +9 -3
  20. data/app/components/lookbook/tabs/tab/component.rb +4 -3
  21. data/app/components/lookbook/toolbar/component.css +1 -1
  22. data/app/controllers/lookbook/application_controller.rb +1 -1
  23. data/app/controllers/lookbook/pages_controller.rb +1 -0
  24. data/app/controllers/lookbook/previews_controller.rb +90 -86
  25. data/app/views/lookbook/pages/show.html.erb +11 -1
  26. data/app/views/lookbook/preview.html.erb +3 -3
  27. data/app/views/lookbook/previews/panels/_content.html.erb +13 -0
  28. data/app/views/lookbook/previews/panels/_notes.html.erb +5 -5
  29. data/app/views/lookbook/previews/panels/_output.html.erb +3 -3
  30. data/app/views/lookbook/previews/panels/_params.html.erb +2 -2
  31. data/app/views/lookbook/previews/panels/_preview.html.erb +1 -1
  32. data/app/views/lookbook/previews/panels/_source.html.erb +6 -6
  33. data/app/views/lookbook/previews/show.html.erb +38 -35
  34. data/lib/lookbook/config.rb +87 -32
  35. data/lib/lookbook/page.rb +31 -8
  36. data/lib/lookbook/page_section.rb +31 -0
  37. data/lib/lookbook/store.rb +36 -0
  38. data/lib/lookbook/theme.rb +7 -0
  39. data/lib/lookbook/utils.rb +1 -1
  40. data/lib/lookbook/version.rb +1 -1
  41. data/lib/lookbook.rb +2 -0
  42. data/public/lookbook-assets/css/lookbook.css +34 -5
  43. data/public/lookbook-assets/css/lookbook.css.map +1 -1
  44. data/public/lookbook-assets/js/lookbook.js +36 -24
  45. data/public/lookbook-assets/js/lookbook.js.map +1 -1
  46. metadata +12 -7
  47. data/app/components/lookbook/tabbed_content/component.html.erb +0 -5
  48. data/app/components/lookbook/tabbed_content/component.js +0 -21
  49. data/app/components/lookbook/tabbed_content/component.rb +0 -20
  50. data/app/components/lookbook/tabbed_content/section/component.rb +0 -9
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: aeef273a433c57159752664a6897e4fb17e1836fa7581db64446ee1674cbcd72
4
- data.tar.gz: 74411f7b3b81d3a442772d1c1dd2ba46f3af684248f96aafd445014278b73b2e
3
+ metadata.gz: 5efc30f722f9fff6377285d5b4e06a5f62e20e0a202eb19966ab6a7701999db2
4
+ data.tar.gz: 4987e68865cf8ddfdc68838bfc1497c71118898c0607d0c5dd9701ccc754d406
5
5
  SHA512:
6
- metadata.gz: b722bd45d02ce7588a1babfe7b6920c30b42a6c7f4517da03c9faaec4777766fff6eee11c9280758a294b30340a2e9526ed4f35f5459f54eb675a427fff8f943
7
- data.tar.gz: 17997ac9bfebed9c4f56999dbdc8ddbc13b9a47acab70137113b1cdf12d69fff3c40c466cb5412eed2878c7bd99363cdcafea3718af2c28f59afce161d34c3db
6
+ metadata.gz: 27b85921801c7e88510e69ae88a0b6b093f9da9252910130b5ee7edbc89ecb9149a8b7d0a6c60b6993904e73448e64150a2756a936eeb1e3f61a4ab7d2acc40b
7
+ data.tar.gz: 68d236bd6baba5c456cc090cd2faed45ef02300ba2d0913eae9d2087b0572d140653df035a65a28d29baf435459f67ea86aa1cb7142634c5154324540ac56e1f
data/README.md CHANGED
@@ -17,7 +17,11 @@ The main goals of the v1.0 release are:
17
17
 
18
18
  **No breaking changes** are planned for user-facing features, although the app UI will include some minor visual updates and usability improvements.
19
19
 
20
- ![Lookbook UI](.github/assets/lookbook_screenshot_v1.0_beta.png)
20
+ ## Demo app
21
+
22
+ There is a demo of the current v1.0-beta here: https://lookbook-demo-app-v1-0-beta.herokuapp.com/lookbook/
23
+
24
+ [![Lookbook UI](.github/assets/lookbook_screenshot_v1.0_beta.png)](https://lookbook-demo-app-v1-0-beta.herokuapp.com/lookbook/)
21
25
 
22
26
  ## 👋 Testing and feedback - help wanted!
23
27
 
@@ -30,10 +34,14 @@ The bulk of the v1.0 'new feature' development work is now mostly complete, alth
30
34
  - Existing Lookbook setups should continue to work **with no changes required**
31
35
  - There have been a number of small UI changes - do any of them negatively affect your experience of using Lookbook?
32
36
  - The Pages feature should work without opting in to any experimental features.
33
- - It's now possible to pick from one of a small set of pre-defined UI themes (finer-grained customisation coming soon!). See below for details. Any thoughts on this?
37
+ - It's now possible to pick from one of a small set of pre-defined UI themes (finer-grained customisation coming soon!). [See below](#ui-theming) for details. Any thoughts on this?
34
38
 
35
39
  > However absolutely any thoughts, comments or bug reports (even if unrelated to the specific areas above) would be much appreciated!
36
40
 
41
+ ## New features
42
+
43
+ There are a number of new features that are planned for inclusion in the v1.0 release. They are:
44
+
37
45
  ### UI theming
38
46
 
39
47
  Lookbook now ships with a small set of pre-defined UI themes, which can be set using the `ui_theme` config option:
@@ -51,6 +59,80 @@ Currently available themes are:
51
59
 
52
60
  > More themes and finer-grained customisation of theme colours is coming soon!
53
61
 
62
+ ### Inspector panels customisation
63
+
64
+ It is now possible to add, remove or customise tabbed panels in the preview inspector by editing the `lookbook.inspector_panels` configuration option.
65
+
66
+ By default Lookbook comes with **five** panels split between two resizable panes:
67
+
68
+ 1. The `main` pane - by default includes the `preview` and `output` (HTML) panels
69
+ 2. The `drawer` pane - by default includes the `source`, `notes` and `params` panels
70
+
71
+ These can be hidden, moved, reordered and/or added to as your project requires.
72
+
73
+ #### Panel config overview
74
+
75
+ Panels are defined as a hash with the following properties (all of which are actually optional):
76
+
77
+ ```ruby
78
+ {
79
+ label: "New Panel",
80
+ pane: :drawer,
81
+ position: 1,
82
+ partial: "path/to/view_partial",
83
+ content: "Some **markdown** content",
84
+ hotkey: "ctrl.n",
85
+ disabled: false,
86
+ show: true,
87
+ copy: "Content to be copied",
88
+ }
89
+ ```
90
+
91
+ * `label`: the text to be displayed in the tab
92
+ * `pane`: the panel location, either `:drawer` or `:main` (`:drawer` is the default)
93
+ * `position`: used for ordering the tabs
94
+ * `partial`: the path to the view template partial used to render the panel
95
+ * `content`: the default partial renders and displays the contents of this (markdown supported)
96
+ * `hotkey`: [keyboard shortcut](https://alpinejs.dev/directives/on#keyboard-events) to make panel become the active tab
97
+ * `disabled`: `true` or `false` - disabled tabs are still accessible but are greyed out in the UI
98
+ * `show`: `true` or `false` - whether or not to display the tab/panel
99
+ * `copy`: if present, the panel will display a copy button that copies the value of this property to the clipboard when clicked
100
+ * `locals`: a `Hash` of local variables that will be made available to the partial when rendering the panel
101
+
102
+ All panel config values can be provided either as a **simple static value** or as a **lambda function** which will receive a hash of data relating to the current preview/example. For example:
103
+
104
+ ```ruby
105
+ {
106
+ label: "Params",
107
+ disabled: ->(data) { data.preview.params.none? } # grey out the Params tab if no params are set for the current preview
108
+ }
109
+ ```
110
+
111
+ > **Work in progress!** There is more documentation to come on the data hash passed to lambdas.
112
+
113
+ #### Removing panels
114
+
115
+ To remove a pane entirely from the UI, just set it's value to false in your `application.rb` (or wherever you do your configuration):
116
+
117
+ ```ruby
118
+ config.lookbook.inspector_panels.notes = false # remove the notes panel
119
+ ```
120
+
121
+ #### Customising existing panels
122
+
123
+ Existing panel configuration can be amended as needed. For example, to change the label on one of the default panels:
124
+
125
+ ```ruby
126
+ config.lookbook.inspector_panels.notes.label = "Instructions"
127
+
128
+ # or use block-style config
129
+ config.lookbook.inspector_panels do |panels|
130
+ panels.notes.label = "Instructions"
131
+ end
132
+ ```
133
+
134
+
135
+
54
136
 
55
137
  ## 🛠 Workbench
56
138
 
@@ -4,15 +4,15 @@ export default function initInspectorStore(Alpine, { prefix }) {
4
4
  return {
5
5
  minVerticalSplitWidth: 800,
6
6
 
7
- preview: {
7
+ main: {
8
8
  activeTab: Alpine.$persist("").as(
9
- prefixString("inspector-preview-active-tab", prefix)
9
+ prefixString("inspector-main-active-tab", prefix)
10
10
  ),
11
11
  width: Alpine.$persist("100%").as(
12
- prefixString("inspector-preview-width", prefix)
12
+ prefixString("inspector-main-width", prefix)
13
13
  ),
14
14
  height: Alpine.$persist("100%").as(
15
- prefixString("inspector-preview-height", prefix)
15
+ prefixString("inspector-main-height", prefix)
16
16
  ),
17
17
  lastWidth: null,
18
18
  lastHeight: null,
@@ -3,7 +3,8 @@
3
3
  "@viewport:resize-start.window": "resizing = true",
4
4
  "@viewport:resize-complete.window": "resizing = false",
5
5
  "@dom:update-start.window": "tearDown",
6
- "@dom:update-complete.window": "createObserver" do %>
6
+ "@dom:update-complete.window": "createObserver",
7
+ "x-show": "target" do %>
7
8
  <span x-text="`${width}px`"></span>
8
9
  <span class="opacity-70">x</span>
9
10
  <span x-text="`${height}px`"></span>
@@ -5,26 +5,33 @@ export default function dimensionsDisplayComponent(targetSelector) {
5
5
  width: 0,
6
6
  height: 0,
7
7
  resizing: false,
8
+ target: null,
8
9
 
9
10
  init() {
10
- const target = document.querySelector(targetSelector);
11
- this.width = Math.round(target.clientWidth);
12
- this.height = Math.round(target.clientHeight);
13
- this.createObserver();
11
+ this.target = document.querySelector(targetSelector);
12
+ if (this.target) {
13
+ this.width = Math.round(this.target.clientWidth);
14
+ this.height = Math.round(this.target.clientHeight);
15
+ this.createObserver();
16
+ }
14
17
  },
15
18
 
16
19
  createObserver() {
17
- this.observer = observeSize(
18
- document.querySelector(targetSelector),
19
- ({ width, height }) => {
20
- this.width = width;
21
- this.height = height;
22
- }
23
- );
20
+ if (this.target) {
21
+ this.observer = observeSize(
22
+ document.querySelector(targetSelector),
23
+ ({ width, height }) => {
24
+ this.width = width;
25
+ this.height = height;
26
+ }
27
+ );
28
+ }
24
29
  },
25
30
 
26
31
  tearDown() {
27
- this.observer.disconnect();
32
+ if (this.observer) {
33
+ this.observer.disconnect();
34
+ }
28
35
  },
29
36
  };
30
37
  }
@@ -51,9 +51,9 @@
51
51
  <span class="opacity-70 mr-1">Lookbook</span>
52
52
  <span class="mr-6">v<%= Lookbook::VERSION %></span>
53
53
  <div class="flex items-center space-x-2">
54
- <a href="https://github.com/allmarkedup/lookbook" target="_blank" class="ml-auto opacity-70" title="Documentation">
54
+ <!-- a href="https://github.com/allmarkedup/lookbook" target="_blank" class="ml-auto opacity-70" title="Documentation">
55
55
  <%= render_component :icon, name: :book, size: 3 %>
56
- </a>
56
+ </a -->
57
57
  <a href="https://github.com/allmarkedup/lookbook" target="_blank" class="ml-auto opacity-70" title="Github">
58
58
  <%= render_component :icon, name: :github, size: 3 %>
59
59
  </a>
@@ -0,0 +1,18 @@
1
+ <%= render_component_tag x_data: "{ activeTab: null }" do %>
2
+ <div class="flex w-full border-b border-lookbook-divider mb-6">
3
+ <%= render_component :tabs, theme: :page do |t| %>
4
+ <% @tabs.each do |props| %>
5
+ <%= t.tab **props %>
6
+ <% end %>
7
+ <% end %>
8
+ </div>
9
+ <%= render_component :tab_panels do |t| %>
10
+ <% @tabs.each do |props| %>
11
+ <% t.panel name: props[:name] do %>
12
+ <%= render_component :prose, markdown: props[:markdown], class: "max-w-none flex-none" do %>
13
+ <%== props[:content] %>
14
+ <% end %>
15
+ <% end %>
16
+ <% end %>
17
+ <% end %>
18
+ <% end %>
@@ -0,0 +1,19 @@
1
+ module Lookbook
2
+ class PageTabs::Component < Lookbook::Component
3
+ renders_many :tabs, ->(**attrs, &block) do
4
+ @tabs ||= []
5
+ attrs[:content] = capture(&block)
6
+ attrs[:markdown] ||= @markdown
7
+ @tabs << attrs
8
+ end
9
+
10
+ def initialize(markdown: true, **html_attrs)
11
+ @markdown = markdown
12
+ super(**html_attrs)
13
+ end
14
+
15
+ def before_render
16
+ tabs.size
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,5 @@
1
+ <%= render_component_tag class: "h-full" do %>
2
+ <div x-ref="panels" class="h-full">
3
+ <%= safe_join(panels) %>
4
+ </div>
5
+ <% end %>
@@ -0,0 +1,25 @@
1
+ export default function tabPanelsComponent(store) {
2
+ return {
3
+ get store() {
4
+ return store || this;
5
+ },
6
+
7
+ get id() {
8
+ return this.$root.id;
9
+ },
10
+
11
+ get panels() {
12
+ return Array.from(this.$refs.panels.children);
13
+ },
14
+
15
+ isActive(el) {
16
+ return this.store.activeTab === this._getRef(el);
17
+ },
18
+
19
+ // protected
20
+
21
+ _getRef(el) {
22
+ return el.getAttribute("x-ref");
23
+ },
24
+ };
25
+ }
@@ -0,0 +1,20 @@
1
+ module Lookbook
2
+ class TabPanels::Component < Lookbook::Component
3
+ renders_many :panels, ->(**attrs) do
4
+ @panel_counter += 1
5
+ attrs[:name] ||= "tab-#{@panel_counter}"
6
+ Lookbook::TabPanels::Panel::Component.new **attrs
7
+ end
8
+
9
+ def initialize(**html_attrs)
10
+ @panel_counter = 0
11
+ super(**html_attrs)
12
+ end
13
+
14
+ protected
15
+
16
+ def alpine_component
17
+ "tabPanelsComponent"
18
+ end
19
+ end
20
+ end
@@ -1,8 +1,8 @@
1
1
  <%= render_component_tag :section,
2
2
  id: @id,
3
- x_ref: @ref,
3
+ x_ref: @name,
4
4
  x_cloak: true,
5
5
  class: "h-full",
6
6
  ":class": "{ hidden: !isActive($el) }" do %>
7
- <%= content %>
7
+ <%== content %>
8
8
  <% end %>
@@ -0,0 +1,9 @@
1
+ module Lookbook
2
+ class TabPanels::Panel::Component < Lookbook::Component
3
+ def initialize(name:, id: nil, **html_attrs)
4
+ @name = name
5
+ @id = id || name
6
+ super(**html_attrs)
7
+ end
8
+ end
9
+ end
@@ -1,5 +1,11 @@
1
- <%= render_component_tag class: "px-4 flex items-center relative" do %>
2
- <div x-ref="tabs" class="flex items-stretch h-10 space-x-6 select-none min-w-0">
1
+ <%= render_component_tag class: "flex items-center relative" do %>
2
+ <div x-ref="tabs" class="<%= class_names [
3
+ "flex items-stretch select-none min-w-0",
4
+ {
5
+ "h-10 space-x-6": @theme == :toolbar,
6
+ "space-x-3": @theme == :page,
7
+ }
8
+ ] %>">
3
9
  <%= safe_join(tabs) %>
4
10
  </div>
5
11
  <div x-ref="dropdownTrigger" class="absolute" x-show="hasHiddenTabs" :style="{left: `${triggerLeft}px`}">
@@ -4,13 +4,17 @@ import { observeSize } from "@helpers/layout";
4
4
  import { getElementSize } from "@helpers/dom";
5
5
 
6
6
  export default function tabsComponent(store) {
7
- const initial = store.activeTab || null;
7
+ const initial = store ? store.activeTab : null;
8
8
  let dropdown = null;
9
9
  return {
10
10
  visibleTabsCount: 0,
11
11
 
12
12
  triggerLeft: 0,
13
13
 
14
+ get store() {
15
+ return store || this;
16
+ },
17
+
14
18
  get tabs() {
15
19
  return Array.from(this.$refs.tabs.children);
16
20
  },
@@ -34,6 +38,7 @@ export default function tabsComponent(store) {
34
38
  theme: "menu",
35
39
  interactive: true,
36
40
  trigger: "click",
41
+ placement: "bottom",
37
42
  appendTo: this.$root,
38
43
  });
39
44
 
@@ -59,10 +64,13 @@ export default function tabsComponent(store) {
59
64
  }
60
65
 
61
66
  if (width === this.$root.offsetWidth) {
67
+ console.log("uep");
62
68
  this.visibleTabsCount = this.tabs.length;
63
69
  return;
64
70
  }
65
71
 
72
+ console.log(width);
73
+
66
74
  let sumTabWidths = 60;
67
75
  let triggerLeft = 20;
68
76
  let visibleTabsCount = 0;
@@ -80,12 +88,12 @@ export default function tabsComponent(store) {
80
88
  },
81
89
 
82
90
  selectTab(el) {
83
- store.activeTab = this._getRef(el);
91
+ this.store.activeTab = this._getRef(el);
84
92
  dropdown.hide();
85
93
  },
86
94
 
87
95
  isSelected(el) {
88
- return store.activeTab === this._getRef(el);
96
+ return this.store.activeTab === this._getRef(el);
89
97
  },
90
98
 
91
99
  isDisabled(el) {
@@ -1,22 +1,20 @@
1
1
  module Lookbook
2
2
  class Tabs::Component < Lookbook::Component
3
- renders_many :tabs, ->(ref: nil, **attrs) do
3
+ renders_many :tabs, ->(**attrs) do
4
4
  @tab_counter += 1
5
- ref ||= "tab-#{@tab_counter}"
6
- attrs = {
7
- ref: ref,
8
- position: @tab_counter,
9
- **attrs
10
- }
5
+ attrs[:name] ||= "tab-#{@tab_counter}"
6
+ attrs[:position] ||= @tab_counter
7
+ attrs[:theme] ||= @theme
11
8
  dropdown_tab(**attrs)
12
9
  Lookbook::Tabs::Tab::Component.new(**attrs)
13
10
  end
14
11
 
15
- renders_many :dropdown_tabs, ->(ref:, **attrs) do
16
- Lookbook::Tabs::DropdownTab::Component.new(ref: "dropdown-#{ref}", **attrs)
12
+ renders_many :dropdown_tabs, ->(name:, **attrs) do
13
+ Lookbook::Tabs::DropdownTab::Component.new(name: "dropdown-#{name}", **attrs)
17
14
  end
18
15
 
19
- def initialize(**html_attrs)
16
+ def initialize(theme: :toolbar, **html_attrs)
17
+ @theme = theme
20
18
  @tab_counter = 0
21
19
  super(**html_attrs)
22
20
  end
@@ -1,6 +1,12 @@
1
1
  <%= render_component_tag :button,
2
- x_ref: @ref,
3
- class: "whitespace-nowrap px-4 py-2 border-l-2 cursor-pointer block w-full text-left",
2
+ x_ref: @name,
3
+ class: [
4
+ "whitespace-nowrap px-4 border-l-2 cursor-pointer block w-full text-left",
5
+ {
6
+ "py-2": @theme == :toolbar,
7
+ "py-2 text-base": @theme == :page,
8
+ }
9
+ ],
4
10
  ":class": "{
5
11
  'border-lookbook-tabs-highlight': isSelected($el),
6
12
  'border-transparent text-lookbook-tabs-text hover:text-lookbook-tabs-text-hover': !isSelected($el),
@@ -1,16 +1,17 @@
1
1
  module Lookbook
2
2
  class Tabs::DropdownTab::Component < Lookbook::Component
3
- def initialize(ref:, label: nil, hotkey: nil, disabled: nil, position: 0, **html_attrs)
4
- @ref = ref
3
+ def initialize(name:, label: nil, hotkey: nil, disabled: nil, position: 0, theme: :toolbar, **html_attrs)
4
+ @name = name
5
5
  @label = label
6
6
  @hotkey = hotkey
7
7
  @disabled = disabled
8
8
  @position = position
9
+ @theme = theme
9
10
  super(**html_attrs)
10
11
  end
11
12
 
12
13
  def label
13
- @label.presence || content
14
+ @label.presence || content || @name.titleize
14
15
  end
15
16
  end
16
17
  end
@@ -1,7 +1,13 @@
1
1
  <%= render_component_tag :button,
2
2
  id: @id,
3
- x_ref: @ref,
4
- class: "whitespace-nowrap pt-2.5 pb-1.5 px-1 border-b-2 cursor-pointer",
3
+ x_ref: @name,
4
+ class: [
5
+ "whitespace-nowrap cursor-pointer pt-2.5 pb-1.5 border-b-2",
6
+ {
7
+ "px-1": @theme == :toolbar,
8
+ "px-2 text-lg relative -bottom-px": @theme == :page,
9
+ }
10
+ ],
5
11
  ":class": "{
6
12
  'border-lookbook-tabs-highlight': isSelected($el),
7
13
  'border-transparent text-lookbook-tabs-text hover:text-lookbook-tabs-text-hover': !isSelected($el),
@@ -14,5 +20,5 @@
14
20
  disabled: @disabled
15
21
  },
16
22
  cloak: true do %>
17
- <%= label %>
23
+ <%== label %>
18
24
  <% end %>
@@ -1,16 +1,17 @@
1
1
  module Lookbook
2
2
  class Tabs::Tab::Component < Lookbook::Component
3
- def initialize(ref:, label: nil, hotkey: nil, disabled: nil, position: 0, **html_attrs)
4
- @ref = ref
3
+ def initialize(name:, label: nil, hotkey: nil, disabled: nil, position: 0, theme: :toolbar, **html_attrs)
4
+ @name = name
5
5
  @label = label
6
6
  @hotkey = hotkey
7
7
  @disabled = disabled
8
8
  @position = position
9
+ @theme = theme
9
10
  super(**html_attrs)
10
11
  end
11
12
 
12
13
  def label
13
- @label.presence || content
14
+ @label.presence || content || @name.titleize
14
15
  end
15
16
  end
16
17
  end
@@ -10,7 +10,7 @@
10
10
  }
11
11
 
12
12
  & [data-component="tabs"] {
13
- @apply relative -mb-px;
13
+ @apply relative -mb-px px-4;
14
14
  }
15
15
  }
16
16
  }
@@ -24,7 +24,7 @@ module Lookbook
24
24
  protected
25
25
 
26
26
  def generate_theme_overrides
27
- @theme_overrides = Lookbook::Theme.new(Lookbook.config.ui_theme_overrides).to_css
27
+ @theme_overrides ||= Lookbook::Theme.new(Lookbook.config.ui_theme_overrides).to_css
28
28
  end
29
29
 
30
30
  def feature_enabled?(feature)
@@ -1,6 +1,7 @@
1
1
  module Lookbook
2
2
  class PagesController < ApplicationController
3
3
  layout "lookbook/page"
4
+ helper_method :page_controller
4
5
 
5
6
  def self.controller_path
6
7
  "lookbook/pages"