GithubHelp home page GithubHelp logo

viewcomponent / lookbook Goto Github PK

View Code? Open in Web Editor NEW
814.0 8.0 84.0 51.91 MB

A UI development environment for Ruby on Rails apps ✨

Home Page: https://lookbook.build

License: MIT License

Ruby 27.08% CSS 3.90% JavaScript 63.54% HTML 5.45% Shell 0.03%
viewcomponent rails ruby development components lookbook ruby-on-rails partials phlex styleguide

lookbook's Introduction


A UI development environment for Ruby on Rails applications.

Documentation  |  Demo site

Gem version CI status


Lookbook combines a powerful component browser and preview system with an integrated documentation engine to help teams build robust, modular, maintainable user interfaces.

It's compatible with ViewComponent, Phlex, ActionView partials and more.

Read the docs →

Lookbook UI

Development

Lookbook is implemented as an isolated Rails Engine and uses ViewComponent, Tailwind and Alpine for its UI.

This repository contains:

Documentation site

The Lookbook docs site is built using Bridgetown and the source files can be found in the ./docs directory.

To preview changes locally you can run a development version of the docs site:

  1. Clone this repo
  2. Install dependencies: bundle install
  3. Start the app: bin/docs
  4. Visit http://localhost:4000

Testing

Lookbook uses RSpec for testing.

Tests can be run using the rake spec or bundle exec rspec commands.

The dummy app that the tests are being run against can be viewed by running the bin/dummy command and then browsing to http://localhost:9292/lookbook

Releases

Lookbook uses Release It! to automate the release process.

Running npm run release will start the process of publishing a new release and walks though all the steps from picking a version number to publishing the updated gem.

Publishing a release requires write permissions for this repository (ViewComponent/lookbook) and 2FA publish permissions for Lookbook on RubyGems.

Contributing

Lookbook is an un-funded open source project and contributions of all types and sizes are most welcome!

Please take the time to read over the Contributing guide before making your first contribution and if anything isn't clear then start a discussion and we will do our best to help you out.

Contributors

Lookbook was created by Mark Perkins and continues to grow & improve thanks to the ideas, suggestions and hard work of all of these excellent humans:

License

The gem is available as open source under the terms of the MIT License.

lookbook's People

Contributors

adrienpoly avatar agrobbin avatar allmarkedup avatar dependabot[bot] avatar dmorgan-fa avatar drbragg avatar edwinthinks avatar erinnachen avatar fusion2004 avatar gabeisman avatar joelhawksley avatar johnanon9771 avatar jonrohan avatar kirillplatonov avatar leighhalliday avatar liram11 avatar martijnversluis avatar mdrbohlav avatar muriloime avatar oli0li avatar sakin avatar spone avatar steves avatar stevetidy avatar tastypi avatar tellodaniel avatar thutterer avatar tleish avatar waldrupm avatar wheeyls avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

lookbook's Issues

Add support for preview tags

Including the ability to filter components by a specific tag.

should support an array of tags in the usual Yard style. Something like:

# @tag [navigation, marketing]

default_preview_layout not used in grouped previews

When defining a custom preview layout

# config/application.rb
config.view_component.default_preview_layout = "view_component/preview"

and when grouping previews

class PillComponentPreview < ViewComponent::Preview
  # @!group Colors

  def inherit_color
    render PillComponent.new(text: "Hello")
  end

  def green_pill
    render PillComponent.new(text: "Hello", color: :green)
  end

  def yellow_pill
    render PillComponent.new(text: "Hello", color: :yellow)
  end

  # @!endgroup
end

... the previews are rendered in the default app/views/layouts/application.html.slim instead of app/views/layouts/view_component/preview.html.slim.

When displaying regular preview (not grouped), the correct default layout is used.

Refactor for better encapsulation

The current v0.1.x branch has a number of places where future changes to ViewComponent could cause issues with Lookbook’s integration - for example potential method name clashes in the base preview class.

For a v0.2.0 release it needs a bit of a refactor to clean up the separation of lookbook and VC so that there is no danger of unwittingly affecting the behaviour of VC.

Syntax error in a component file does not display the error

Visiting the URL of a preview example that attempts to render a component with a syntax error in it results in results in 'preview not found' message.

This is not very helpful because it effectively swallows the error message making it hard to debug.

It should display the Rails error instead.

In-browser editable dynamic preview parameters

ViewComponent previews allow setting dynamic values that be changed by editing query string parameters.

Lookbook could parse the parameters and generate fields in the UI so that these values could be edited live and the changes instantly reflected in the rendered component preview, much like the way StorybookJS controls work.

