From 8af34c0be592b98800453fdea1e66bd26dbfacc3 Mon Sep 17 00:00:00 2001 From: Cristen Jones Date: Mon, 9 Sep 2024 15:31:45 -0400 Subject: [PATCH] remove CoreComponents since they're in mbta_metro --- lib/dotcom_web.ex | 2 + lib/dotcom_web/components/core_components.ex | 697 ------------------- 2 files changed, 2 insertions(+), 697 deletions(-) delete mode 100644 lib/dotcom_web/components/core_components.ex diff --git a/lib/dotcom_web.ex b/lib/dotcom_web.ex index a8820fec32..1799ff0691 100644 --- a/lib/dotcom_web.ex +++ b/lib/dotcom_web.ex @@ -139,6 +139,8 @@ defmodule DotcomWeb do import Phoenix.HTML import PhoenixHTMLHelpers.Form use PhoenixHTMLHelpers + # Use all MBTA Metro components + use MbtaMetro # Import LiveView and .heex helpers (live_render, live_patch, <.form>, etc) import Phoenix.LiveView.Helpers diff --git a/lib/dotcom_web/components/core_components.ex b/lib/dotcom_web/components/core_components.ex deleted file mode 100644 index a29865121f..0000000000 --- a/lib/dotcom_web/components/core_components.ex +++ /dev/null @@ -1,697 +0,0 @@ -defmodule DotcomWeb.CoreComponents do - @moduledoc """ - Provides core UI components. - - At first glance, this module may seem daunting, but its goal is to provide - core building blocks for your application, such as modals, tables, and - forms. The components consist mostly of markup and are well-documented - with doc strings and declarative assigns. You may customize and style - them in any way you want, based on your application growth and needs. - - The default components use Tailwind CSS, a utility-first CSS framework. - See the [Tailwind CSS documentation](https://tailwindcss.com) to learn - how to customize them or feel free to swap in another framework altogether. - - Icons are provided by [heroicons](https://heroicons.com). See `icon/1` for usage. - """ - use Phoenix.Component - - alias Phoenix.LiveView.JS - import DotcomWeb.Gettext - - @doc """ - Renders a modal. - - ## Examples - - <.modal id="confirm-modal"> - This is a modal. - - - JS commands may be passed to the `:on_cancel` to configure - the closing/cancel event, for example: - - <.modal id="confirm" on_cancel={JS.navigate(~p"/posts")}> - This is another modal. - - - """ - attr :id, :string, required: true - attr :show, :boolean, default: false - attr :on_cancel, JS, default: %JS{} - slot :inner_block, required: true - - def modal(assigns) do - ~H""" -
- - """ - end - - @doc """ - Renders flash notices. - - ## Examples - - <.flash kind={:info} flash={@flash} /> - <.flash kind={:info} phx-mounted={show("#flash")}>Welcome Back! - """ - attr :id, :string, doc: "the optional id of flash container" - attr :flash, :map, default: %{}, doc: "the map of flash messages to display" - attr :title, :string, default: nil - attr :kind, :atom, values: [:info, :error], doc: "used for styling and flash lookup" - attr :rest, :global, doc: "the arbitrary HTML attributes to add to the flash container" - - slot :inner_block, doc: "the optional inner block that renders the flash message" - - def flash(assigns) do - assigns = assign_new(assigns, :id, fn -> "flash-#{assigns.kind}" end) - - ~H""" -
hide("##{@id}")} - role="alert" - class={[ - "tw-fixed tw-top-2 tw-right-2 tw-mr-2 tw-w-80 tw-sm:w-96 tw-z-50 tw-rounded-lg tw-p-3 tw-ring-1", - @kind == :info && "tw-bg-emerald-50 tw-text-emerald-800 tw-ring-emerald-500 tw-fill-cyan-900", - @kind == :error && - "tw-bg-rose-50 tw-text-rose-900 tw-shadow-md tw-ring-rose-500 tw-fill-rose-900" - ]} - {@rest} - > -

- <.icon :if={@kind == :info} name="hero-information-circle-mini" class="tw-h-4 tw-w-4" /> - <.icon :if={@kind == :error} name="hero-exclamation-circle-mini" class="tw-h-4 tw-w-4" /> - <%= @title %> -

-

<%= msg %>

