From 3e5d5e5f6763febae795cc0d76b61d90f56c6389 Mon Sep 17 00:00:00 2001 From: Angelika Tyborska Date: Fri, 22 Mar 2024 13:30:11 +0100 Subject: [PATCH] Add documentation about upgrading bitstyles versions; add versions showcase dev tool (#119) * Render static pages with showcases for all bitstyles versions * Add an --only flag * Refactoring * Hide showcase task from library users * Add to CI to ensure it continues working in the future * Describe how to approach upgrading bitstyles * Fix credo problem * Don't include test fixtures in documentation * Don't link from hexdoc to a dev-only doc * Fix plural vs singular * Split doctest into two parts in story macro * Allow doctests for other bitstyles versions * Extend version doc with new multi-version doctests * credo * Make tests async again with process dict --- .github/workflows/action.yml | 2 + .gitignore | 1 + README.md | 4 +- docs/bitstyles_version_compatibility.md | 103 ++ lib/bitstyles_phoenix/alpine3/dropdown.ex | 4 + lib/bitstyles_phoenix/alpine3/sidebar.ex | 2 + lib/bitstyles_phoenix/bitstyles.ex | 11 +- lib/bitstyles_phoenix/component/avatar.ex | 122 ++- lib/bitstyles_phoenix/component/badge.ex | 155 +-- .../component/breadcrumbs.ex | 6 + lib/bitstyles_phoenix/component/button.ex | 340 ++++--- lib/bitstyles_phoenix/component/card.ex | 8 + lib/bitstyles_phoenix/component/content.ex | 6 + .../component/description_list.ex | 4 + lib/bitstyles_phoenix/component/dropdown.ex | 91 +- lib/bitstyles_phoenix/component/error.ex | 144 ++- lib/bitstyles_phoenix/component/flash.ex | 12 + lib/bitstyles_phoenix/component/form.ex | 936 ++++++++++-------- lib/bitstyles_phoenix/component/heading.ex | 10 + lib/bitstyles_phoenix/component/icon.ex | 62 +- lib/bitstyles_phoenix/component/modal.ex | 8 + lib/bitstyles_phoenix/component/sidebar.ex | 6 + lib/bitstyles_phoenix/component/tabs.ex | 6 + lib/bitstyles_phoenix/component/use_svg.ex | 6 + .../helper/component_rendering.ex | 32 + lib/bitstyles_phoenix/helper/test_fixtures.ex | 22 + lib/bitstyles_phoenix/showcase.ex | 54 +- mix.exs | 2 +- scripts/generate_version_showcase.ex | 320 ++++++ .../component/error_test.exs | 10 +- .../bitstyles_phoenix/component/form_test.exs | 12 +- test/support/component_case.ex | 24 +- 32 files changed, 1701 insertions(+), 824 deletions(-) create mode 100644 docs/bitstyles_version_compatibility.md create mode 100644 lib/bitstyles_phoenix/helper/component_rendering.ex create mode 100644 lib/bitstyles_phoenix/helper/test_fixtures.ex create mode 100644 scripts/generate_version_showcase.ex diff --git a/.github/workflows/action.yml b/.github/workflows/action.yml index 5b8ca56..affa76b 100644 --- a/.github/workflows/action.yml +++ b/.github/workflows/action.yml @@ -15,6 +15,8 @@ jobs: - run: mix test - run: mix credo --strict - run: mix docs + - name: Check if versions showcase mix script finishes + run: mix run scripts/generate_version_showcase.ex demo: runs-on: ubuntu-latest name: Demo diff --git a/.gitignore b/.gitignore index 863a391..c1ff8c5 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,4 @@ erl_crash.dump # Ignore package tarball (built via "mix hex.build"). bitstyles_phoenix-*.tar +/version_showcase diff --git a/README.md b/README.md index 3cd9af2..bc512f8 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,9 @@ Basic helpers for [bitstyles](https://github.com/bitcrowd/bitstyles) for elixir ## Requirements -bitstyles must be installed separately into the asset generation. The helpers in this project just output classes for working with bitstyles. +Bitstyles must be installed separately into the asset generation. The helpers in this project just output classes for working with bitstyles. + +Bitstyles versions from 4.3.0 down to 1.3.0 are supported. ## Installation diff --git a/docs/bitstyles_version_compatibility.md b/docs/bitstyles_version_compatibility.md new file mode 100644 index 0000000..82743e7 --- /dev/null +++ b/docs/bitstyles_version_compatibility.md @@ -0,0 +1,103 @@ +# Bitstyles version compatibility + +General rules: + +- We don't drop bitstyles version support. Users of bitstyles_phoenix should be able to upgrade bitstyles_phoenix to the newest version without having to upgrade bitstyles. +- We don't skip bitstyles versions. Users of bitstyles_phoenix should be able to upgrade bitstyles to any version between the highest and lowest currently supported bitstyles version. + +## Doctests ("stories") + +The `story` macro is used to generate doctests, as well as the component preview in docs. + +The first argument is the story's description (`"An error tag"`), the second argument is an iex code snippet, and the third argument is the expected result when the code snippet gets executed. The third argument can be a single charlist, or a keyword lists that maps bitstyles version numbers to charlists. If the third argument is a single charlist, it's assumed that is the expected result for the default bitstyles version. + +⚠️ Note that the 4 space indentation in the code snippet and the expected result is important. + +### Multi-version doctest example + +```elixir + story( + "An error tag", + ''' + iex> assigns = %{} + ...> render ~H""" + ...> <.ui_error error={{"Foo error", []}} /> + ...> """ + ''', + "4.3.0": ''' + """ + + Foo error + + """ + ''', + "3.0.0": ''' + """ + + Foo error + + """ + ''' + ) +``` + +## Versions showcase + +A showcase of components in all supported bitstyles versions can be generated by running: + +```bash +mix run scripts/generate_version_showcase.ex +``` + +The script accepts multiple `--only` arguments if you want to limit the showcase to only a handful of versions: + +```bash +mix run scripts/generate_version_showcase.ex --only 4.3.0 --only 4.2.0 +``` + +This script will create a `version_showcase` directory with static web pages. Open the starting page with: + +```bash +open version_showcase/index.html +``` + +## How to upgrade the default bitstyles version in bitstyles_phoenix? + +1. Choose the smallest possible version jump (do not skip versions). +2. Read about the changes in version in [the bitstyles Changelog](https://github.com/bitcrowd/bitstyles/blob/main/CHANGELOG.md). +3. Update the highest supported version mentioned in the [README](../README.md). +4. Update the `@default_version` in [`BitstylesPhoenix.Bitstyles`](../lib/bitstyles_phoenix/bitstyles.ex). +5. Add the new version to the version lists in [`generate_version_showcase`](../scripts/generate_version_showcase.ex). +6. Handle classes renamed by bitstyles by adding new clauses of the `classname/2` function in [`BitstylesPhoenix.Bitstyles`](../lib/bitstyles_phoenix/bitstyles.ex). +7. If renaming classes is not enough to upgrade correctly, you can perform [a bitstyles version check in a component](#an-example-of-a-bitstyles-version-check-in-a-component). +8. Run `mix test`. Fix all doctests until `mix test` succeeds. Add new expected values for the new version, and keep the current expected value for the previous version (see [multi-version doctest example](#multi-version-doctest-example)) +9. Run `mix docs` to preview components after making changes to them. +10. Use the [versions showcase](#versions-showcase) to test that you didn't break anything for older bitstyles versions. + +### An example of a bitstyles version check in a component + +```elixir +def ui_tricky_component(assigns) do + version = BitstylesPhoenix.Bitstyles.version() + + if version >= "5.0.0" do + ~H""" +

...

+ """ + else + ~H""" +
+
+ ... +
+
+ """ + end +end +``` + +## Adding new components + +Ideally, if you're adding a completely new component, make sure it works with all supported bitstyles versions by using the [versions showcase](#versions-showcase) to test it. + +If it's not practical to support it in other version, you can perform [a bitstyles version check in the component](#an-example-of-a-bitstyles-version-check-in-a-component). diff --git a/lib/bitstyles_phoenix/alpine3/dropdown.ex b/lib/bitstyles_phoenix/alpine3/dropdown.ex index 64b73d5..5e8ac50 100644 --- a/lib/bitstyles_phoenix/alpine3/dropdown.ex +++ b/lib/bitstyles_phoenix/alpine3/dropdown.ex @@ -43,6 +43,8 @@ defmodule BitstylesPhoenix.Alpine3.Dropdown do ...> ...> ...> """ + ''', + ''' """
- """ - ''') - - story("Default link", ''' - iex> assigns = %{} - ...> render ~H""" - ...> <.ui_button href="/" variant="ui"> - ...> Publish - ...> - ...> """ - """ - - Publish - - """ - ''') - - story("Default disabled link renders disabled button instead", ''' - iex> assigns = %{} - ...> render ~H""" - ...> <.ui_button href="/" variant="ui" disabled> - ...> Publish - ...> - ...> """ - """ - - """ - ''') - - story("Default submit button", ''' - iex> assigns = %{} - ...> render ~H""" - ...> <.ui_button type="submit"> - ...> Save - ...> - ...> """ - """ - - """ - ''') - - story("Default submit button with custom classes", ''' - iex> assigns = %{} - ...> render ~H""" - ...> <.ui_button type="submit" class="foo bar"> - ...> Save - ...> - ...> """ - """ - - """ - ''') - - story("UI button", ''' - iex> assigns = %{} - ...> render ~H""" - ...> <.ui_button type="submit" variant={:ui}> - ...> Save - ...> - ...> """ - """ - - """ - ''') - - story("Dangerous button", ''' - iex> assigns = %{} - ...> render ~H""" - ...> <.ui_button type="submit" variant={:danger}> - ...> Save - ...> - ...> """ - """ - - """ - ''') + story( + "Default button", + ''' + iex> assigns = %{} + ...> render ~H""" + ...> <.ui_button> + ...> Publish + ...> + ...> """ + ''', + ''' + """ + + """ + ''' + ) + + story( + "Default link", + ''' + iex> assigns = %{} + ...> render ~H""" + ...> <.ui_button href="/" variant="ui"> + ...> Publish + ...> + ...> """ + ''', + ''' + """ + + Publish + + """ + ''' + ) + + story( + "Default disabled link renders disabled button instead", + ''' + iex> assigns = %{} + ...> render ~H""" + ...> <.ui_button href="/" variant="ui" disabled> + ...> Publish + ...> + ...> """ + ''', + ''' + """ + + """ + ''' + ) + + story( + "Default submit button", + ''' + iex> assigns = %{} + ...> render ~H""" + ...> <.ui_button type="submit"> + ...> Save + ...> + ...> """ + ''', + ''' + """ + + """ + ''' + ) + + story( + "Default submit button with custom classes", + ''' + iex> assigns = %{} + ...> render ~H""" + ...> <.ui_button type="submit" class="foo bar"> + ...> Save + ...> + ...> """ + ''', + ''' + """ + + """ + ''' + ) + + story( + "UI button", + ''' + iex> assigns = %{} + ...> render ~H""" + ...> <.ui_button type="submit" variant={:ui}> + ...> Save + ...> + ...> """ + ''', + ''' + """ + + """ + ''' + ) + + story( + "Dangerous button", + ''' + iex> assigns = %{} + ...> render ~H""" + ...> <.ui_button type="submit" variant={:danger}> + ...> Save + ...> + ...> """ + ''', + ''' + """ + + """ + ''' + ) story( "Button with an icon", @@ -133,6 +168,8 @@ defmodule BitstylesPhoenix.Component.Button do ...> Add ...> ...> """ + ''', + ''' """ - """ - ''') + story( + "Icon button with some options", + ''' + iex> assigns = %{} + ...> render ~H""" + ...> <.ui_icon_button icon={{"bin", file: "assets/icons.svg", size: "xl"}} label="Delete" class="foo" /> + ...> """ + ''', + ''' + """ + + """ + ''' + ) story( "Icon button reversed", @@ -364,6 +420,8 @@ defmodule BitstylesPhoenix.Component.Button do ...> render ~H""" ...> <.ui_icon_button icon="plus" label="Show" href="#" reversed /> ...> """ + ''', + ''' """

Hello world

...> """ + ''', + ''' """

@@ -35,6 +37,8 @@ defmodule BitstylesPhoenix.Component.Card do ...> render ~H""" ...> <.ui_card size="l">

Hello world

...> """ + ''', + ''' """

@@ -55,6 +59,8 @@ defmodule BitstylesPhoenix.Component.Card do ...>

Hello world

...> ...> """ + ''', + ''' """
@@ -80,6 +86,8 @@ defmodule BitstylesPhoenix.Component.Card do ...>

Hello world

...> ...> """ + ''', + ''' """
diff --git a/lib/bitstyles_phoenix/component/content.ex b/lib/bitstyles_phoenix/component/content.ex index db03d90..c869a7e 100644 --- a/lib/bitstyles_phoenix/component/content.ex +++ b/lib/bitstyles_phoenix/component/content.ex @@ -26,6 +26,8 @@ defmodule BitstylesPhoenix.Component.Content do ...> Content ...> ...> """ + ''', + ''' """
Content @@ -44,6 +46,8 @@ defmodule BitstylesPhoenix.Component.Content do ...> Full Content ...> ...> """ + ''', + ''' """
Full Content @@ -62,6 +66,8 @@ defmodule BitstylesPhoenix.Component.Content do ...> Content with extra ...> ...> """ + ''', + ''' """
Content with extra diff --git a/lib/bitstyles_phoenix/component/description_list.ex b/lib/bitstyles_phoenix/component/description_list.ex index 38dbf10..62be529 100644 --- a/lib/bitstyles_phoenix/component/description_list.ex +++ b/lib/bitstyles_phoenix/component/description_list.ex @@ -15,6 +15,8 @@ defmodule BitstylesPhoenix.Component.DescriptionList do ...> <.ui_dl_item label="Inserted at">2007-01-02 ...> ...> """ + ''', + ''' """
@@ -57,6 +59,8 @@ defmodule BitstylesPhoenix.Component.DescriptionList do ...> ...> ...> """ + ''', + ''' """
...> """ + ''', + ''' """
@@ -175,6 +208,8 @@ defmodule BitstylesPhoenix.Component.Dropdown do ...> ...> ...> """ + ''', + ''' """
...> """ + ''', + ''' """
@@ -288,6 +325,8 @@ defmodule BitstylesPhoenix.Component.Dropdown do ...> ...> ...> """ + ''', + ''' """
...> """ + ''', + ''' """
diff --git a/lib/bitstyles_phoenix/component/error.ex b/lib/bitstyles_phoenix/component/error.ex index d330f4d..066f824 100644 --- a/lib/bitstyles_phoenix/component/error.ex +++ b/lib/bitstyles_phoenix/component/error.ex @@ -23,38 +23,55 @@ defmodule BitstylesPhoenix.Component.Error do Uses the `translate_errors` MFA from the config to translate field errors (e.g. with `gettext`). """ - story("A single error", ''' - iex> assigns = %{form: @form_with_errors} - ...> render ~H""" - ...> <.ui_errors form={@form} field={:single} /> - ...> """ - """ - - is too short - - """ - ''') - - story("Multiple errors", ''' - iex> assigns = %{form: @form_with_errors} - ...> render ~H""" - ...> <.ui_errors form={@form} field={:multiple} /> - ...> """ - """ -
    -
  • - - is simply bad - -
  • -
  • - - not fun - -
  • -
- """ - ''') + story( + "A single error", + ''' + iex> assigns = %{form: form_with_errors()} + ...> render ~H""" + ...> <.ui_errors form={@form} field={:name} /> + ...> """ + ''', + "4.3.0": ''' + """ + + is too short + + """ + ''', + "3.0.0": ''' + """ + + is too short + + """ + ''' + ) + + story( + "Multiple errors", + ''' + iex> assigns = %{form: form_with_errors()} + ...> render ~H""" + ...> <.ui_errors form={@form} field={:email} /> + ...> """ + ''', + ''' + """ +
    +
  • + + is invalid + +
  • +
  • + + must end with @bitcrowd.net + +
  • +
+ """ + ''' + ) def ui_errors(assigns) do assigns.form.errors @@ -106,29 +123,46 @@ defmodule BitstylesPhoenix.Component.Error do specified in [bitstyles colors](https://bitcrowd.github.io/bitstyles/?path=/docs/utilities-fg--warning). """ - story("An error tag", ''' - iex> assigns = %{} - ...> render ~H""" - ...> <.ui_error error={{"Foo error", []}} /> - ...> """ - """ - - Foo error - - """ - ''') - - story("An error tag extra options and classes", ''' - iex> assigns = %{error: {"Foo error", []}} - ...> render ~H""" - ...> <.ui_error error={@error} phx-feedback-for="foo" class="bar" /> - ...> """ - """ - - Foo error - - """ - ''') + story( + "An error tag", + ''' + iex> assigns = %{} + ...> render ~H""" + ...> <.ui_error error={{"Foo error", []}} /> + ...> """ + ''', + "4.3.0": ''' + """ + + Foo error + + """ + ''', + "3.0.0": ''' + """ + + Foo error + + """ + ''' + ) + + story( + "An error tag extra options and classes", + ''' + iex> assigns = %{error: {"Foo error", []}} + ...> render ~H""" + ...> <.ui_error error={@error} phx-feedback-for="foo" class="bar" /> + ...> """ + ''', + ''' + """ + + Foo error + + """ + ''' + ) def ui_error(assigns) do extra = assigns_to_attributes(assigns, [:class, :error, :field, :form]) diff --git a/lib/bitstyles_phoenix/component/flash.ex b/lib/bitstyles_phoenix/component/flash.ex index 49b0823..eb03fd4 100644 --- a/lib/bitstyles_phoenix/component/flash.ex +++ b/lib/bitstyles_phoenix/component/flash.ex @@ -35,6 +35,8 @@ defmodule BitstylesPhoenix.Component.Flash do ...> Something you may be interested to hear ...> ...> """) + ''', + ''' """
@@ -55,6 +57,8 @@ defmodule BitstylesPhoenix.Component.Flash do ...> Saved successfully ...> ...> """) + ''', + ''' """
@@ -75,6 +79,8 @@ defmodule BitstylesPhoenix.Component.Flash do ...> Saved with errors ...> ...> """) + ''', + ''' """
@@ -95,6 +101,8 @@ defmodule BitstylesPhoenix.Component.Flash do ...> Saving failed ...> ...> """) + ''', + ''' """
@@ -115,6 +123,8 @@ defmodule BitstylesPhoenix.Component.Flash do ...> Saving failed ...> ...> """) + ''', + ''' """
@@ -135,6 +145,8 @@ defmodule BitstylesPhoenix.Component.Flash do ...> Saving failed ...> ...> """) + ''', + ''' """
diff --git a/lib/bitstyles_phoenix/component/form.ex b/lib/bitstyles_phoenix/component/form.ex index b9a3ce7..7b542ae 100644 --- a/lib/bitstyles_phoenix/component/form.ex +++ b/lib/bitstyles_phoenix/component/form.ex @@ -66,221 +66,286 @@ defmodule BitstylesPhoenix.Component.Form do See the [bitstyles form docs](https://bitcrowd.github.io/bitstyles/?path=/docs/ui-data-forms--login-form) for examples of form layouts. """ - story("Text field with label", ''' - iex> assigns=%{form: @form} - ...> render ~H""" - ...> <.ui_input form={@form} field={:name} /> - ...> """ - """ - - - """ - ''') - - story("Text required field with label", ''' - iex> assigns=%{form: @form} - ...> render ~H""" - ...> <.ui_input form={@form} field={:name} required/> - ...> """ - """ - - - """ - ''') - - story("Text field with error", ''' - iex> assigns=%{form: @form_with_errors} - ...> render ~H""" - ...> <.ui_input form={@form} field={:name} /> - ...> """ - """ - - - - is too short - - """ - ''') - - story("Text field with multiple errors", ''' - iex> assigns=%{form: @form_with_errors} - ...> render ~H""" - ...> <.ui_input form={@form} field={:email} /> - ...> """ - """ - - -
    -
  • - - is invalid + """ + ''' + ) + + story( + "Text field with multiple errors", + ''' + iex> assigns=%{form: form_with_errors()} + ...> render ~H""" + ...> <.ui_input form={@form} field={:email} /> + ...> """ + ''', + ''' + """ + + +
      +
    • + + is invalid + +
    • +
    • + + must end with @bitcrowd.net + +
    • +
    + """ + ''' + ) + + story( + "Text field with hidden label", + ''' + iex> assigns=%{form: form()} + ...> render ~H""" + ...> <.ui_input form={@form} field={:name} hidden_label={true} /> + ...> """ + ''', + ''' + """ + + + """ + ''' + ) + + story( + "Text field with label (without maxlength)", + ''' + iex> assigns=%{form: form()} + ...> render ~H""" + ...> <.ui_input form={@form} field={:name} maxlength={false}/> + ...> """ + ''', + ''' + """ + + + """ + ''' + ) + + story( + "Text field with options", + ''' + iex> assigns=%{form: form()} + ...> render ~H""" + ...> <.ui_input + ...> form={@form} + ...> field={:totp} + ...> label="Authentication code" + ...> label_opts={[class: "extra"]} + ...> placeholder="6-digit code" + ...> required={true} + ...> value="" + ...> inputmode="numeric" + ...> pattern="[0-9]*" + ...> autocomplete="one-time-code" + ...> maxlength={6} /> + ...> """ + ''', + ''' + """ +
  • -
  • - - must end with @bitcrowd.net + + + """ + ''' + ) + + story( + "Email field with label", + ''' + iex> assigns=%{form: form()} + ...> render ~H""" + ...> <.ui_input form={@form} field={:email} type={:email} /> + ...> """ + ''', + ''' + """ + + + """ + ''' + ) + + story( + "Search field with placholder", + ''' + iex> assigns=%{form: form()} + ...> render ~H""" + ...> <.ui_input + ...> form={@form} + ...> field={:email_or_name} + ...> type={:search} + ...> placeholder="Search by email or name" + ...> autofocus={true} /> + ...> """ + ''', + ''' + """ + + + """ + ''' + ) + + story( + "File field for pdfs", + ''' + iex> assigns=%{form: form()} + ...> render ~H""" + ...> + ...> <.ui_input form={form} field={:file} type={:file} accept="application/pdf" /> + ...> + ...> """ + ''', + ''' + """ +
    + + +
    + """ + ''' + ) + + story( + "Checkbox", + ''' + iex> assigns=%{form: form()} + ...> render ~H""" + ...> <.ui_input form={@form} field={:accept} type={:checkbox} /> + ...> """ + ''', + ''' + """ + + """ + ''' + ) + + story( + "Checkbox required", + ''' + iex> assigns=%{form: form()} + ...> render ~H""" + ...> <.ui_input form={@form} field={:accept} type={:checkbox} required/> + ...> """ + ''', + ''' + """ +
  • -
- """ - ''') - - story("Text field with hidden label", ''' - iex> assigns=%{form: @form} - ...> render ~H""" - ...> <.ui_input form={@form} field={:name} hidden_label={true} /> - ...> """ - """ - - - """ - ''') - - story("Text field with label (without maxlength)", ''' - iex> assigns=%{form: @form} - ...> render ~H""" - ...> <.ui_input form={@form} field={:name} maxlength={false}/> - ...> """ - """ - - - """ - ''') - - story("Text field with options", ''' - iex> assigns=%{form: @form} - ...> render ~H""" - ...> <.ui_input - ...> form={@form} - ...> field={:totp} - ...> label="Authentication code" - ...> label_opts={[class: "extra"]} - ...> placeholder="6-digit code" - ...> required={true} - ...> value="" - ...> inputmode="numeric" - ...> pattern="[0-9]*" - ...> autocomplete="one-time-code" - ...> maxlength={6} /> - ...> """ - """ - - - """ - ''') - - story("Email field with label", ''' - iex> assigns=%{form: @form} - ...> render ~H""" - ...> <.ui_input form={@form} field={:email} type={:email} /> - ...> """ - """ - - - """ - ''') - - story("Search field with placholder", ''' - iex> assigns=%{form: @form} - ...> render ~H""" - ...> <.ui_input - ...> form={@form} - ...> field={:email_or_name} - ...> type={:search} - ...> placeholder="Search by email or name" - ...> autofocus={true} /> - ...> """ - """ - - - """ - ''') - - story("File field for pdfs", ''' - iex> assigns=%{form: @form} - ...> render ~H""" - ...> - ...> <.ui_input form={form} field={:file} type={:file} accept="application/pdf" /> - ...> - ...> """ - """ -
- - -
- """ - ''') - - story("Checkbox", ''' - iex> assigns=%{form: @form} - ...> render ~H""" - ...> <.ui_input form={@form} field={:accept} type={:checkbox} /> - ...> """ - """ - - """ - ''') - - story("Checkbox required", ''' - iex> assigns=%{form: @form} - ...> render ~H""" - ...> <.ui_input form={@form} field={:accept} type={:checkbox} required/> - ...> """ - """ - - """ - ''') - - story("Checkbox with label class", ''' - iex> assigns=%{form: @form} - ...> render ~H""" - ...> <.ui_input form={@form} field={:accept} type={:checkbox} label_opts={[class: "extra"]}/> - ...> """ - """ - - """ - ''') + """ + ''' + ) + + story( + "Checkbox with label class", + ''' + iex> assigns=%{form: form()} + ...> render ~H""" + ...> <.ui_input form={@form} field={:accept} type={:checkbox} label_opts={[class: "extra"]}/> + ...> """ + ''', + ''' + """ + + """ + ''' + ) def ui_input(assigns) do extra = assigns_to_attributes(assigns, @wrapper_assigns_keys ++ [:type]) @@ -330,89 +395,114 @@ defmodule BitstylesPhoenix.Component.Form do See the [bitstyles textarea docs](https://bitcrowd.github.io/bitstyles/?path=/docs/base-forms--textarea-and-label) for examples of textareas and labels in use. """ - story("Textarea", ''' - iex> assigns=%{form: @form} - ...> render ~H""" - ...> <.ui_textarea form={@form} field={:about_me} /> - ...> """ - """ - - - """ - ''') - - story("Textarea", ''' - iex> assigns=%{form: @form} - ...> render ~H""" - ...> <.ui_textarea form={@form} field={:about_me} required/> - ...> """ - """ - - - """ - ''') - - story("Textarea with options", ''' - iex> assigns=%{form: @form} - ...> render ~H""" - ...> <.ui_textarea - ...> form={@form} - ...> field={:metadata} - ...> label="Metadata" - ...> label_opts={[class: "extra"]} - ...> value="Value here" - ...> rows={10} - ...> /> - ...> """ - """ - - - """ - ''') - - story("Textarea with hidden label", ''' - iex> assigns=%{form: @form} - ...> render ~H""" - ...> <.ui_textarea form={@form} field={:address} hidden_label/> - ...> """ - """ - - - """ - ''') - - story("Textarea with error", ''' - iex> assigns=%{form: @form_with_errors} - ...> render ~H""" - ...> <.ui_textarea form={@form} field={:name} /> - ...> """ - """ - - - - is too short - - """ - ''') + """ + ''' + ) def ui_textarea(assigns) do extra = assigns_to_attributes(assigns, @wrapper_assigns_keys) @@ -442,88 +532,108 @@ defmodule BitstylesPhoenix.Component.Form do See the [bitstyles select docs](https://bitcrowd.github.io/bitstyles/?path=/docs/base-forms--select-and-label) for examples of textareas and labels in use. """ - story("Select box", ''' - iex> assigns=%{form: @form} - ...> render ~H""" - ...> <.ui_select form={@form} field={:week} options={1..2} /> - ...> """ - """ - - - """ - ''') - - story("Select box required", ''' - iex> assigns=%{form: @form} - ...> render ~H""" - ...> <.ui_select form={@form} field={:week} options={1..2} required /> - ...> """ - """ - - - """ - ''') - - story("Select box without label", ''' - iex> assigns=%{form: @form} - ...> render ~H""" - ...> <.ui_select form={@form} field={:week} options={1..2} hidden_label/> - ...> """ - """ - - - """ - ''') - - story("Select box with options", ''' - iex> assigns=%{form: @form, options: [{"Ducks", "ducks"}, {"Cats", "cats"}]} - ...> render ~H""" - ...> <.ui_select form={@form} field={:preference} options={@options} label="What do you like best?" label_opts={[class: "extra"]}/> - ...> """ - """ - - - """ - ''') + story( + "Select box", + ''' + iex> assigns=%{form: form()} + ...> render ~H""" + ...> <.ui_select form={@form} field={:week} options={1..2} /> + ...> """ + ''', + ''' + """ + + + """ + ''' + ) + + story( + "Select box required", + ''' + iex> assigns=%{form: form()} + ...> render ~H""" + ...> <.ui_select form={@form} field={:week} options={1..2} required /> + ...> """ + ''', + ''' + """ + + + """ + ''' + ) + + story( + "Select box without label", + ''' + iex> assigns=%{form: form()} + ...> render ~H""" + ...> <.ui_select form={@form} field={:week} options={1..2} hidden_label/> + ...> """ + ''', + ''' + """ + + + """ + ''' + ) + + story( + "Select box with options", + ''' + iex> assigns=%{form: form(), options: [{"Ducks", "ducks"}, {"Cats", "cats"}]} + ...> render ~H""" + ...> <.ui_select form={@form} field={:preference} options={@options} label="What do you like best?" label_opts={[class: "extra"]}/> + ...> """ + ''', + ''' + """ + + + """ + ''' + ) def ui_select(assigns) do extra = assigns_to_attributes(assigns, @wrapper_assigns_keys ++ [:options]) @@ -553,25 +663,30 @@ defmodule BitstylesPhoenix.Component.Form do - All options from above (see top level module doc). """ - story("Custom inputs", ''' - iex> assigns=%{form: @form_with_errors} - ...> render ~H""" - ...> <.ui_unwrapped_input form={@form} field={:name} label="Custom"> - ...> Custom content - ...> - ...> - ...> """ - """ - - Custom content - - - is too short - - """ - ''') + story( + "Custom inputs", + ''' + iex> assigns=%{form: form_with_errors()} + ...> render ~H""" + ...> <.ui_unwrapped_input form={@form} field={:name} label="Custom"> + ...> Custom content + ...> + ...> + ...> """ + ''', + ''' + """ + + Custom content + + + is too short + + """ + ''' + ) def ui_unwrapped_input(assigns) do label_text = Map.get_lazy(assigns, :label, fn -> default_label(assigns.field) end) @@ -604,20 +719,25 @@ defmodule BitstylesPhoenix.Component.Form do - All options from above (see top level module doc). """ - story("Custom wrapped inputs", ''' - iex> assigns=%{form: @form} - ...> render ~H""" - ...> <.ui_wrapped_input form={@form} field={:name} label="Current name"> - ...> - ...> - ...> """ - """ - - """ - ''') + story( + "Custom wrapped inputs", + ''' + iex> assigns=%{form: form()} + ...> render ~H""" + ...> <.ui_wrapped_input form={@form} field={:name} label="Current name"> + ...> + ...> + ...> """ + ''', + ''' + """ + + """ + ''' + ) def ui_wrapped_input(assigns) do assigns = diff --git a/lib/bitstyles_phoenix/component/heading.ex b/lib/bitstyles_phoenix/component/heading.ex index c97a856..2899685 100644 --- a/lib/bitstyles_phoenix/component/heading.ex +++ b/lib/bitstyles_phoenix/component/heading.ex @@ -35,6 +35,8 @@ defmodule BitstylesPhoenix.Component.Heading do ...> Title ...> ...> """ + ''', + ''' """
@@ -69,6 +71,8 @@ defmodule BitstylesPhoenix.Component.Heading do ...> ...> ...> """ + ''', + ''' """
@@ -161,6 +165,8 @@ defmodule BitstylesPhoenix.Component.Heading do ...> Section title ...> ...> """ + ''', + ''' """
@@ -183,6 +189,8 @@ defmodule BitstylesPhoenix.Component.Heading do ...> Section title ...> ...> """ + ''', + ''' """
@@ -217,6 +225,8 @@ defmodule BitstylesPhoenix.Component.Heading do ...> ...> ...> """ + ''', + ''' """
diff --git a/lib/bitstyles_phoenix/component/icon.ex b/lib/bitstyles_phoenix/component/icon.ex index 55cce72..5b59f21 100644 --- a/lib/bitstyles_phoenix/component/icon.ex +++ b/lib/bitstyles_phoenix/component/icon.ex @@ -31,6 +31,8 @@ defmodule BitstylesPhoenix.Component.Icon do ...> render ~H""" ...> <.ui_icon name="inline-arrow"/> ...> """ + ''', + ''' """