Wrong preview when using nested components

I have 2 components:

  • HeaderComponent
  • Header::MenuComponent

The previews are correct when accessing them with the standard ViewComponent URLs:

  • http://localhost:3000/rails/view_components/header_component/default
  • http://localhost:3000/rails/view_components/header/menu_component/default

But in lookbook (0.4.0.beta.1), I always get the HeaderComponent preview:

image

image

Do you need a failing test?

Various small bugs

Hey, my team and I are really glad to have found Lookbook. We've only recently started using it, but we've been really impressed so far and are really hopeful it'll continue to grow.

I've noticed a few bugs and wanted to bring them to your attention, here's a PR demonstrating the issues I've uncovered:

  • Multiple toggles in a components param tab don't move independentally
  • Background colour still requires quotes, however the README has dropped this information
  • Something is causing the Source tab output to append lines when toggling between different select options

Thanks again for your work with Lookbook! 👍

NoMethodError: undefined method `with_indifferent_access' for nil:NilClass

Me again

I wanted to test if my components would display correctly in staging (testing for #8) and I got this message during the deploy phase on Heroku.

rake aborted!
remote:        NoMethodError: undefined method `with_indifferent_access' for nil:NilClass
remote:        /tmp/build_af8e446f/vendor/bundle/ruby/2.7.0/gems/lookbook-0.2.2/lib/lookbook/engine.rb:40:in `block in <class:Engine>'
remote:        /tmp/build_af8e446f/vendor/bundle/ruby/2.7.0/gems/railties-6.1.4.1/lib/rails/initializable.rb:32:in `instance_exec'
remote:        /tmp/build_af8e446f/vendor/bundle/ruby/2.7.0/gems/railties-6.1.4.1/lib/rails/initializable.rb:32:in `run'
remote:        /tmp/build_af8e446f/vendor/bundle/ruby/2.7.0/gems/railties-6.1.4.1/lib/rails/initializable.rb:61:in `block in run_initializers'
remote:        /tmp/build_af8e446f/vendor/bundle/ruby/2.7.0/gems/railties-6.1.4.1/lib/rails/initializable.rb:60:in `run_initializers'
remote:        /tmp/build_af8e446f/vendor/bundle/ruby/2.7.0/gems/railties-6.1.4.1/lib/rails/application.rb:391:in `initialize!'
remote:        /tmp/build_af8e446f/config/environment.rb:7:in `<main>'
remote:        /tmp/build_af8e446f/vendor/bundle/ruby/2.7.0/gems/bootsnap-1.7.3/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:23:in `require'
remote:        /tmp/build_af8e446f/vendor/bundle/ruby/2.7.0/gems/bootsnap-1.7.3/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:23:in `block in require_with_bootsnap_lfi'
remote:        /tmp/build_af8e446f/vendor/bundle/ruby/2.7.0/gems/bootsnap-1.7.3/lib/bootsnap/load_path_cache/loaded_features_index.rb:92:in `register'
remote:        /tmp/build_af8e446f/vendor/bundle/ruby/2.7.0/gems/bootsnap-1.7.3/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:22:in `require_with_bootsnap_lfi'
remote:        /tmp/build_af8e446f/vendor/bundle/ruby/2.7.0/gems/bootsnap-1.7.3/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:31:in `require'
remote:        /tmp/build_af8e446f/vendor/bundle/ruby/2.7.0/gems/zeitwerk-2.4.2/lib/zeitwerk/kernel.rb:34:in `require'
remote:        /tmp/build_af8e446f/vendor/bundle/ruby/2.7.0/gems/activesupport-6.1.4.1/lib/active_support/dependencies.rb:332:in `block in require'
remote:        /tmp/build_af8e446f/vendor/bundle/ruby/2.7.0/gems/activesupport-6.1.4.1/lib/active_support/dependencies.rb:299:in `load_dependency'
remote:        /tmp/build_af8e446f/vendor/bundle/ruby/2.7.0/gems/activesupport-6.1.4.1/lib/active_support/dependencies.rb:332:in `require'
remote:        /tmp/build_af8e446f/vendor/bundle/ruby/2.7.0/gems/railties-6.1.4.1/lib/rails/application.rb:367:in `require_environment!'
remote:        /tmp/build_af8e446f/vendor/bundle/ruby/2.7.0/gems/railties-6.1.4.1/lib/rails/application.rb:533:in `block in run_tasks_blocks'
remote:        /tmp/build_af8e446f/vendor/bundle/ruby/2.7.0/gems/sprockets-rails-3.2.2/lib/sprockets/rails/task.rb:61:in `block (2 levels) in define'
remote:        Tasks: TOP => environment
remote:        (See full trace by running task with --trace)

Feature Request: Searching by example name + Sorting examples by alphabetical name in sidebar

Hi!

So I haven't pulled down the latest version and gotten it to boot yet, but... one thing that would be nice, is the ability to sort the examples within the sidebar folders by alphabetical name, I've found the names to end up going all over the place.

Another feature request we have is extending the sidebar search to support by example name as well.

For some more context, here's how we're thinking of setting up our examples:

CleanShot 2021-07-30 at 10 14 06@2x

and search has been mostly limited to the titles.

If y'all have a lot of components, how do you think of organizing the Lookbook examples? We have hundreds of components at @podia 😅, and are hoping to use Lookbook to help surface them to our team.

Additionally.... this is more of a bug, but I'm a little befuddled why the first item in my namespace Podia::UI:: always gets added to its own list. 😭 (We have a custom inflector to make Ui -> UI with Zeitwerk, but even renaming it, it tended to push it into a new list for the first item.

Getting undefined method component error

Hey guys, not sure if this is the best place to ask, but here it goes:

I keep on getting this error on my local:

Screenshot 2022-03-25 at 12 27 14 PM

I can load http://localhost:3000/lookbook just fine, but when I want to preview one of the components, it throws that error. I can also view the component just fine from http://localhost:3000/lookbook/example/with_default_title (one of them)

Here are my code:

# app/components/example_component.rb

class ExampleComponent < ViewComponent::Base
  def initialize(title:)
    @title = title
  end
end
<!-- app/components/example_component.html.erb -->

<span title="<%= @title %>"><%= content %></span>
<%= @title %>
# test/components/previews/example_component_preview.rb
class ExampleComponentPreview < ViewComponent::Preview
  # 🎉 Button playground! 🎉
  # -----------------------
  # You can use the controls in the 'Params' section
  # to set button property values on the fly.
  #
  # @param title text
  def with_default_title(title: "hello")
    render_with_template(locals: {
      title: title
    })
  end

  def with_long_title
    render(ExampleComponent.new(title: "This is a really long title to see how the component renders this"))
  end

  def with_content_block
  end
end
<!-- test/components/previews/example_component_preview/with_content_block.html.erb -->
<%= 
  render(ExampleComponent.new(title: "This component accepts a block of content")) do
    tag.div do
      content_tag(:span, "Hello")
    end
  end
%>
<!-- test/components/previews/example_component_preview/with_default_title.html.erb -->
<%= render(ExampleComponent.new(title: title)) %>

My current environment:

  • Rails v5.2.5
  • view_component v2.51.0
  • lookbook v0.7.1

Let me know if you need more information. Thanks in advance.

Don’t flatten nav structure when filtering

Current implementation was just a quick way to work around complexities of filtering nested tree structures, but it means that it’s easy to lose context when filtering components.

Javascript error when using lookbook in a gem

I'm using lookbook in an admin gem that have a Rails engine. In dev environment, I use combustion.

Lookbook seems to works correctly but I noticed that when I open my browser dev tool, I've got the following errors:

Uncaught 
Exception { name: "NS_ERROR_FAILURE", message: "", result: 2147500037, filename: "http://localhost:5000/assets/madmin/application.debug-f4b00a…506709e018153472c1654fac6ebe8ef52c9131170148aae16953f89a7.js", lineNumber: 6576, columnNumber: 0, data: null, stack: "update@http://localhost:5000/assets/madmin/application.debug-f4b00af506709e018153472c1654fac6ebe8ef52c9131170148aae16953f89a7.js:6576:14\nreplace@http://localhost:5000/assets/madmin/application.debug-f4b00af506709e018153472c1654fac6ebe8ef52c9131170148aae16953f89a7.js:6572:12\nstart@http://localhost:5000/assets/madmin/application.debug-f4b00af506709e018153472c1654fac6ebe8ef52c9131170148aae16953f89a7.js:6558:14\nstart@http://localhost:5000/assets/madmin/application.debug-f4b00af506709e018153472c1654fac6ebe8ef52c9131170148aae16953f89a7.js:7145:22\nstart@http://localhost:5000/assets/madmin/application.debug-f4b00af506709e018153472c1654fac6ebe8ef52c9131170148aae16953f89a7.js:7386:13\n@http://localhost:5000/assets/madmin/application.debug-f4b00af506709e018153472c1654fac6ebe8ef52c9131170148aae16953f89a7.js:7921:3\n@http://localhost:5000/assets/madmin/application.debug-f4b00af506709e018153472c1654fac6ebe8ef52c9131170148aae16953f89a7.js:16091:3\n" }
application.debug-f4b00af506709e018153472c1654fac6ebe8ef52c9131170148aae16953f89a7.js:6576

And

Uncaught TypeError: can't access property "href", this.location is undefined
    notifyApplicationAfterPageLoad http://localhost:5000/assets/madmin/application.debug-f4b00af506709e018153472c1654fac6ebe8ef52c9131170148aae16953f89a7.js:7327
    pageBecameInteractive http://localhost:5000/assets/madmin/application.debug-f4b00af506709e018153472c1654fac6ebe8ef52c9131170148aae16953f89a7.js:7264
    pageIsInteractive http://localhost:5000/assets/madmin/application.debug-f4b00af506709e018153472c1654fac6ebe8ef52c9131170148aae16953f89a7.js:6810
    pageIsComplete http://localhost:5000/assets/madmin/application.debug-f4b00af506709e018153472c1654fac6ebe8ef52c9131170148aae16953f89a7.js:6814
    interpretReadyState http://localhost:5000/assets/madmin/application.debug-f4b00af506709e018153472c1654fac6ebe8ef52c9131170148aae16953f89a7.js:6782
application.debug-f4b00af506709e018153472c1654fac6ebe8ef52c9131170148aae16953f89a7.js:7327:49

I may try to create a small standalone app that reproduced this issue if this may help you.

Like I said it doesn't seems to brake the lookbook features.

Release as a Gem

Currently Lookbook can only be installed directly from Github.

NameError when ViewComponent source code preview is turned on

Hi there!

I pulled down the latest version of Lookbook and set it up like the following in my development.rb environment.

We're using view_component 2.35

  # ViewComponent preview configuration
  config.view_component.preview_paths << Rails.root.join("spec", "components", "previews")
  config.view_component.show_previews_source = true
  config.view_component.preview_route = "/view_component/previews"
  config.view_component.default_preview_layout = "view_component_preview"

Upon installing Lookbook per the Readme (add the gem from GitHub, add the mount line into routes and trying to view a basic view component preview (inside of Lookbook), I ran into this error:

CleanShot 2021-07-29 at 20 12 55@2x

We would love the ability to retain the ViewComponent source code previews in the native ViewComponent previews while Lookbook rapidly improves.

Let me know if you need me to dive into this!

Is there slot issue?

Before I start digging in, I wanted to report an issue with lookbook and slots.

    def default
      component = NavBar::Component.new do |c|
        c.main_navigation_item text: "Home", href: "#"
        c.main_navigation_item text: "About", href: "#"
        c.user_sign_out_link href: "#", confirm: "Are you sure?"
      end
      render component
    end

The rest of the component renders fine, but it's as if the slots are not defined at all.

Is this a known issue?

Support nested rendering and/or support params in erb examples

Hey @allmarkedup, I've created a PR demonstrating the issue.

The end-goal for us is to be able to host a Lookbook instance, and iframe in the rendered components into our reference site (and likely pull the code examples too), so being able demonstrate composability of our ViewComponents, is really important (i.e. an autogrid layout with various cards within).

BAOAgency's Polaris ViewComponents example has a nice solution whereby they're using erb examples, called from by the ruby files. This works really well, and we're planning on following this method for all our components, but it does mean the params support no longer works (unless I'm missing something).

Is this something you've considered?

Thanks,
- D

Notes section - rendering a table in markdown

Great tool!

I am trying to render a table in the notes section in Markdown by doing something like the following in the preview template:

Screenshot 2021-10-25 at 10 04 05

However the output in the UI looks like it's being treated as straightforward text as seen below.

Screenshot 2021-10-25 at 10 06 46

I'm not sure if I am just getting the syntax wrong or if this isn't actually possible within the notes section?

UI improvements

  • Improve accessibility across the UI
  • Make the UI work at small-screen sizes to make component testing on mobile devices a better experience
  • Add some configuration options for customising UI look and feel

Components having a single preview: nav label

I'm testing the 0.3.0.beta.2 version. Some of my components have a single preview method, named default (which is the default 😄 ). In this case, they are displayed as "Default" in the navigation. I would expect them to use the name of the component instead.

image

Improve UI accessibility

Current first-pass implementation has not had any work put into accessibility considerations or how to optimise for keyboard navigation. Need to look into this and how best to test it.

Add HTML beautifier

Hi! We are testing this pretty gem on one of our project, and I notice a small thing.

We use SLIM for views, and SLIM render html in one line.

Do you think, output tab content may use a prettier or a beautifier to show HTML?

Screenshot 2021-09-03 at 11 26 02

Extra pages

What do you think about having some extra pages like there is in mountain_view gem?

Could be nice to print some info like:

  • color palettes, fonts, styleguide details
  • some generic information about components

NameError: uninitialized constant ComponentPreview::RSpec

We just bumped lookbook from 0.6.1 to 0.7.1, and we are now seeing this while deploying.

Is anyone else seeing this issue?

NameError: uninitialized constant MeterReadingGraphComponentPreview::RSpec
spec/components/previews/meter_reading_graph_component_preview.rb:2:in `<class:MeterReadingGraphComponentPreview>'
spec/components/previews/meter_reading_graph_component_preview.rb:1:in `<main>'
config/environment.rb:5:in `<main>'
/home/deploy/.rbenv/versions/3.0.2/bin/bundle:23:in `load'
/home/deploy/.rbenv/versions/3.0.2/bin/bundle:23:in `<main>'
Tasks: TOP => db:migrate => db:load_config => environment