- -
- """ - end - - @doc """ - Shows the flash group with standard titles and content. - - ## Examples - - <.flash_group flash={@flash} /> - """ - attr :flash, :map, required: true, doc: "the map of flash messages" - attr :id, :string, default: "flash-group", doc: "the optional id of flash container" - - def flash_group(assigns) do - ~H""" -
- <.flash kind={:info} title={gettext("Success!")} flash={@flash} /> - <.flash kind={:error} title={gettext("Error!")} flash={@flash} /> - <.flash - id="client-error" - kind={:error} - title={gettext("We can't find the internet")} - phx-disconnected={show(".phx-client-error #client-error")} - phx-connected={hide("#client-error")} - hidden - > - <%= gettext("Attempting to reconnect") %> - <.icon name="hero-arrow-path" class="tw-ml-1 tw-h-3 tw-w-3 tw-animate-spin" /> - - - <.flash - id="server-error" - kind={:error} - title={gettext("Something went wrong!")} - phx-disconnected={show(".phx-server-error #server-error")} - phx-connected={hide("#server-error")} - hidden - > - <%= gettext("Hang in there while we get back on track") %> - <.icon name="hero-arrow-path" class="tw-ml-1 tw-h-3 tw-w-3 tw-animate-spin" /> - -
- """ - end - - @doc """ - Renders a simple form. - - ## Examples - - <.simple_form for={@form} phx-change="validate" phx-submit="save"> - <.input field={@form[:email]} label="Email"/> - <.input field={@form[:username]} label="Username" /> - <:actions> - <.button>Save - - - """ - attr :for, :any, required: true, doc: "the data structure for the form" - attr :as, :any, default: nil, doc: "the server side parameter to collect all input under" - - attr :rest, :global, - include: ~w(autocomplete name rel action enctype method novalidate target multipart), - doc: "the arbitrary HTML attributes to apply to the form tag" - - slot :inner_block, required: true - slot :actions, doc: "the slot for form actions, such as a submit button" - - def simple_form(assigns) do - ~H""" - <.form :let={f} for={@for} as={@as} {@rest}> -
- <%= render_slot(@inner_block, f) %> -
- <%= render_slot(action, f) %> -
-
- - """ - end - - @doc """ - Renders a button. - - ## Examples - - <.button>Send! - <.button phx-click="go" class="tw-ml-2">Send! - """ - attr :type, :string, default: nil - attr :class, :string, default: nil - attr :rest, :global, include: ~w(disabled form name value) - - slot :inner_block, required: true - - def button(assigns) do - ~H""" - - """ - end - - @doc """ - Renders an input with label and error messages. - - A `Phoenix.HTML.FormField` may be passed as argument, - which is used to retrieve the input name, id, and values. - Otherwise all attributes may be passed explicitly. - - ## Types - - This function accepts all HTML input types, considering that: - - * You may also set `type="select"` to render a ` - - <%= @label %> - - <.error :for={msg <- @errors}><%= msg %> -
- """ - end - - def input(%{type: "select"} = assigns) do - ~H""" -
- <.label for={@id}><%= @label %> - - <.error :for={msg <- @errors}><%= msg %> -
- """ - end - - def input(%{type: "textarea"} = assigns) do - ~H""" -
- <.label for={@id}><%= @label %> - - <.error :for={msg <- @errors}><%= msg %> -
- """ - end - - # All other inputs text, datetime-local, url, password, etc. are handled here... - def input(assigns) do - ~H""" -
- <.label for={@id}><%= @label %> - - <.error :for={msg <- @errors}><%= msg %> -
- """ - end - - @doc """ - Renders a label. - """ - attr :for, :string, default: nil - slot :inner_block, required: true - - def label(assigns) do - ~H""" - - """ - end - - @doc """ - Generates a generic error message. - """ - slot :inner_block, required: true - - def error(assigns) do - ~H""" -

- <.icon name="hero-exclamation-circle-mini" class="tw-mt-0.5 tw-h-5 tw-w-5 tw-flex-none" /> - <%= render_slot(@inner_block) %> -

- """ - end - - @doc """ - Renders a header with title. - """ - attr :class, :string, default: nil - - slot :inner_block, required: true - slot :subtitle - slot :actions - - def header(assigns) do - ~H""" -
-
-

- <%= render_slot(@inner_block) %> -

-

- <%= render_slot(@subtitle) %> -

