diff --git a/apps/phoenix_webcomponent/assets/js/phoenix_webcomponent.js b/apps/phoenix_webcomponent/assets/js/phoenix_webcomponent.js index ba250cf2..e8a9efbc 100644 --- a/apps/phoenix_webcomponent/assets/js/phoenix_webcomponent.js +++ b/apps/phoenix_webcomponent/assets/js/phoenix_webcomponent.js @@ -1,6 +1,6 @@ import '@gsmlg/lit'; -const PhxWCHook = { +export const PhxWCHook = { mounted() { const attrs = this.el.attributes; const phxTarget = attrs["phx-target"].value; @@ -40,4 +40,6 @@ const PhxWCHook = { }, }; -window.__PhxWCHook__ = PhxWCHook; +if (window) { + window.__PhxWCHook__ = PhxWCHook; +} diff --git a/apps/phoenix_webcomponent/lib/phoenix_webcomponent.ex b/apps/phoenix_webcomponent/lib/phoenix_webcomponent.ex index bed7bacd..3e3c8270 100644 --- a/apps/phoenix_webcomponent/lib/phoenix_webcomponent.ex +++ b/apps/phoenix_webcomponent/lib/phoenix_webcomponent.ex @@ -27,15 +27,20 @@ defmodule Phoenix.WebComponent do quote do use Phoenix.LiveComponent - unquote(view_helpers()) + unquote(html_helpers()) end end - def component do + def html do quote do use Phoenix.Component - unquote(view_helpers()) + # Import convenience functions from controllers + import Phoenix.Controller, + only: [get_csrf_token: 0, view_module: 1, view_template: 1] + + # Include general helpers for rendering HTML + unquote(html_helpers()) end end @@ -51,16 +56,13 @@ defmodule Phoenix.WebComponent do end end - defp view_helpers do + defp html_helpers do quote do - # Use all HTML functionality (forms, tags, etc) - use Phoenix.HTML - - # Import LiveView and .heex helpers (live_render, live_patch, <.form>, etc) - import Phoenix.LiveView.Helpers + # HTML escaping functionality + import Phoenix.HTML - # Import basic rendering functionality (render, render_layout, etc) - import Phoenix.View + # Shortcut for generating JS commands + alias Phoenix.LiveView.JS end end diff --git a/apps/phoenix_webcomponent/lib/phoenix_webcomponent/actionbar.ex b/apps/phoenix_webcomponent/lib/phoenix_webcomponent/actionbar.ex index 4b88baa1..cff7b640 100644 --- a/apps/phoenix_webcomponent/lib/phoenix_webcomponent/actionbar.ex +++ b/apps/phoenix_webcomponent/lib/phoenix_webcomponent/actionbar.ex @@ -2,7 +2,7 @@ defmodule Phoenix.WebComponent.Actionbar do @moduledoc """ Render actionbar. """ - use Phoenix.WebComponent, :component + use Phoenix.WebComponent, :html @doc """ Generates a actionbar. diff --git a/apps/phoenix_webcomponent/lib/phoenix_webcomponent/appbar.ex b/apps/phoenix_webcomponent/lib/phoenix_webcomponent/appbar.ex index ca0e6c8b..10718e96 100644 --- a/apps/phoenix_webcomponent/lib/phoenix_webcomponent/appbar.ex +++ b/apps/phoenix_webcomponent/lib/phoenix_webcomponent/appbar.ex @@ -3,9 +3,7 @@ defmodule Phoenix.WebComponent.Appbar do render appbar """ - use Phoenix.WebComponent, :component - - import Phoenix.WebComponent.Helpers.Link + use Phoenix.WebComponent, :html @doc """ Generates a html customElement appbar. @@ -15,7 +13,7 @@ defmodule Phoenix.WebComponent.Appbar do - `title` binary example: "App Title" - `menus` List - example: [ %{ label: "Menu Name", to: Routes.index_path(@conn, :index) } ] + example: [ %{ label: "Menu Name", to: ~p"/menu-url" } ] ## Slots @@ -35,15 +33,20 @@ defmodule Phoenix.WebComponent.Appbar do ~H""" - + <%= for menu <- @menus do %> + <.link + navigate={menu.to} + slot="nav" + > + <%= menu.label %> + + <% end %> + <%= render_slot(@user_profile) %> - + """ end diff --git a/apps/phoenix_webcomponent/lib/phoenix_webcomponent/card.ex b/apps/phoenix_webcomponent/lib/phoenix_webcomponent/card.ex index 24dc944b..d8948a72 100644 --- a/apps/phoenix_webcomponent/lib/phoenix_webcomponent/card.ex +++ b/apps/phoenix_webcomponent/lib/phoenix_webcomponent/card.ex @@ -2,7 +2,7 @@ defmodule Phoenix.WebComponent.Card do @moduledoc """ Render card. """ - use Phoenix.WebComponent, :component + use Phoenix.WebComponent, :html # alias Phoenix.LiveView.JS diff --git a/apps/phoenix_webcomponent/lib/phoenix_webcomponent/helpers/link.ex b/apps/phoenix_webcomponent/lib/phoenix_webcomponent/helpers/link.ex deleted file mode 100644 index e491c145..00000000 --- a/apps/phoenix_webcomponent/lib/phoenix_webcomponent/helpers/link.ex +++ /dev/null @@ -1,390 +0,0 @@ -defmodule Phoenix.WebComponent.Helpers.Link do - @moduledoc """ - Conveniences for working with links and URLs in HTML. - """ - - import Phoenix.HTML.Tag - alias Phoenix.LiveView.Socket - - @doc """ - Returns a list of attributes that make an element behave like a link. - For example, to make a button work like a link: - - However, this function is more often used to create buttons that - must invoke an action on the server, such as deleting an entity, - using the relevant HTTP protocol: - - The `to` argument may be a string, a URI, or a tuple `{scheme, value}`. - See the examples below. - Note: using this function requires loading the JavaScript library - at `priv/static/phoenix_html.js`. See the `Phoenix.HTML` module - documentation for more information. - ## Options - * `:method` - the HTTP method for the link. Defaults to `:get`. - * `:csrf_token` - a custom token to use when method is not `:get`. - This is used to ensure the request was sent by the user who - rendered the page. By default, CSRF tokens are generated through - `Plug.CSRFProtection`. You can set this option to `false`, to - disable token generation, or set it to your own token. - When the `:method` is set to `:get` and the `:to` URL contains query - parameters the generated form element will strip the parameters in - accordance with the [W3C](https://www.w3.org/TR/html401/interact/forms.html#h-17.13.3.4) - form specification. - ## Data attributes - The following data attributes can also be manually set in the element: - * `data-confirm` - shows a confirmation prompt before generating and - submitting the form. - ## Examples - iex> link_attributes("/world") - [data: [method: :get, to: "/world"]] - iex> link_attributes(URI.parse("https://elixir-lang.org")) - [data: [method: :get, to: "https://elixir-lang.org"]] - iex> link_attributes("/product/1", method: :delete) - [data: [csrf: Plug.CSRFProtection.get_csrf_token(), method: :delete, to: "/product/1"]] - ## If the URL is absolute, only certain schemas are allowed to avoid JavaScript injection. - For example, the following will fail - iex> link_attributes("javascript:alert('hacked!')") - ** (ArgumentError) unsupported scheme given as link. In case you want to link to an - unknown or unsafe scheme, such as javascript, use a tuple: {:javascript, rest} - You can however explicitly render those unsafe schemes by using a tuple: - iex> link_attributes({:javascript, "alert('my alert!')"}) - [data: [method: :get, to: ["javascript", 58, "alert('my alert!')"]]] - """ - def link_attributes(to, opts \\ []) do - to = valid_destination!(to) - method = Keyword.get(opts, :method, :get) - data = [method: method, to: to] - - data = - if method == :get do - data - else - case Keyword.get(opts, :csrf_token, true) do - true -> [csrf: Phoenix.HTML.Tag.csrf_token_value(to)] ++ data - false -> data - csrf when is_binary(csrf) -> [csrf: csrf] ++ data - end - end - - [data: data] - end - - @doc """ - Generates a link to the given URL. - - ## Examples - - wc_link("hello", to: "/world") - #=> hello - - wc_link("hello", to: URI.parse("https://elixir-lang.org")) - #=> hello - - wc_link("", to: "/world") - #=> <hello> - - wc_link("", to: "/world", class: "btn") - #=> <hello> - - wc_link("delete", to: "/the_world", data: [confirm: "Really?"]) - #=> delete - - # If you supply a method other than `:get`: - wc_link("delete", to: "/everything", method: :delete) - #=> delete - - # You can use a `do ... end` block too: - link to: "/hello" do - "world" - end - #=> world - - ## Options - - * `:to` - the page to link to. This option is required - - * `:method` - the method to use with the link. In case the - method is not `:get`, the link is generated inside the form - which sets the proper information. In order to submit the - form, JavaScript must be enabled - - * `:csrf_token` - a custom token to use for links with a method - other than `:get`. - - All other options are forwarded to the underlying `` tag. - - ## Data attributes - - Data attributes are added as a keyword list passed to the `data` key. - The following data attributes are supported: - - * `data-confirm` - shows a confirmation prompt before - generating and submitting the form when `:method` - is not `:get`. - - ## CSRF Protection - - By default, CSRF tokens are generated through `Plug.CSRFProtection`. - """ - def wc_link(text, opts) - - def wc_link(opts, do: contents) when is_list(opts) do - wc_link(contents, opts) - end - - def wc_link(_text, opts) when not is_list(opts) do - raise ArgumentError, "wc_link/2 requires a keyword list as second argument" - end - - def wc_link(text, opts) do - {to, opts} = pop_required_option!(opts, :to, "expected non-nil value for :to in wc_link/2") - {method, opts} = Keyword.pop(opts, :method, :get) - - if method == :get do - # Call link attributes to validate `to` - [data: data] = link_attributes(to, []) - {linkOpts, opts} = pop_link_attr(Keyword.delete(opts, :csrf_token)) - - content_tag(:"wc-button", text, [href: data[:to]] ++ linkOpts ++ opts) - else - {csrf_token, opts} = Keyword.pop(opts, :csrf_token, true) - opts = Keyword.put_new(opts, :rel, "nofollow") - - [data: data] = link_attributes(to, method: method, csrf_token: csrf_token) - - {linkOpts, opts} = pop_link_attr(opts) - - content_tag(:"wc-button", text, [data: data, href: data[:to]] ++ linkOpts ++ opts) - end - end - - @doc """ - Generates a button tag that uses the Javascript function handleClick() - (see phoenix_html.js) to submit the form data. - - Useful to ensure that links that change data are not triggered by - search engines and other spidering software. - - ## Examples - - button("hello", to: "/world") - #=> - - button("hello", to: "/world", method: :get, class: "btn") - #=> - - ## Options - - * `:to` - the page to link to. This option is required - - * `:method` - the method to use with the button. Defaults to :post. - - All other options are forwarded to the underlying button input. - - When the `:method` is set to `:get` and the `:to` URL contains query - parameters the generated form element will strip the parameters in accordance - with the [W3C](https://www.w3.org/TR/html401/interact/forms.html#h-17.13.3.4) - form specification. - - ## Data attributes - - Data attributes are added as a keyword list passed to the - `data` key. The following data attributes are supported: - - * `data-confirm` - shows a confirmation prompt before generating and - submitting the form. - """ - def wc_button(opts, do: contents) do - wc_button(contents, opts) - end - - def wc_button(text, opts) do - {to, opts} = pop_required_option!(opts, :to, "option :to is required in wc_button/2") - - {link_opts, opts} = - opts - |> Keyword.put_new(:method, :post) - |> Keyword.split([:method, :csrf_token]) - - link_attributes = link_attributes(to, link_opts) - content_tag(:"wc-button", text, link_attributes ++ opts) - end - - defp pop_required_option!(opts, key, error_message) do - {value, opts} = Keyword.pop(opts, key) - - unless value do - raise ArgumentError, error_message - end - - {value, opts} - end - - defp pop_link_attr(opts) do - list = [ - :data, - :download, - :href, - :hreflang, - :media, - :ping, - :referrerpolicy, - :rel, - :target, - :type - ] - - Enum.reduce(list, {[], opts}, fn name, {pop, list} -> - case Keyword.pop(list, name) do - {val, list} when is_nil(val) -> - {pop, list} - - {val, list} -> - {Keyword.put(pop, name, val), list} - end - end) - end - - @doc false - def wc_live_patch(opts) when is_list(opts) do - wc_live_link("patch", Keyword.fetch!(opts, :do), Keyword.delete(opts, :do)) - end - - @doc """ - Generates a link that will patch the current LiveView. - When navigating to the current LiveView, - `c:Phoenix.LiveView.handle_params/3` is - immediately invoked to handle the change of params and URL state. - Then the new state is pushed to the client, without reloading the - whole page while also maintaining the current scroll position. - For live redirects to another LiveView, use `wc_live_redirect/2`. - ## Options - * `:to` - the required path to link to. - * `:replace` - the flag to replace the current history or push a new state. - Defaults `false`. - All other options are forwarded to the anchor tag. - ## Examples - <%= wc_live_patch "home", to: Routes.page_path(@socket, :index) %> - <%= wc_live_patch "next", to: Routes.live_path(@socket, MyLive, @page + 1) %> - <%= wc_live_patch to: Routes.live_path(@socket, MyLive, dir: :asc), replace: false do %> - Sort By Price - <% end %> - """ - def wc_live_patch(text, opts) - - def wc_live_patch(%Socket{}, _) do - raise """ - you are invoking wc_live_patch/2 with a socket but a socket is not expected. - If you want to wc_live_patch/2 inside a LiveView, use push_patch/2 instead. - If you are inside a template, make the sure the first argument is a string. - """ - end - - def wc_live_patch(opts, do: block) when is_list(opts) do - wc_live_link("patch", block, opts) - end - - def wc_live_patch(text, opts) when is_list(opts) do - wc_live_link("patch", text, opts) - end - - @doc false - def wc_live_redirect(opts) when is_list(opts) do - wc_live_link("redirect", Keyword.fetch!(opts, :do), Keyword.delete(opts, :do)) - end - - @doc """ - Generates a link that will redirect to a new LiveView of the same live session. - The current LiveView will be shut down and a new one will be mounted - in its place, without reloading the whole page. This can - also be used to remount the same LiveView, in case you want to start - fresh. If you want to navigate to the same LiveView without remounting - it, use `wc_live_patch/2` instead. - *Note*: The live redirects are only supported between two LiveViews defined - under the same live session. See `Phoenix.LiveView.Router.live_session/3` for - more details. - ## Options - * `:to` - the required path to link to. - * `:replace` - the flag to replace the current history or push a new state. - Defaults `false`. - All other options are forwarded to the anchor tag. - ## Examples - <%= wc_live_redirect "home", to: Routes.page_path(@socket, :index) %> - <%= wc_live_redirect "next", to: Routes.live_path(@socket, MyLive, @page + 1) %> - <%= wc_live_redirect to: Routes.live_path(@socket, MyLive, dir: :asc), replace: false do %> - Sort By Price - <% end %> - """ - def wc_live_redirect(text, opts) - - def wc_live_redirect(%Socket{}, _) do - raise """ - you are invoking wc_live_redirect/2 with a socket but a socket is not expected. - If you want to wc_live_redirect/2 inside a LiveView, use push_redirect/2 instead. - If you are inside a template, make the sure the first argument is a string. - """ - end - - def wc_live_redirect(opts, do: block) when is_list(opts) do - wc_live_link("redirect", block, opts) - end - - def wc_live_redirect(text, opts) when is_list(opts) do - wc_live_link("redirect", text, opts) - end - - defp wc_live_link(type, block_or_text, opts) do - {uri, opts} = pop_required_option!(opts, :to, "option :to is required in wc_live_link/2") - replace = Keyword.get(opts, :replace, false) - kind = if replace, do: "replace", else: "push" - - data = [phx_link: type, phx_link_state: kind] - - opts = - opts - |> Keyword.update(:data, data, &Keyword.merge(&1, data)) - |> Keyword.put(:href, uri) - - {linkOpts, opts} = pop_link_attr(opts) - - content_tag(:"wc-button", linkOpts ++ opts, do: block_or_text) - end - - defp valid_destination!(%URI{} = uri) do - valid_destination!(URI.to_string(uri)) - end - - defp valid_destination!({:safe, to}) do - {:safe, valid_string_destination!(IO.iodata_to_binary(to))} - end - - defp valid_destination!({other, to}) when is_atom(other) do - [Atom.to_string(other), ?:, to] - end - - defp valid_destination!(to) do - valid_string_destination!(IO.iodata_to_binary(to)) - end - - @valid_uri_schemes ~w(http: https: ftp: ftps: mailto: news: irc: gopher:) ++ - ~w(nntp: feed: telnet: mms: rtsp: svn: tel: fax: xmpp:) - - for scheme <- @valid_uri_schemes do - defp valid_string_destination!(unquote(scheme) <> _ = string), do: string - end - - defp valid_string_destination!(to) do - if not match?("/" <> _, to) and String.contains?(to, ":") do - raise ArgumentError, """ - unsupported scheme given as link. In case you want to link to an - unknown or unsafe scheme, such as javascript, use a tuple: {:javascript, rest}\ - """ - else - to - end - end -end diff --git a/apps/phoenix_webcomponent/lib/phoenix_webcomponent/left_menu.ex b/apps/phoenix_webcomponent/lib/phoenix_webcomponent/left_menu.ex index 7a2c6a8c..72dbd30b 100644 --- a/apps/phoenix_webcomponent/lib/phoenix_webcomponent/left_menu.ex +++ b/apps/phoenix_webcomponent/lib/phoenix_webcomponent/left_menu.ex @@ -2,7 +2,7 @@ defmodule Phoenix.WebComponent.LeftMenu do @moduledoc """ Render left menu. """ - use Phoenix.WebComponent, :component + use Phoenix.WebComponent, :html @doc """ Generates left menu @@ -28,9 +28,12 @@ defmodule Phoenix.WebComponent.LeftMenu do
<%= group %>
<%= for {id, menu, url} <- subMenu do %> - <%= live_redirect to: url, class: "px-6 py-4 rounded-lg w-full flex flex-row justify-start items-center hover:text-blue-600 cursor-pointer" <> if(@active == id, do: " bg-blue-600 text-white hover:text-slate-300", else: "") do %> + <.link + navigate={url} + class={"px-6 py-4 rounded-lg w-full flex flex-row justify-start items-center hover:text-blue-600 cursor-pointer" <> if(@active == id, do: " bg-blue-600 text-white hover:text-slate-300", else: "")} + > <%= menu %> - <% end %> + <% end %>
diff --git a/apps/phoenix_webcomponent/lib/phoenix_webcomponent/markdown.ex b/apps/phoenix_webcomponent/lib/phoenix_webcomponent/markdown.ex index b8466b4a..6912eb23 100644 --- a/apps/phoenix_webcomponent/lib/phoenix_webcomponent/markdown.ex +++ b/apps/phoenix_webcomponent/lib/phoenix_webcomponent/markdown.ex @@ -8,7 +8,7 @@ defmodule Phoenix.WebComponent.Markdown do * charts render by mermaid.js """ - use Phoenix.WebComponent, :component + use Phoenix.WebComponent, :html @doc """ Generates a html customElement remark-element to preview markdown. diff --git a/apps/phoenix_webcomponent/lib/phoenix_webcomponent/pagination.ex b/apps/phoenix_webcomponent/lib/phoenix_webcomponent/pagination.ex index bed800a9..574f5185 100644 --- a/apps/phoenix_webcomponent/lib/phoenix_webcomponent/pagination.ex +++ b/apps/phoenix_webcomponent/lib/phoenix_webcomponent/pagination.ex @@ -3,7 +3,7 @@ defmodule Phoenix.WebComponent.Pagination do Render pagination. """ - use Phoenix.WebComponent, :component + use Phoenix.WebComponent, :html @doc """ Generates a pagination. diff --git a/apps/phoenix_webcomponent/lib/phoenix_webcomponent/table.ex b/apps/phoenix_webcomponent/lib/phoenix_webcomponent/table.ex index e14da5dc..f6fab7fe 100644 --- a/apps/phoenix_webcomponent/lib/phoenix_webcomponent/table.ex +++ b/apps/phoenix_webcomponent/lib/phoenix_webcomponent/table.ex @@ -2,7 +2,7 @@ defmodule Phoenix.WebComponent.Table do @moduledoc """ Render table. """ - use Phoenix.WebComponent, :component + use Phoenix.WebComponent, :html @doc """ Generates a table. diff --git a/apps/phoenix_webcomponent/mix.exs b/apps/phoenix_webcomponent/mix.exs index ecfd006b..a30c1499 100644 --- a/apps/phoenix_webcomponent/mix.exs +++ b/apps/phoenix_webcomponent/mix.exs @@ -39,7 +39,7 @@ defmodule PhoenixWebComponent.Mixfile do defp deps do [ {:phoenix_html, "~> 3.0"}, - {:phoenix_live_view, ">= 0.17.0"}, + {:phoenix_live_view, "~> 0.18"}, {:plug, "~> 1.5", optional: true}, {:jason, "~> 1.0"}, {:esbuild, "~> 0.2", runtime: true}, diff --git a/apps/phoenix_webcomponent/package.json b/apps/phoenix_webcomponent/package.json index 99ec01f6..cd36f678 100644 --- a/apps/phoenix_webcomponent/package.json +++ b/apps/phoenix_webcomponent/package.json @@ -14,18 +14,19 @@ "priv/static/" ], "dependencies": { - "@gsmlg/lit": "^1.25.3", - "lit": "^2.3.1", + "@gsmlg/lit": "^1.28.0", + "lit": "^2.4.1", "lit-element": "^3.2.2", - "lit-html": "^2.3.1" + "lit-html": "^2.4.0" }, "devDependencies": { - "@babel/core": "^7.19.3", - "@babel/preset-env": "^7.19.3" + "@babel/core": "^7.20.2", + "@babel/preset-env": "^7.20.2" }, "peerDependencies": { - "lit": "^2.3.1", + "@gsmlg/lit": "^1.28.0", + "lit": "^2.4.1", "lit-element": "^3.2.2", - "lit-html": "^2.3.1" + "lit-html": "^2.4.0" } } diff --git a/apps/phx_wc_storybook_web/lib/phx_wc_storybook_web/router.ex b/apps/phx_wc_storybook_web/lib/phx_wc_storybook_web/router.ex index 4b8114b3..ad0ebaf1 100644 --- a/apps/phx_wc_storybook_web/lib/phx_wc_storybook_web/router.ex +++ b/apps/phx_wc_storybook_web/lib/phx_wc_storybook_web/router.ex @@ -15,14 +15,17 @@ defmodule PhxWCStorybookWeb.Router do plug :accepts, ["json"] end + scope "/" do + storybook_assets() + end + scope "/", PhxWCStorybookWeb do pipe_through :browser get "/", PageController, :index + + live_storybook "/storybook", backend_module: PhxWCStorybookWeb.Storybook end - live_storybook("/storybook", - otp_app: :phx_wc_storybook_web, - backend_module: PhxWCStorybookWeb.Storybook - ) + end diff --git a/apps/phx_wc_storybook_web/lib/phx_wc_storybook_web/storybook.ex b/apps/phx_wc_storybook_web/lib/phx_wc_storybook_web/storybook.ex index baae4fa5..9154743b 100644 --- a/apps/phx_wc_storybook_web/lib/phx_wc_storybook_web/storybook.ex +++ b/apps/phx_wc_storybook_web/lib/phx_wc_storybook_web/storybook.ex @@ -1,4 +1,20 @@ defmodule PhxWCStorybookWeb.Storybook do @moduledoc false - use PhxLiveStorybook, otp_app: :phx_wc_storybook_web + use PhxLiveStorybook, + # OTP name of your application. + otp_app: :phx_wc_storybook_web, + + # Path to your storybook stories (required). + content_path: Path.expand("storybook", __DIR__), + + # Custom storybook title. Default is "Live Storybook". + title: "Phoenix WebComponent Live Storybook", + + # Story compilation mode, can be either `:eager` or `:lazy`. + # It defaults to `:lazy` in dev environment, `:eager` in other environments. + # - When eager: all .story.exs & .index.exs files are compiled upfront. + # - When lazy: ony .index.exs files are compiled upfront and .story.exs are compile when the + # matching story is loaded in UI. + compilation_mode: :eager + end diff --git a/apps/phx_wc_storybook_web/lib/phx_wc_storybook_web/storybook/components/actionbar.exs b/apps/phx_wc_storybook_web/lib/phx_wc_storybook_web/storybook/components/actionbar.exs deleted file mode 100644 index 3db113e4..00000000 --- a/apps/phx_wc_storybook_web/lib/phx_wc_storybook_web/storybook/components/actionbar.exs +++ /dev/null @@ -1,28 +0,0 @@ -defmodule PhxWCStorybookWeb.Storybook.Components.Actionbar do - # :live_component or :page are also available - use PhxLiveStorybook.Entry, :component - - def function, do: &Phoenix.WebComponent.Actionbar.wc_actionbar/1 - def description, do: "A actionbar element." - - def stories do - [ - %Story{ - id: :default, - attributes: %{ - class: "shadow" - }, - slots: [ - """ - <:left> - Star Wars - - <:right> - - - """ - ] - } - ] - end -end diff --git a/apps/phx_wc_storybook_web/lib/phx_wc_storybook_web/storybook/components/actionbar.story.exs b/apps/phx_wc_storybook_web/lib/phx_wc_storybook_web/storybook/components/actionbar.story.exs new file mode 100644 index 00000000..45527e6c --- /dev/null +++ b/apps/phx_wc_storybook_web/lib/phx_wc_storybook_web/storybook/components/actionbar.story.exs @@ -0,0 +1,28 @@ +defmodule PhxWCStorybookWeb.Storybook.Components.Actionbar do + # :live_component or :page are also available + use PhxLiveStorybook.Story, :component + + def function, do: &Phoenix.WebComponent.Actionbar.wc_actionbar/1 + def description, do: "A actionbar element." + + def variations do [ + %Variation{ + id: :default, + attributes: %{ + class: "shadow" + }, + slots: [ + """ + <:left> + Star Wars + + <:right> + + + """ + ] + } + ] + end + +end diff --git a/apps/phx_wc_storybook_web/lib/phx_wc_storybook_web/storybook/components/card.exs b/apps/phx_wc_storybook_web/lib/phx_wc_storybook_web/storybook/components/card.story.exs similarity index 88% rename from apps/phx_wc_storybook_web/lib/phx_wc_storybook_web/storybook/components/card.exs rename to apps/phx_wc_storybook_web/lib/phx_wc_storybook_web/storybook/components/card.story.exs index 47422033..777fa1a2 100644 --- a/apps/phx_wc_storybook_web/lib/phx_wc_storybook_web/storybook/components/card.exs +++ b/apps/phx_wc_storybook_web/lib/phx_wc_storybook_web/storybook/components/card.story.exs @@ -1,13 +1,13 @@ defmodule PhxWCStorybookWeb.Storybook.Components.Card do # :live_component or :page are also available - use PhxLiveStorybook.Entry, :component + use PhxLiveStorybook.Story, :component def function, do: &Phoenix.WebComponent.Card.wc_card/1 def description, do: "A card element." - def stories do + def variations do [ - %Story{ + %Variation{ id: :default, slots: [ """ diff --git a/apps/phx_wc_storybook_web/lib/phx_wc_storybook_web/storybook/components/left_menu.exs b/apps/phx_wc_storybook_web/lib/phx_wc_storybook_web/storybook/components/left_menu.story.exs similarity index 92% rename from apps/phx_wc_storybook_web/lib/phx_wc_storybook_web/storybook/components/left_menu.exs rename to apps/phx_wc_storybook_web/lib/phx_wc_storybook_web/storybook/components/left_menu.story.exs index ecb652da..5f2d91e7 100644 --- a/apps/phx_wc_storybook_web/lib/phx_wc_storybook_web/storybook/components/left_menu.exs +++ b/apps/phx_wc_storybook_web/lib/phx_wc_storybook_web/storybook/components/left_menu.story.exs @@ -1,13 +1,13 @@ defmodule PhxWCStorybookWeb.Storybook.Components.LeftMenu do # :live_component or :page are also available - use PhxLiveStorybook.Entry, :component + use PhxLiveStorybook.Story, :component def function, do: &Phoenix.WebComponent.LeftMenu.wc_left_menu/1 def description, do: "A left menu element." - def stories do + def variations do [ - %Story{ + %Variation{ id: :default, attributes: %{ active: "left_menu", diff --git a/apps/phx_wc_storybook_web/lib/phx_wc_storybook_web/storybook/components/markdown.exs b/apps/phx_wc_storybook_web/lib/phx_wc_storybook_web/storybook/components/markdown.story.exs similarity index 89% rename from apps/phx_wc_storybook_web/lib/phx_wc_storybook_web/storybook/components/markdown.exs rename to apps/phx_wc_storybook_web/lib/phx_wc_storybook_web/storybook/components/markdown.story.exs index af746056..ba59c4ba 100644 --- a/apps/phx_wc_storybook_web/lib/phx_wc_storybook_web/storybook/components/markdown.exs +++ b/apps/phx_wc_storybook_web/lib/phx_wc_storybook_web/storybook/components/markdown.story.exs @@ -1,13 +1,13 @@ defmodule PhxWCStorybookWeb.Storybook.Components.Markdown do # :live_component or :page are also available - use PhxLiveStorybook.Entry, :component + use PhxLiveStorybook.Story, :component def function, do: &Phoenix.WebComponent.Markdown.wc_markdown/1 def description, do: "A markdown render element." - def stories do + def variations do [ - %Story{ + %Variation{ id: :default, attributes: %{ content: """ @@ -15,7 +15,7 @@ defmodule PhxWCStorybookWeb.Storybook.Components.Markdown do """ } }, - %Story{ + %Variation{ id: :with_code, attributes: %{ content: """ @@ -26,7 +26,7 @@ defmodule PhxWCStorybookWeb.Storybook.Components.Markdown do """ } }, - %Story{ + %Variation{ id: :with_mermaid, attributes: %{ content: """ diff --git a/apps/phx_wc_storybook_web/lib/phx_wc_storybook_web/storybook/components/pagination.exs b/apps/phx_wc_storybook_web/lib/phx_wc_storybook_web/storybook/components/pagination.story.exs similarity index 84% rename from apps/phx_wc_storybook_web/lib/phx_wc_storybook_web/storybook/components/pagination.exs rename to apps/phx_wc_storybook_web/lib/phx_wc_storybook_web/storybook/components/pagination.story.exs index c6a14bc8..a8c6c852 100644 --- a/apps/phx_wc_storybook_web/lib/phx_wc_storybook_web/storybook/components/pagination.exs +++ b/apps/phx_wc_storybook_web/lib/phx_wc_storybook_web/storybook/components/pagination.story.exs @@ -1,13 +1,13 @@ defmodule PhxWCStorybookWeb.Storybook.Components.Pagination do # :live_component or :page are also available - use PhxLiveStorybook.Entry, :component + use PhxLiveStorybook.Story, :component def function, do: &Phoenix.WebComponent.Pagination.wc_pagination/1 def description, do: "A pagination element." - def stories do + def variations do [ - %Story{ + %Variation{ id: :default, attributes: %{ total: 100, diff --git a/apps/phx_wc_storybook_web/lib/phx_wc_storybook_web/storybook/components/table.exs b/apps/phx_wc_storybook_web/lib/phx_wc_storybook_web/storybook/components/table.story.exs similarity index 97% rename from apps/phx_wc_storybook_web/lib/phx_wc_storybook_web/storybook/components/table.exs rename to apps/phx_wc_storybook_web/lib/phx_wc_storybook_web/storybook/components/table.story.exs index 7c24539b..2f09402e 100644 --- a/apps/phx_wc_storybook_web/lib/phx_wc_storybook_web/storybook/components/table.exs +++ b/apps/phx_wc_storybook_web/lib/phx_wc_storybook_web/storybook/components/table.story.exs @@ -1,13 +1,13 @@ defmodule PhxWCStorybookWeb.Storybook.Components.Table do # :live_component or :page are also available - use PhxLiveStorybook.Entry, :component + use PhxLiveStorybook.Story, :component def function, do: &Phoenix.WebComponent.Table.wc_table/1 def description, do: "A table element." - def stories do + def variations do [ - %Story{ + %Variation{ id: :default, attributes: %{ rows: [ diff --git a/apps/phx_wc_storybook_web/lib/phx_wc_storybook_web/templates/layout/live.html.heex b/apps/phx_wc_storybook_web/lib/phx_wc_storybook_web/templates/layout/live.html.heex index a29d6044..169aed95 100644 --- a/apps/phx_wc_storybook_web/lib/phx_wc_storybook_web/templates/layout/live.html.heex +++ b/apps/phx_wc_storybook_web/lib/phx_wc_storybook_web/templates/layout/live.html.heex @@ -1,11 +1,5 @@
- - - - + + <%= @inner_content %>
diff --git a/apps/phx_wc_storybook_web/mix.exs b/apps/phx_wc_storybook_web/mix.exs index 11a5ad90..7c791e32 100644 --- a/apps/phx_wc_storybook_web/mix.exs +++ b/apps/phx_wc_storybook_web/mix.exs @@ -40,10 +40,10 @@ defmodule PhxWCStorybookWeb.MixProject do {:phoenix, "~> 1.6.8"}, {:phoenix_html, "~> 3.0"}, {:phoenix_live_reload, "~> 1.2", only: :dev}, - {:phoenix_live_view, "~> 0.17.5"}, - {:phx_live_storybook, "~> 0.3.0"}, + {:phoenix_live_view, "~> 0.18"}, + {:phx_live_storybook, "~> 0.4.0"}, {:floki, ">= 0.30.0", only: :test}, - {:phoenix_live_dashboard, "~> 0.6"}, + {:phoenix_live_dashboard, "~> 0.7"}, {:tailwind, "~> 0.1.6", runtime: Mix.env() == :dev}, {:esbuild, "~> 0.4", runtime: Mix.env() == :dev}, {:telemetry_metrics, "~> 0.6"}, diff --git a/config/config.exs b/config/config.exs index e17eef9a..f123cea6 100644 --- a/config/config.exs +++ b/config/config.exs @@ -25,8 +25,6 @@ config :phx_wc_storybook_web, PhxWCStorybookWeb.Endpoint, live_view: [signing_salt: "HkF5qV0r"] config :phx_wc_storybook_web, PhxWCStorybookWeb.Storybook, - content_path: - Path.expand("../apps/phx_wc_storybook_web/lib/phx_wc_storybook_web/storybook", __DIR__), js_path: "/assets/app.js", css_path: "/assets/app.css" diff --git a/mix.lock b/mix.lock index 46549b53..65846fcf 100644 --- a/mix.lock +++ b/mix.lock @@ -1,8 +1,9 @@ %{ - "castore": {:hex, :castore, "0.1.18", "deb5b9ab02400561b6f5708f3e7660fc35ca2d51bfc6a940d2f513f89c2975fc", [:mix], [], "hexpm", "61bbaf6452b782ef80b33cdb45701afbcf0a918a45ebe7e73f1130d661e66a06"}, + "castore": {:hex, :castore, "0.1.19", "a2c3e46d62b7f3aa2e6f88541c21d7400381e53704394462b9fd4f06f6d42bb6", [:mix], [], "hexpm", "e96e0161a5dc82ef441da24d5fa74aefc40d920f3a6645d15e1f9f3e66bb2109"}, "cowboy": {:hex, :cowboy, "2.9.0", "865dd8b6607e14cf03282e10e934023a1bd8be6f6bacf921a7e2a96d800cd452", [:make, :rebar3], [{:cowlib, "2.11.0", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "1.8.0", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "2c729f934b4e1aa149aff882f57c6372c15399a20d54f65c8d67bef583021bde"}, "cowboy_telemetry": {:hex, :cowboy_telemetry, "0.4.0", "f239f68b588efa7707abce16a84d0d2acf3a0f50571f8bb7f56a15865aae820c", [:rebar3], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "7d98bac1ee4565d31b62d59f8823dfd8356a169e7fcbb83831b8a5397404c9de"}, "cowlib": {:hex, :cowlib, "2.11.0", "0b9ff9c346629256c42ebe1eeb769a83c6cb771a6ee5960bd110ab0b9b872063", [:make, :rebar3], [], "hexpm", "2b3e9da0b21c4565751a6d4901c20d1b4cc25cbb7fd50d91d2ab6dd287bc86a9"}, + "earmark": {:hex, :earmark, "1.4.27", "b413b0379043df51475a9b22ce344e8a58a117516c735b8871e6cdd5ed0f0153", [:mix], [{:earmark_parser, "~> 1.4.26", [hex: :earmark_parser, repo: "hexpm", optional: false]}], "hexpm", "579ebe2eaf4c7e040815a73a268036bcd96e6aab8ad2b1fcd979aaeb1ea47e15"}, "earmark_parser": {:hex, :earmark_parser, "1.4.26", "f4291134583f373c7d8755566122908eb9662df4c4b63caa66a0eabe06569b0a", [:mix], [], "hexpm", "48d460899f8a0c52c5470676611c01f64f3337bad0b26ddab43648428d94aabc"}, "esbuild": {:hex, :esbuild, "0.5.0", "d5bb08ff049d7880ee3609ed5c4b864bd2f46445ea40b16b4acead724fb4c4a3", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}], "hexpm", "f183a0b332d963c4cfaf585477695ea59eef9a6f2204fdd0efa00e099694ffe5"}, "ex_doc": {:hex, :ex_doc, "0.28.5", "3e52a6d2130ce74d096859e477b97080c156d0926701c13870a4e1f752363279", [:mix], [{:earmark_parser, "~> 1.4.19", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "d2c4b07133113e9aa3e9ba27efb9088ba900e9e51caa383919676afdf09ab181"}, @@ -10,7 +11,7 @@ "floki": {:hex, :floki, "0.33.1", "f20f1eb471e726342b45ccb68edb9486729e7df94da403936ea94a794f072781", [:mix], [{:html_entities, "~> 0.5.0", [hex: :html_entities, repo: "hexpm", optional: false]}], "hexpm", "461035fd125f13fdf30f243c85a0b1e50afbec876cbf1ceefe6fddd2e6d712c6"}, "gettext": {:hex, :gettext, "0.20.0", "75ad71de05f2ef56991dbae224d35c68b098dd0e26918def5bb45591d5c8d429", [:mix], [], "hexpm", "1c03b177435e93a47441d7f681a7040bd2a816ece9e2666d1c9001035121eb3d"}, "html_entities": {:hex, :html_entities, "0.5.2", "9e47e70598da7de2a9ff6af8758399251db6dbb7eebe2b013f2bbd2515895c3c", [:mix], [], "hexpm", "c53ba390403485615623b9531e97696f076ed415e8d8058b1dbaa28181f4fdcc"}, - "jason": {:hex, :jason, "1.3.0", "fa6b82a934feb176263ad2df0dbd91bf633d4a46ebfdffea0c8ae82953714946", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "53fc1f51255390e0ec7e50f9cb41e751c260d065dcba2bf0d08dc51a4002c2ac"}, + "jason": {:hex, :jason, "1.4.0", "e855647bc964a44e2f67df589ccf49105ae039d4179db7f6271dfd3843dc27e6", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "79a3791085b2a0f743ca04cec0f7be26443738779d09302e01318f97bdb82121"}, "makeup": {:hex, :makeup, "1.1.0", "6b67c8bc2882a6b6a445859952a602afc1a41c2e08379ca057c0f525366fc3ca", [:mix], [{:nimble_parsec, "~> 1.2.2 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "0a45ed501f4a8897f580eabf99a2e5234ea3e75a4373c8a52824f6e873be57a6"}, "makeup_eex": {:hex, :makeup_eex, "0.1.1", "89352d5da318d97ae27bbcc87201f274504d2b71ede58ca366af6a5fbed9508d", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.16", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_html, "~> 0.1.0", [hex: :makeup_html, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "d111a0994eaaab09ef1a4b3b313ef806513bb4652152c26c0d7ca2be8402a964"}, "makeup_elixir": {:hex, :makeup_elixir, "0.16.0", "f8c570a0d33f8039513fbccaf7108c5d750f47d8defd44088371191b76492b0b", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "28b2cbdc13960a46ae9a8858c4bebdec3c9a6d7b4b9e7f4ed1502f8159f338e7"}, @@ -18,16 +19,17 @@ "makeup_html": {:hex, :makeup_html, "0.1.0", "b0228fda985e311d8f0d25bed58f8280826633a38d7448cabdd723e116165bcf", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "0ca44e7dcb8d933e010740324470dd8ec947243b51304bd34b8165ef3281edc2"}, "mime": {:hex, :mime, "2.0.3", "3676436d3d1f7b81b5a2d2bd8405f412c677558c81b1c92be58c00562bb59095", [:mix], [], "hexpm", "27a30bf0db44d25eecba73755acf4068cbfe26a4372f9eb3e4ea3a45956bff6b"}, "nimble_parsec": {:hex, :nimble_parsec, "1.2.3", "244836e6e3f1200c7f30cb56733fd808744eca61fd182f731eac4af635cc6d0b", [:mix], [], "hexpm", "c8d789e39b9131acf7b99291e93dae60ab48ef14a7ee9d58c6964f59efb570b0"}, - "phoenix": {:hex, :phoenix, "1.6.12", "f8f8ac077600f84419806dd53114b2e77aedde7a502e74181a7d886355aa0643", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 2.0", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 1.0", [hex: :phoenix_view, repo: "hexpm", optional: false]}, {:plug, "~> 1.10", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.2", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:plug_crypto, "~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "2d6cf5583c9c20f7103c40e6014ef802d96553b8e5d6585ad6e627bd5ddb0d12"}, + "phoenix": {:hex, :phoenix, "1.6.15", "0a1d96bbc10747fd83525370d691953cdb6f3ccbac61aa01b4acb012474b047d", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 2.0", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 1.0 or ~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: false]}, {:plug, "~> 1.10", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.2", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:plug_crypto, "~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "d70ab9fbf6b394755ea88b644d34d79d8b146e490973151f248cacd122d20672"}, "phoenix_html": {:hex, :phoenix_html, "3.2.0", "1c1219d4b6cb22ac72f12f73dc5fad6c7563104d083f711c3fcd8551a1f4ae11", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "36ec97ba56d25c0136ef1992c37957e4246b649d620958a1f9fa86165f8bc54f"}, - "phoenix_live_dashboard": {:hex, :phoenix_live_dashboard, "0.6.5", "1495bb014be12c9a9252eca04b9af54246f6b5c1e4cd1f30210cd00ec540cf8e", [:mix], [{:ecto, "~> 3.6.2 or ~> 3.7", [hex: :ecto, repo: "hexpm", optional: true]}, {:ecto_mysql_extras, "~> 0.3", [hex: :ecto_mysql_extras, repo: "hexpm", optional: true]}, {:ecto_psql_extras, "~> 0.7", [hex: :ecto_psql_extras, repo: "hexpm", optional: true]}, {:mime, "~> 1.6 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:phoenix_live_view, "~> 0.17.7", [hex: :phoenix_live_view, repo: "hexpm", optional: false]}, {:telemetry_metrics, "~> 0.6.0", [hex: :telemetry_metrics, repo: "hexpm", optional: false]}], "hexpm", "ef4fa50dd78364409039c99cf6f98ab5209b4c5f8796c17f4db118324f0db852"}, + "phoenix_live_dashboard": {:hex, :phoenix_live_dashboard, "0.7.2", "97cc4ff2dba1ebe504db72cb45098cb8e91f11160528b980bd282cc45c73b29c", [:mix], [{:ecto, "~> 3.6.2 or ~> 3.7", [hex: :ecto, repo: "hexpm", optional: true]}, {:ecto_mysql_extras, "~> 0.5", [hex: :ecto_mysql_extras, repo: "hexpm", optional: true]}, {:ecto_psql_extras, "~> 0.7", [hex: :ecto_psql_extras, repo: "hexpm", optional: true]}, {:mime, "~> 1.6 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:phoenix_live_view, "~> 0.18.3", [hex: :phoenix_live_view, repo: "hexpm", optional: false]}, {:telemetry_metrics, "~> 0.6 or ~> 1.0", [hex: :telemetry_metrics, repo: "hexpm", optional: false]}], "hexpm", "0e5fdf063c7a3b620c566a30fcf68b7ee02e5e46fe48ee46a6ec3ba382dc05b7"}, "phoenix_live_reload": {:hex, :phoenix_live_reload, "1.3.3", "3a53772a6118d5679bf50fc1670505a290e32a1d195df9e069d8c53ab040c054", [:mix], [{:file_system, "~> 0.2.1 or ~> 0.3", [hex: :file_system, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.4", [hex: :phoenix, repo: "hexpm", optional: false]}], "hexpm", "766796676e5f558dbae5d1bdb066849673e956005e3730dfd5affd7a6da4abac"}, - "phoenix_live_view": {:hex, :phoenix_live_view, "0.17.11", "205f6aa5405648c76f2abcd57716f42fc07d8f21dd8ea7b262dd12b324b50c95", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix, "~> 1.6.0", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 3.1", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "7177791944b7f90ed18f5935a6a5f07f760b36f7b3bdfb9d28c57440a3c43f99"}, + "phoenix_live_view": {:hex, :phoenix_live_view, "0.18.3", "2e3d009422addf8b15c3dccc65ce53baccbe26f7cfd21d264680b5867789a9c1", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix, "~> 1.6.15 or ~> 1.7.0", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 3.1", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "c8845177a866e017dcb7083365393c8f00ab061b8b6b2bda575891079dce81b2"}, "phoenix_pubsub": {:hex, :phoenix_pubsub, "2.1.1", "ba04e489ef03763bf28a17eb2eaddc2c20c6d217e2150a61e3298b0f4c2012b5", [:mix], [], "hexpm", "81367c6d1eea5878ad726be80808eb5a787a23dee699f96e72b1109c57cdd8d9"}, - "phoenix_view": {:hex, :phoenix_view, "1.1.2", "1b82764a065fb41051637872c7bd07ed2fdb6f5c3bd89684d4dca6e10115c95a", [:mix], [{:phoenix_html, "~> 2.14.2 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}], "hexpm", "7ae90ad27b09091266f6adbb61e1d2516a7c3d7062c6789d46a7554ec40f3a56"}, - "phx_live_storybook": {:hex, :phx_live_storybook, "0.3.0", "0f4fd16942cb0044444381e1fdfb239b1a6fe3837f871e7c06caf38c0251730c", [:mix], [{:jason, "~> 1.3", [hex: :jason, repo: "hexpm", optional: true]}, {:makeup_eex, "~> 0.1.0", [hex: :makeup_eex, repo: "hexpm", optional: false]}, {:phoenix_live_view, "~> 0.17.11", [hex: :phoenix_live_view, repo: "hexpm", optional: false]}], "hexpm", "00f57de08c0ea3c3c7ddb468ad7e65187af51c3c64bf801eb44f2dc47ce004cf"}, - "plug": {:hex, :plug, "1.13.6", "187beb6b67c6cec50503e940f0434ea4692b19384d47e5fdfd701e93cadb4cc2", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "02b9c6b9955bce92c829f31d6284bf53c591ca63c4fb9ff81dfd0418667a34ff"}, - "plug_cowboy": {:hex, :plug_cowboy, "2.5.2", "62894ccd601cf9597e2c23911ff12798a8a18d237e9739f58a6b04e4988899fe", [:mix], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:cowboy_telemetry, "~> 0.3", [hex: :cowboy_telemetry, repo: "hexpm", optional: false]}, {:plug, "~> 1.7", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "ea6e87f774c8608d60c8d34022a7d073bd7680a0a013f049fc62bf35efea1044"}, + "phoenix_template": {:hex, :phoenix_template, "1.0.0", "c57bc5044f25f007dc86ab21895688c098a9f846a8dda6bc40e2d0ddc146e38f", [:mix], [{:phoenix_html, "~> 2.14.2 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}], "hexpm", "1b066f99a26fd22064c12b2600a9a6e56700f591bf7b20b418054ea38b4d4357"}, + "phoenix_view": {:hex, :phoenix_view, "2.0.2", "6bd4d2fd595ef80d33b439ede6a19326b78f0f1d8d62b9a318e3d9c1af351098", [:mix], [{:phoenix_html, "~> 2.14.2 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}], "hexpm", "a929e7230ea5c7ee0e149ffcf44ce7cf7f4b6d2bfe1752dd7c084cdff152d36f"}, + "phx_live_storybook": {:hex, :phx_live_storybook, "0.4.5", "a14d33a81caa751e1af8e3e72c638595cf6cccbcabba20cc6821f3c028f1d5d1", [:mix], [{:earmark, "~> 1.4", [hex: :earmark, repo: "hexpm", optional: false]}, {:heroicons, "~> 0.5", [hex: :heroicons, repo: "hexpm", optional: true]}, {:jason, "~> 1.3", [hex: :jason, repo: "hexpm", optional: true]}, {:makeup_eex, "~> 0.1.0", [hex: :makeup_eex, repo: "hexpm", optional: false]}, {:phoenix_live_view, "~> 0.18", [hex: :phoenix_live_view, repo: "hexpm", optional: false]}], "hexpm", "84faeb19a516e474b5732ea3c905f7a920ec3371fd064da306abd62778f5db12"}, + "plug": {:hex, :plug, "1.14.0", "ba4f558468f69cbd9f6b356d25443d0b796fbdc887e03fa89001384a9cac638f", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "bf020432c7d4feb7b3af16a0c2701455cbbbb95e5b6866132cb09eb0c29adc14"}, + "plug_cowboy": {:hex, :plug_cowboy, "2.6.0", "d1cf12ff96a1ca4f52207c5271a6c351a4733f413803488d75b70ccf44aebec2", [:mix], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:cowboy_telemetry, "~> 0.3", [hex: :cowboy_telemetry, repo: "hexpm", optional: false]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "073cf20b753ce6682ed72905cd62a2d4bd9bad1bf9f7feb02a1b8e525bd94fa6"}, "plug_crypto": {:hex, :plug_crypto, "1.2.3", "8f77d13aeb32bfd9e654cb68f0af517b371fb34c56c9f2b58fe3df1235c1251a", [:mix], [], "hexpm", "b5672099c6ad5c202c45f5a403f21a3411247f164e4a8fab056e5cd8a290f4a2"}, "ranch": {:hex, :ranch, "1.8.0", "8c7a100a139fd57f17327b6413e4167ac559fbc04ca7448e9be9057311597a1d", [:make, :rebar3], [], "hexpm", "49fbcfd3682fab1f5d109351b61257676da1a2fdbe295904176d5e521a2ddfe5"}, "tailwind": {:hex, :tailwind, "0.1.9", "25ba09d42f7bfabe170eb67683a76d6ec2061952dc9bd263a52a99ba3d24bd4d", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}], "hexpm", "9213f87709c458aaec313bb5f2df2b4d2cedc2b630e4ae821bf3c54c47a56d0b"},