Websocket fails to connect when Lookbook is mounted at root

Hey Mark, something that I've ran into recently:

When we mount the Lookbook engine at the root of the rails app, rather than /lookbook, websockets fail to connect and hot reloading fails.

Demo here
Console: WebSocket connection to 'ws://cable/?uid=1646144935981' failed

Edit:
I've also checked against the latest 0.6.1, and the problem is still present.

Some HTML character codes copied to clipboard

Testing this against v0.5.1

Click copy to clipboard has some HTML characters when using an erb example:

Expected:

<%= render(CardComponent.new) do |c| %>
  <% c.header do %>
    <h2 class="fe-u-heading--4">Heading</h2>
  <% end %>
  <% c.row do %>
    This content is in a row.
  <% end %>
  <% c.footer(divider: divider) do %>
    Footer content goes here.
  <% end %>
<% end %>

Result:

&lt;%= render(CardComponent.new) do |c| %&gt;
  &lt;% c.header do %&gt;
    <h2 class="fe-u-heading--4">Heading</h2>
  &lt;% end %&gt;
  &lt;% c.row do %&gt;
    This content is in a row.
  &lt;% end %&gt;
  &lt;% c.footer(divider: divider) do %&gt;
    Footer content goes here.
  &lt;% end %&gt;
&lt;% end %&gt;