-
-
<%= render_slot(@actions) %>
-
- """ - end - - @doc ~S""" - Renders a table with generic styling. - - ## Examples - - <.table id="users" rows={@users}> - <:col :let={user} label="id"><%= user.id %> - <:col :let={user} label="username"><%= user.username %> - - """ - attr :id, :string, required: true - attr :rows, :list, required: true - attr :row_id, :any, default: nil, doc: "the function for generating the row id" - attr :row_click, :any, default: nil, doc: "the function for handling phx-click on each row" - - attr :row_item, :any, - default: &Function.identity/1, - doc: "the function for mapping each row before calling the :col and :action slots" - - slot :col, required: true do - attr :label, :string - end - - slot :action, doc: "the slot for showing user actions in the last table column" - - def table(assigns) do - assigns = - with %{rows: %Phoenix.LiveView.LiveStream{}} <- assigns do - assign(assigns, row_id: assigns.row_id || fn {id, _item} -> id end) - end - - ~H""" -
- - - - - - - - - - - - - -
- <%= col[:label] %> - - <%= gettext("Actions") %> -
-
- - - <%= render_slot(col, @row_item.(row)) %> - -
-
-
- - - <%= render_slot(action, @row_item.(row)) %> - -
-
-
- """ - end - - @doc """ - Renders a data list. - - ## Examples - - <.list> - <:item title="Title"><%= @post.title %> - <:item title="Views"><%= @post.views %> - - """ - slot :item, required: true do - attr :title, :string, required: true - end - - def list(assigns) do - ~H""" -
-
-
-
<%= item.title %>
-
<%= render_slot(item) %>
-
-
-
- """ - end - - @doc """ - Renders a back navigation link. - - ## Examples - - <.back navigate={~p"/posts"}>Back to posts - """ - attr :navigate, :any, required: true - slot :inner_block, required: true - - def back(assigns) do - ~H""" -
- <.link - navigate={@navigate} - class="tw-text-sm tw-font-semibold tw-leading-6 tw-text-zinc-900 tw-hover:text-zinc-700" - > - <.icon name="hero-arrow-left-solid" class="tw-h-3 tw-w-3" /> - <%= render_slot(@inner_block) %> - -
- """ - end - - @doc """ - Renders a [Heroicon](https://heroicons.com). - - Heroicons come in three styles – outline, solid, and mini. - By default, the outline style is used, but solid and mini may - be applied by using the `-solid` and `-mini` suffix. - - You can customize the size and colors of the icons by setting - width, height, and background color classes. - - Icons are extracted from the `deps/heroicons` directory and bundled within - your compiled app.css by the plugin in your `assets/tailwind.config.js`. - - ## Examples - - <.icon name="hero-x-mark-solid" /> - <.icon name="hero-arrow-path" class="tw-ml-1 tw-w-3 tw-h-3 tw-animate-spin" /> - """ - attr :name, :string, required: true - attr :class, :string, default: nil - - def icon(%{name: "hero-" <> _} = assigns) do - ~H""" - - """ - end - - ## JS Commands - - def show(js \\ %JS{}, selector) do - JS.show(js, - to: selector, - time: 300, - transition: - {"tw-transition-all tw-transform tw-ease-out tw-duration-300", - "tw-opacity-0 tw-translate-y-4 tw-sm:translate-y-0 tw-sm:scale-95", - "tw-opacity-100 tw-translate-y-0 tw-sm:scale-100"} - ) - end - - def hide(js \\ %JS{}, selector) do - JS.hide(js, - to: selector, - time: 200, - transition: - {"tw-transition-all tw-transform tw-ease-in tw-duration-200", - "tw-opacity-100 tw-translate-y-0 tw-sm:scale-100", - "tw-opacity-0 tw-translate-y-4 tw-sm:translate-y-0 tw-sm:scale-95"} - ) - end - - def show_modal(js \\ %JS{}, id) when is_binary(id) do - js - |> JS.show(to: "##{id}") - |> JS.show( - to: "##{id}-bg", - time: 300, - transition: - {"tw-transition-all tw-transform tw-ease-out tw-duration-300", "tw-opacity-0", - "tw-opacity-100"} - ) - |> show("##{id}-container") - |> JS.add_class("tw-overflow-hidden", to: "body") - |> JS.focus_first(to: "##{id}-content") - end - - def hide_modal(js \\ %JS{}, id) do - js - |> JS.hide( - to: "##{id}-bg", - transition: - {"tw-transition-all tw-transform tw-ease-in tw-duration-200", "tw-opacity-100", - "tw-opacity-0"} - ) - |> hide("##{id}-container") - |> JS.hide(to: "##{id}", transition: {"tw-block", "tw-block", "tw-hidden"}) - |> JS.remove_class("tw-overflow-hidden", to: "body") - |> JS.pop_focus() - end - - @doc """ - Translates an error message using gettext. - """ - def translate_error({msg, opts}) do - # When using gettext, we typically pass the strings we want - # to translate as a static argument: - # - # # Translate the number of files with plural rules - # dngettext("errors", "1 file", "%{count} files", count) - # - # However the error messages in our forms and APIs are generated - # dynamically, so we need to translate them by calling Gettext - # with our gettext backend as first argument. Translations are - # available in the errors.po file (as we use the "errors" domain). - if count = opts[:count] do - Gettext.dngettext(HelloWeb.Gettext, "errors", msg, msg, count, opts) - else - Gettext.dgettext(HelloWeb.Gettext, "errors", msg, opts) - end - end - - @doc """ - Translates the errors for a field from a keyword list of errors. - """ - def translate_errors(errors, field) when is_list(errors) do - for {^field, {msg, opts}} <- errors, do: translate_error({msg, opts}) - end -end