phenixdigital / phoenix_storybook

A pluggable storybook for your Phoenix components.
MIT License
685 stars 54 forks source link

Working with forms and inputs #67

Closed nicolasdabreo closed 2 years ago

nicolasdabreo commented 2 years ago

Hello, how should I go about using forms and inputs in the storybook? using the Phoenix.HTML.Form struct directly causes browser errors which are not likely to be very useful to share.

Uncaught TypeError: e is null

Here is how I'm currently supporting my inputs in storybook:

      %Story{
        id: :select_error_state,
        attributes: %{
          type: :select,
          select_options: ["Foo", "Bar", "Fizz", "Buzz"],
          prompt: "Select a variable name",
          class: "",
          form: %Phoenix.HTML.Form{data: %{foo: "Foo"}, errors: [foo: {"can't be set to Foo", []}]},
          field: :foo
        }
      },
cblavier commented 2 years ago

Hey Nicolas,

I'm currently in the process of my moving all our company's components to the storybook, but I have not tackled the form ones yet.

I'll have a look at it tomorrow and let you know how it goes

cblavier commented 2 years ago

I'm starting right now to move my form components to the storybook! Keep you posted

cblavier commented 2 years ago

I'm using phx_live_storybook from the main branch and got this text_input to work.

defmodule Storybook.Components.TextInput do
  use PhxLiveStorybook.Entry, :component
  alias PhenixStorybook.Components.Form.TextInputGroup

  def function, do: &TextInputGroup.text_input_group/1
  def icon, do: "fat fa-badge-check"

  def template do
    """
    <div class="w-64" lsb-code-hidden>
      <.lsb-story/>
    </div>
    """
  end

  def attributes do
    [
      %Attr{
        id: :form,
        type: Phoenix.HTML.Form,
        doc: "The form structure holding form data."
      },
      %Attr{
        id: :field,
        type: :atom,
        doc: "The form field key."
      },
      %Attr{
        id: :name,
        type: :string,
        doc: "The input name."
      },
      %Attr{
        id: :label,
        type: :string,
        doc: "The input label."
      },
      %Attr{
        id: :value,
        type: :string,
        doc: "The input value."
      },
      %Attr{
        id: :placeholder,
        type: :string,
        doc: "The input placeholder."
      },
      %Attr{
        id: :hint,
        type: :string,
        doc: "A hint to display below the input."
      },
      %Attr{
        id: :icon,
        type: :string,
        doc: "A font awesome icon class that will be prepended to the input."
      },
      %Attr{
        id: :disabled,
        type: :boolean,
        default: false,
        doc: "To allow input change or not. The default value will not be submitted."
      }
    ]
  end

  def stories do
    [
      %Story{
        id: :default_text_input,
        attributes: %{
          name: "address",
          placeholder: "Please type your address",
          label: "Adress",
          for: "address"
        }
      },
      %Story{
        id: :in_error,
        attributes: %{
          form: %Phoenix.HTML.Form{
            data: %{foo: "Foo"},
            errors: [foo: {"can't be set to Foo", []}]
          },
          field: :foo,
          label: "Foo attribute"
        }
      }
    ]
  end
end

CleanShot 2022-09-12 at 15 26 18

I will also provide form examples on the sample application repository.

Does this help?

cblavier commented 2 years ago

I just improved templating feature so that you can pass arbitrary variables into your story:

<.form for={:story} let={f}>
  <.lsb-story form={f}/>
</.form>

Example text_input is available here.