noahsettersten commited on
Commit
24d78ad
1 Parent(s): 662eaac

chore: Run `mix phx.gen.storybook`

Browse files
assets/css/storybook.css ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* This is your custom storybook stylesheet. */
2
+ @import "tailwindcss/base";
3
+ @import "tailwindcss/components";
4
+ @import "tailwindcss/utilities";
5
+
6
+ /*
7
+ * Put your component styling within the Tailwind utilities layer.
8
+ * See the https://hexdocs.pm/phoenix_storybook/sandboxing.html guide for more info.
9
+ */
10
+
11
+ @layer utilities {
12
+ * {
13
+ font-family: system-ui;
14
+ }
15
+ }
assets/js/storybook.js ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // If your components require any hooks or custom uploaders, or if your pages
2
+ // require connect parameters, uncomment the following lines and declare them as
3
+ // such:
4
+ //
5
+ // import * as Hooks from "./hooks";
6
+ // import * as Params from "./params";
7
+ // import * as Uploaders from "./uploaders";
8
+
9
+ // (function () {
10
+ // window.storybook = { Hooks, Params, Uploaders };
11
+ // })();
12
+
13
+
14
+ // If your components require alpinejs, you'll need to start
15
+ // alpine after the DOM is loaded and pass in an onBeforeElUpdated
16
+ //
17
+ // import Alpine from 'alpinejs'
18
+ // window.Alpine = Alpine
19
+ // document.addEventListener('DOMContentLoaded', () => {
20
+ // window.Alpine.start();
21
+ // });
22
+
23
+ // (function () {
24
+ // window.storybook = {
25
+ // LiveSocketOptions: {
26
+ // dom: {
27
+ // onBeforeElUpdated(from, to) {
28
+ // if (from._x_dataStack) {
29
+ // window.Alpine.clone(from, to)
30
+ // }
31
+ // }
32
+ // }
33
+ // }
34
+ // };
35
+ // })();
lib/medical_transcription_web/storybook.ex ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ defmodule MedicalTranscriptionWeb.Storybook do
2
+ use PhoenixStorybook,
3
+ otp_app: :medical_transcription_web,
4
+ content_path: Path.expand("../../storybook", __DIR__),
5
+ # assets path are remote path, not local file-system paths
6
+ css_path: "/assets/storybook.css",
7
+ js_path: "/assets/storybook.js",
8
+ sandbox_class: "medical-transcription-web"
9
+ end
storybook/_root.index.exs ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ defmodule Storybook.Root do
2
+ # See https://hexdocs.pm/phoenix_storybook/PhoenixStorybook.Index.html for full index
3
+ # documentation.
4
+
5
+ use PhoenixStorybook.Index
6
+
7
+ def folder_icon, do: {:fa, "book-open", :light, "psb-mr-1"}
8
+ def folder_name, do: "Storybook"
9
+
10
+ def entry("welcome") do
11
+ [
12
+ name: "Welcome Page",
13
+ icon: {:fa, "hand-wave", :thin}
14
+ ]
15
+ end
16
+ end
storybook/core_components/button.story.exs ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ defmodule Storybook.CoreComponents.Button do
2
+ use PhoenixStorybook.Story, :component
3
+
4
+ def function, do: &MedicalTranscriptionWeb.CoreComponents.button/1
5
+
6
+ def variations do
7
+ [
8
+ %Variation{
9
+ id: :default,
10
+ slots: ["Button"]
11
+ },
12
+ %Variation{
13
+ id: :custom_class,
14
+ attributes: %{
15
+ class: "rounded-full bg-indigo-500 hover:bg-indigo-600"
16
+ },
17
+ slots: ["Disabled"]
18
+ },
19
+ %Variation{
20
+ id: :disabled,
21
+ attributes: %{
22
+ disabled: true
23
+ },
24
+ slots: ["Disabled"]
25
+ }
26
+ ]
27
+ end
28
+ end
storybook/core_components/flash.story.exs ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ defmodule Storybook.CoreComponents.Flash do
2
+ use PhoenixStorybook.Story, :component
3
+ alias MedicalTranscriptionWeb.CoreComponents
4
+
5
+ def function, do: &CoreComponents.flash/1
6
+ def imports, do: [{CoreComponents, [button: 1, show: 1]}]
7
+
8
+ def template do
9
+ """
10
+ <.button phx-click={show("#:variation_id")} psb-code-hidden>
11
+ Open flash
12
+ </.button>
13
+ <.psb-variation/>
14
+ """
15
+ end
16
+
17
+ def variations do
18
+ [
19
+ %Variation{
20
+ id: :info_no_title,
21
+ attributes: %{
22
+ kind: :info,
23
+ hidden: true
24
+ },
25
+ slots: ["Info message"]
26
+ },
27
+ %Variation{
28
+ id: :error_with_title,
29
+ attributes: %{
30
+ kind: :error,
31
+ hidden: true,
32
+ title: "Flash title"
33
+ },
34
+ slots: ["Error message"]
35
+ },
36
+ %Variation{
37
+ id: :no_close_button,
38
+ attributes: %{
39
+ kind: :info,
40
+ hidden: true,
41
+ close: false
42
+ },
43
+ slots: ["Info message"]
44
+ }
45
+ ]
46
+ end
47
+ end
storybook/core_components/header.story.exs ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ defmodule Storybook.CoreComponents.Header do
2
+ use PhoenixStorybook.Story, :component
3
+ alias MedicalTranscriptionWeb.CoreComponents
4
+
5
+ def function, do: &CoreComponents.header/1
6
+ def imports, do: [{CoreComponents, button: 1}]
7
+
8
+ def variations do
9
+ [
10
+ %Variation{
11
+ id: :default,
12
+ slots: [
13
+ "Hello World"
14
+ ]
15
+ },
16
+ %Variation{
17
+ id: :with_a_subtitle,
18
+ slots: [
19
+ "Hello World",
20
+ "<:subtitle>I'm a header subtitle</:subtitle>"
21
+ ]
22
+ },
23
+ %Variation{
24
+ id: :with_actions,
25
+ slots: [
26
+ "Hello World",
27
+ "<:subtitle>I'm a header subtitle</:subtitle>",
28
+ """
29
+ <:actions>
30
+ <.button>Link</.button>
31
+ </:actions>
32
+ """
33
+ ]
34
+ }
35
+ ]
36
+ end
37
+ end
storybook/core_components/input.story.exs ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ defmodule Storybook.CoreComponents.Input do
2
+ use PhoenixStorybook.Story, :component
3
+ alias MedicalTranscriptionWeb.CoreComponents
4
+
5
+ def function, do: &CoreComponents.input/1
6
+ def imports, do: [{CoreComponents, [simple_form: 1]}]
7
+
8
+ def template do
9
+ """
10
+ <.simple_form :let={f} for={%{}} as={:story} class="w-full">
11
+ <.psb-variation-group field={f[:field]}/>
12
+ </.simple_form>
13
+ """
14
+ end
15
+
16
+ def variations do
17
+ [
18
+ %VariationGroup{
19
+ id: :basic_inputs,
20
+ variations:
21
+ for type <- ~w(text textarea number date color range checkbox)a do
22
+ %Variation{
23
+ id: type,
24
+ attributes: %{
25
+ type: to_string(type),
26
+ label: String.capitalize("#{type} input")
27
+ }
28
+ }
29
+ end
30
+ },
31
+ %Variation{
32
+ id: :select,
33
+ attributes: %{
34
+ label: "Select input",
35
+ type: "select",
36
+ options: ["Option 1", "Option 2", "Option 3"]
37
+ }
38
+ }
39
+ ]
40
+ end
41
+ end
storybook/core_components/list.story.exs ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ defmodule Storybook.CoreComponents.List do
2
+ use PhoenixStorybook.Story, :component
3
+
4
+ def function, do: &MedicalTranscriptionWeb.CoreComponents.list/1
5
+
6
+ def variations do
7
+ [
8
+ %Variation{
9
+ id: :default,
10
+ slots: [
11
+ ~s|<:item title="Title">Elixir</:item>|,
12
+ ~s|<:item title="Rating">5/5</:item>|
13
+ ]
14
+ }
15
+ ]
16
+ end
17
+ end
storybook/core_components/modal.story.exs ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ defmodule Storybook.CoreComponents.Modal do
2
+ use PhoenixStorybook.Story, :component
3
+ alias MedicalTranscriptionWeb.CoreComponents
4
+
5
+ def function, do: &CoreComponents.modal/1
6
+ def imports, do: [{CoreComponents, [button: 1, hide_modal: 1, show_modal: 1]}]
7
+
8
+ def template do
9
+ """
10
+ <.button phx-click={show_modal(":variation_id")} psb-code-hidden>
11
+ Open modal
12
+ </.button>
13
+ <.psb-variation/>
14
+ """
15
+ end
16
+
17
+ def variations do
18
+ [
19
+ %Variation{
20
+ id: :default,
21
+ slots: ["Modal body"]
22
+ }
23
+ ]
24
+ end
25
+ end
storybook/core_components/table.story.exs ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ defmodule Storybook.CoreComponents.Table do
2
+ use PhoenixStorybook.Story, :component
3
+ alias MedicalTranscriptionWeb.CoreComponents
4
+
5
+ def function, do: &CoreComponents.table/1
6
+ def aliases, do: [Storybook.CoreComponents.Table.User]
7
+
8
+ def variations do
9
+ [
10
+ %Variation{
11
+ id: :table,
12
+ attributes: %{
13
+ rows:
14
+ {:eval,
15
+ ~s"""
16
+ [
17
+ %User{id: 1, username: "jose"},
18
+ %User{id: 2, username: "chris"}
19
+ ]
20
+ """}
21
+ },
22
+ slots: [
23
+ """
24
+ <:col :let={user} label="Id">
25
+ <%= user.id %>
26
+ </:col>
27
+ """,
28
+ """
29
+ <:col :let={user} label="User name">
30
+ <%= user.username %>
31
+ </:col>
32
+ """
33
+ ]
34
+ }
35
+ ]
36
+ end
37
+ end
38
+
39
+ defmodule Storybook.CoreComponents.Table.User do
40
+ defstruct [:id, :username]
41
+ end
storybook/examples/core_components.story.exs ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ defmodule Storybook.Examples.CoreComponents do
2
+ use PhoenixStorybook.Story, :example
3
+ import MedicalTranscriptionWeb.CoreComponents
4
+
5
+ alias Phoenix.LiveView.JS
6
+
7
+ def doc do
8
+ "An example of what you can achieve with Phoenix core components."
9
+ end
10
+
11
+ defstruct [:id, :first_name, :last_name]
12
+
13
+ @impl true
14
+ def mount(_params, _session, socket) do
15
+ {:ok,
16
+ assign(socket,
17
+ current_id: 2,
18
+ users: [
19
+ %__MODULE__{id: 1, first_name: "Jose", last_name: "Valim"},
20
+ %__MODULE__{
21
+ id: 2,
22
+ first_name: "Chris",
23
+ last_name: "McCord"
24
+ }
25
+ ]
26
+ )}
27
+ end
28
+
29
+ @impl true
30
+ def render(assigns) do
31
+ ~H"""
32
+ <.header>
33
+ List of users
34
+ <:subtitle>Feel free to add any missing user!</:subtitle>
35
+ <:actions>
36
+ <.button phx-click={show_modal("new-user-modal")}>Create user</.button>
37
+ </:actions>
38
+ </.header>
39
+ <.table id="user-table" rows={@users}>
40
+ <:col :let={user} label="Id">
41
+ <%= user.id %>
42
+ </:col>
43
+ <:col :let={user} label="First name">
44
+ <%= user.first_name %>
45
+ </:col>
46
+ <:col :let={user} label="Last name">
47
+ <%= user.last_name %>
48
+ </:col>
49
+ </.table>
50
+ <.modal id="new-user-modal">
51
+ <.header>
52
+ Create new user
53
+ <:subtitle>This won't be persisted into DB, memory only</:subtitle>
54
+ </.header>
55
+ <.simple_form
56
+ :let={f}
57
+ for={%{}}
58
+ as={:user}
59
+ phx-submit={JS.push("save_user") |> hide_modal("new-user-modal")}
60
+ >
61
+ <.input field={f[:first_name]} label="First name" />
62
+ <.input field={f[:last_name]} label="Last name" />
63
+ <:actions>
64
+ <.button>Save user</.button>
65
+ </:actions>
66
+ </.simple_form>
67
+ </.modal>
68
+ """
69
+ end
70
+
71
+ @impl true
72
+ def handle_event("save_user", %{"user" => params}, socket) do
73
+ user = %__MODULE__{
74
+ first_name: params["first_name"],
75
+ last_name: params["last_name"],
76
+ id: socket.assigns.current_id + 1
77
+ }
78
+
79
+ {:noreply,
80
+ socket
81
+ |> update(:users, &(&1 ++ [user]))
82
+ |> update(:current_id, &(&1 + 1))}
83
+ end
84
+ end
storybook/welcome.story.exs ADDED
@@ -0,0 +1,100 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ defmodule Storybook.MyPage do
2
+ # See https://hexdocs.pm/phoenix_storybook/PhoenixStorybook.Story.html for full story
3
+ # documentation.
4
+ use PhoenixStorybook.Story, :page
5
+
6
+ def doc, do: "Your very first steps into using Phoenix Storybook"
7
+
8
+ # Declare an optional tab-based navigation in your page:
9
+ def navigation do
10
+ [
11
+ {:welcome, "Welcome", {:fa, "hand-wave", :thin}},
12
+ {:components, "Components", {:fa, "toolbox", :thin}},
13
+ {:sandboxing, "Sandboxing", {:fa, "box-check", :thin}},
14
+ {:icons, "Icons", {:fa, "icons", :thin}}
15
+ ]
16
+ end
17
+
18
+ # This is a dummy fonction that you should replace with your own HEEx content.
19
+ def render(assigns = %{tab: :welcome}) do
20
+ ~H"""
21
+ <div class="psb-welcome-page">
22
+ <p>
23
+ We generated your storybook with an example of a page and a component.
24
+ Explore the generated <code class="psb-inline">*.story.exs</code>
25
+ files in your <code class="inline">/storybook</code>
26
+ directory. When you're ready to add your own, just drop your new story & index files into the same directory and refresh your storybook.
27
+ </p>
28
+
29
+ <p>
30
+ Here are a few docs you might be interested in:
31
+ </p>
32
+
33
+ <.description_list items={[
34
+ {"Create a new Story", doc_link("Story")},
35
+ {"Display components using Variations", doc_link("Stories.Variation")},
36
+ {"Group components using VariationGroups", doc_link("Stories.VariationGroup")},
37
+ {"Organize the sidebar with Index files", doc_link("Index")}
38
+ ]} />
39
+
40
+ <p>
41
+ This should be enough to get you started, but you can use the tabs in the upper-right corner of this page to <strong>check out advanced usage guides</strong>.
42
+ </p>
43
+ </div>
44
+ """
45
+ end
46
+
47
+ def render(assigns = %{tab: guide}) when guide in ~w(components sandboxing icons)a do
48
+ assigns =
49
+ assign(assigns,
50
+ guide: guide,
51
+ guide_content: PhoenixStorybook.Guides.markup("#{guide}.md")
52
+ )
53
+
54
+ ~H"""
55
+ <p class="md:psb-text-lg psb-leading-relaxed psb-text-slate-400 psb-w-full psb-text-left psb-mb-4 psb-mt-2 psb-italic">
56
+ <a
57
+ class="hover:text-indigo-700"
58
+ href={"https://hexdocs.pm/phoenix_storybook/#{@guide}.html"}
59
+ target="_blank"
60
+ >
61
+ This and other guides are also available on HexDocs.
62
+ </a>
63
+ </p>
64
+ <div class="psb-welcome-page psb-border-t psb-border-gray-200 psb-pt-4">
65
+ <%= Phoenix.HTML.raw(@guide_content) %>
66
+ </div>
67
+ """
68
+ end
69
+
70
+ defp description_list(assigns) do
71
+ ~H"""
72
+ <div class="psb-w-full md:psb-px-8">
73
+ <div class="md:psb-border-t psb-border-gray-200 psb-px-4 psb-py-5 sm:psb-p-0 md:psb-my-6 psb-w-full">
74
+ <dl class="sm:psb-divide-y sm:psb-divide-gray-200">
75
+ <%= for {dt, link} <- @items do %>
76
+ <div class="psb-py-4 sm:psb-grid sm:psb-grid-cols-3 sm:psb-gap-4 sm:psb-py-5 sm:psb-px-6 psb-max-w-full">
77
+ <dt class="psb-text-base psb-font-medium psb-text-indigo-700">
78
+ <%= dt %>
79
+ </dt>
80
+ <dd class="psb-mt-1 psb-text-base psb-text-slate-400 sm:psb-col-span-2 sm:psb-mt-0 psb-group psb-cursor-pointer psb-max-w-full">
81
+ <a
82
+ class="group-hover:psb-text-indigo-700 psb-max-w-full psb-inline-block psb-truncate"
83
+ href={link}
84
+ target="_blank"
85
+ >
86
+ <%= link %>
87
+ </a>
88
+ </dd>
89
+ </div>
90
+ <% end %>
91
+ </dl>
92
+ </div>
93
+ </div>
94
+ """
95
+ end
96
+
97
+ defp doc_link(page) do
98
+ "https://hexdocs.pm/phoenix_storybook/PhoenixStorybook.#{page}.html"
99
+ end
100
+ end