Lookbook
👀 A native development UI for [ViewComponent](http://viewcomponent.org/) 👀
---
Lookbook gives [ViewComponent](http://viewcomponent.org/)-based projects a _ready-to-go_ development UI for navigating, inspecting and interacting with component previews.
It uses (and extends) the native [ViewComponent preview functionality](https://viewcomponent.org/guide/previews.html), so you don't need to learn a new DSL or create any extra files to get up and running.
Lookbook uses [RDoc/Yard-style comment tags](https://rubydoc.info/gems/yard/file/docs/Tags.md) to extend the capabilities of ViewComponent's previews whilst maintaining compatability with the standard preview class format, so you can add or remove Lookbook at any time without having to rework your code.
![Lookbook UI](.github/assets/lookbook_screenshot.png)
### Features
- Tree-style navigation menu
- Live nav search/filter
- Resizable preview window for responsive testing
- Highlighted preview source code and HTML output
- Add notes via comments in the preview file (markdown supported)
- Auto-updating UI when component or preview files are updated
- Supports 'hidden' previews and examples
- Works with standard the ViewComponent preview system
## Lookbook demo
If you want to have a quick play with Lookbook, the easiest way is to [give the demo app](https://github.com/allmarkedup/lookbook-demo) a spin. It's a basic Rails/ViewComponent app with a few test components included to tinker with.
The [demo app repo](https://github.com/allmarkedup/lookbook-demo) contains instructions on how to get it up and running.
## Installing
> ⚠️ **Please note:** Lookbook is still in the early stages of development and has not yet been well tested across a wide range of Rails/ViewComponent versions and setups. If you run into any problems please [open an issue](issues) with as much detail as possible. Thanks! ⚠️
### 1. Add as a dependency
In your `Gemfile` add:
```ruby
gem "lookbook"
```
or
```bash
gem install lookbook
```
### 2. Mount the Lookbook engine
You then need to mount the Lookbook engine (at a path of your choosing) in your `routes.rb` file:
```ruby
Rails.application.routes.draw do
if Rails.env.development?
mount Lookbook::Engine, at: "/lookbook"
end
end
```
The `at` property determines the root URL that the Lookbook UI will be served at.
> If you would like to expose the Lookbook UI in production as well as in development, just remove the `if Rails.env.development?` condition from around the mount statement.
Then you can start your app as normal and navigate to `http://localhost:3000/lookbook` (or whatever mount path you specified) to view your component previews in the Lookbook UI.
## Usage
You don't need to do anything special to create ViewComponent previews for Lookbook.
Lookbook will use the [ViewComponent configuration options](https://viewcomponent.org/api.html#configuration) for your project to find and render your components so you don't need to configure anything separately (unless you want to tweak the behaviour or look of Lookbook itself, of course).
> If you are new to ViewComponent development, checkout the [ViewComponent docs](https://viewcomponent.org/guide/) on how to get started developing your components and creating previews.
Lookbook uses the exact same [preview files](https://viewcomponent.org/guide/previews.html) as 'regular' ViewComponent previews, so using preview templates, custom layouts and even bespoke [preview controllers](https://viewcomponent.org/guide/previews.html#configuring-preview-controller) all works as you would expect.
### Comment tags
Lookbook uses [Yard-style tags](https://rubydoc.info/gems/yard/file/docs/Tags.md) in class and method comments to extract additional information about previews and examples.
Tags are just strings identified by their `@` prefix - for example `@hidden`. Tags are always placed in a comment above the relevant preview class or example method. The comments can still contain any other text, and multiple tags can be included in any one comment. For example:
```ruby
# This is a class-level comment.
# @hidden
class MyClass
# This is a method-level comment.
# @hidden
def my_method
end
end
```
Some tags can also require additional arguments. Further information on the tags Lookbook uses are detailed in the docs below.
### 📝 Adding notes to previews
Lookbook lets you add notes to your preview examples which are then displayed in the inspector panel. They look something like this:
Notes are generated from comments above example methods in your preview files. Below is an example of two preview examples that both have notes:
```ruby
class ButtonComponentPreview < ViewComponent::Preview
# Add notes as comments above the example methods.
# Multi-line is just fine and **markdown** is supported too!
#
# It's a good place to put usage and implementation instructions
# for people browsing the component previews in the UI.
def default
render ButtonComponent.new(text: "Click me")
end
# Each preview example has it's own notes, extracted from the method comments.
def danger
render ButtonComponent.new(text: "Don't do it!", theme: :danger)
end
end
```
### 👀 Navigation customisation
Lookbook generates a nested navigation menu based on the file structure of your component preview directory (or directories). This can be customised in a number of ways.
#### Preview and example labels
By default, the labels shown for previews and examples are stripped and 'titlized' versions of the preview file names and the example method names, respectively.
If you wish to override the automatic navigation label generation for a preview or example you can use the `@label` comment tag:
```ruby
# @label Standard Button
class BtnPreview < ViewComponent::Preview
# @label Icon Button
def with_icon
end
end
```
In the example above, the preview and example would be displayed like this:
#### Excluding previews and/or examples from the navigation
Sometimes you may want to temporarily hide a preview or an individual example from the Lookbook UI. This means that the preview or example will not show up in the navigation, but will still be accessible via it's URL. You can use the `@hidden` comment tag to manage this.
To **hide an entire preview** include the `@hidden` tag in a class comment:
```ruby
# @hidden
class MyComponentPreview < ViewComponent::Preview
# examples here....
end
```
To **hide an individual example** include the `@hidden` tag in the appropriate method comment:
```ruby
class MyComponentPreview < ViewComponent::Preview
# Hidden Example
# ----------
# You won't see this in the nav!
#
# @hidden
def hidden_example
# ...
end
def a_visible_example
# ...
end
# @hidden
def another_hidden_example
# ...
end
end
```
## Configuration
Lookbook uses ViewComponent's configuration options for anything to do with previews, paths and general setup, so you won't need to duplicate any settings.
However the following Lookbook-specific config options are also available:
### UI auto-refresh
Disable/enable the auto-updating of the Lookbook UI when files change. Enabled by default.
```ruby
config.lookbook.auto_refresh = false # default is true
```
By default Lookbook will listen for changes in any [preview directories](https://viewcomponent.org/api.html#preview_paths) as well as in the [components directory](config.view_component.preview_paths) itself.
If you wish to add additional paths to listen for changes in, you can use the `listen_paths` option:
```ruby
config.lookbook.listen_paths << Rails.root.join('app/other/directory')
```
## Contributing
Lookbook is very much a small hobby/side project at the moment. I'd love to hear from anyone who is interested in contributing but I'm terrible at replying to emails or messages, so don't be surprised if I take forever to get back to you. It's not personal 😜
### Developing on a local version of Lookbook
The quickest way to get a development version of Lookbook up and running is to use the [lookbook-demo](https://github.com/allmarkedup/lookbook-demo) app and link it to a local version of the Lookbook gem:
#### Initial setup:
1. Clone this repository somewhere on your machine - `git clone git@github.com:allmarkedup/lookbook.git`
2. Also pull down the [lookbook-demo](https://github.com/allmarkedup/lookbook-demo) repository to your machine
3. In the `Gemfile` of the `lookbook-demo` repository, replace `gem "lookbook", '>= 0.1', git: "https://github.com/allmarkedup/lookbook", branch: "main"` with `gem "lookbook", path: "../path/to/lookbook"` (use the path to your local copy of lookbook)
4. Install dependencies - from the root of the parent project run `bundle install`
#### Starting development
1. From within the `lookbook` root directory run the comand `npm run dev` (this will make sure the CSS/JS is recompiled if/when you make changes to the UI)
2. From within the `lookbook-demo` root directory run `npm run start` - this will start a server and build the demo assets
Point your browser to http://localhost:3000/lookbook to see the UI. You can then make and test changes to the Lookbook code in your local copy of lookbook repo. PRs are welcome if you add anything useful :-)
> Note that changes to files in the Lookbook `lib/` directory will require a server restart in order to have them applied.
#### Tests
You can run the tests from within the `lookbook` root directory with the `rake test` command.
## License
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).