Improve search/filtering/navigation

  • Include example names in the filter
  • Add keyboard navigation
  • Allow tagging of previews/examples for grouping and advanced search
  • Add ability to override/customise nav tree generation
  • Add support for 'hidden' components that don't appear in the nav

Injected content is not escaped correctly in iframe `srcdoc` attribute

Some middleware such as Rack::LiveReload inject content into the HTML response. It seems that this can cause issues with the iframe srcdoc attribute that is used display the rendered preview. Possibly due to quotes not being escaped correctly in the injected content?

See #8 for further discussion.

Figure out which component is being rendered by the preview

It should be possible to make an educated guess about which component is currently being rendered in the preview, although this may be tricky in certain situations. However given the strong focus on conventions in Rails it should be possible in the majority of cases.

If the target component can be ascertained, it opens up possible future features like:

  • displaying filesystem links to the target component files
  • Listing/inspecting sidecar asset files
  • Displaying component documentation and parameter schema if documented with Yard comments.

Layout broken in 0.3.0.beta.0

Hi @allmarkedup,

I just tested your beta release, and notice an issue on layout. It looks broken on my browser (test on linux elementary OS Chromium and Firefox). Until I open folder to make tree size use all browser height.

Screenshot from 2021-09-20 21 59 00

Otherwise nice new release 🚀

Add links to open preview/component files in the user’s code editor

Would be great to display links to the current preview (and component file if possible) that when clicked on locally open the file in the users code editor.

Would require specifying which editor the user uses in a local .env file or similar.

Could also potentially be configured to open the file in an online repo as an alternative/fallback.

lookbook must be after view_component in the Gemfile

Hi, thanks for your work on this awesome project!

I just discovered that the

gem "lookbook"

declaration must be after

gem "view_component", require: "view_component/engine"

in the Gemfile, else you get this error when trying to show a preview:

NoMethodError in Lookbook::BrowserController#show
undefined method `constantize' for nil:NilClass

lookbook (0.2.1) app/controllers/lookbook/browser_controller.rb:133:in `preview_controller' 

In my case it was before because they were sorted alphabetically :)

What could be done to prevent this unexpected error?

Maybe add an explicit error message in this case? Add a mention in the README?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.