From 58f9dd23a4b0643890fea88a554d1f26e587362c Mon Sep 17 00:00:00 2001 From: Nicholas Barone Date: Fri, 9 Aug 2024 11:21:53 -0700 Subject: [PATCH] Rake task for generating stories from component previews --- lib/rails/storybook.rb | 2 ++ lib/storybook.rb | 7 +++---- lib/storybook/preview.rb | 25 +++++++++++++++++++++++++ lib/storybook/railtie.rb | 14 ++++++++++++++ lib/storybook/tasks/stories.rake | 18 ++++++++++++++++++ 5 files changed, 62 insertions(+), 4 deletions(-) create mode 100644 lib/rails/storybook.rb create mode 100644 lib/storybook/preview.rb create mode 100644 lib/storybook/railtie.rb create mode 100644 lib/storybook/tasks/stories.rake diff --git a/lib/rails/storybook.rb b/lib/rails/storybook.rb new file mode 100644 index 0000000..e37c131 --- /dev/null +++ b/lib/rails/storybook.rb @@ -0,0 +1,2 @@ +require_relative "../storybook.rb" +# TODO: Fix the gem naming, etc diff --git a/lib/storybook.rb b/lib/storybook.rb index 4a98677..4f126f6 100644 --- a/lib/storybook.rb +++ b/lib/storybook.rb @@ -1,6 +1,5 @@ require "storybook/version" +require "storybook/preview" +require "storybook/railtie" if defined?(Rails::Railtie) -module Storybook - class Error < StandardError; end - # Your code goes here... -end +module Storybook; end diff --git a/lib/storybook/preview.rb b/lib/storybook/preview.rb new file mode 100644 index 0000000..a950eac --- /dev/null +++ b/lib/storybook/preview.rb @@ -0,0 +1,25 @@ +module Storybook + module Preview + def self.included(base) + base.extend ClassMethods + end + + module ClassMethods + def to_csf + { title: component_name, stories: stories } + end + + def stories + instance_methods(false).collect { |name| story(name) } + end + + def story(name) + { name:, parameters: { server: { id: "#{component_name&.underscore}/#{name}" } } } + end + + def component_name + $1 if name =~ /(.+Component)(?=Preview)/ + end + end + end +end diff --git a/lib/storybook/railtie.rb b/lib/storybook/railtie.rb new file mode 100644 index 0000000..ad782a5 --- /dev/null +++ b/lib/storybook/railtie.rb @@ -0,0 +1,14 @@ +require "storybook" +require "rails" + +# https://gist.github.com/ntamvl/7a6658b4cd82d6fbd15434f0a9953411 +module Storybook + class Railtie < Rails::Railtie + railtie_name :storybook + + rake_tasks do + path = File.expand_path(__dir__) + Dir.glob("#{path}/tasks/**/*.rake").each { |f| load f } + end + end +end diff --git a/lib/storybook/tasks/stories.rake b/lib/storybook/tasks/stories.rake new file mode 100644 index 0000000..1685341 --- /dev/null +++ b/lib/storybook/tasks/stories.rake @@ -0,0 +1,18 @@ +namespace :storybook do + desc "Write CSF JSON stories for all Stories" + task stories: :environment do + previews_dir = Rails.root.join("test/components/previews") + Dir.glob("#{previews_dir}/**/*_preview.rb").each { |file| require file } + + stories = ViewComponent::Preview.descendants.map do |preview| + [ preview.component_name&.underscore, preview.to_csf ] if preview < Storybook::Preview + end + + stories_dir = "stories" + stories.each do |path, story| + File.open(Rails.root.join("#{stories_dir}/#{path}.stories.json"), "w") do |f| + f.write(JSON.pretty_generate(story)) + end + end + end +end