Commit
•
24d78ad
1
Parent(s):
662eaac
chore: Run `mix phx.gen.storybook`
Browse files- assets/css/storybook.css +15 -0
- assets/js/storybook.js +35 -0
- lib/medical_transcription_web/storybook.ex +9 -0
- storybook/_root.index.exs +16 -0
- storybook/core_components/button.story.exs +28 -0
- storybook/core_components/flash.story.exs +47 -0
- storybook/core_components/header.story.exs +37 -0
- storybook/core_components/input.story.exs +41 -0
- storybook/core_components/list.story.exs +17 -0
- storybook/core_components/modal.story.exs +25 -0
- storybook/core_components/table.story.exs +41 -0
- storybook/examples/core_components.story.exs +84 -0
- storybook/welcome.story.exs +100 -0
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
|