Extract button component (#3474)

* Add button component

* Use new button in settings screen

* Use button component in registration screens

* Use new button component for Billing.upgrade_link

* Separate .button and .button_link

* Add attr definiton for disabled

* Fix funnels test
This commit is contained in:
Uku Taht 2023-11-08 11:40:07 +02:00 committed by GitHub
parent 2917cfaf65
commit 058d8cc6c9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 121 additions and 100 deletions

View File

@ -322,24 +322,19 @@ defmodule PlausibleWeb.Components.Billing do
def upgrade_link(%{business_tier: true} = assigns) do
~H"""
<.link
id="upgrade-link-2"
href={upgrade_link_href(@user)}
class="inline-block px-3 py-2 border border-transparent text-sm leading-4 font-medium rounded-md text-white bg-indigo-600 hover:bg-indigo-500 focus:outline-none focus:border-indigo-700 focus:ring active:bg-indigo-700 transition ease-in-out duration-150"
>
<PlausibleWeb.Components.Generic.button_link id="upgrade-link-2" href={upgrade_link_href(@user)}>
Upgrade
</.link>
</PlausibleWeb.Components.Generic.button_link>
"""
end
def upgrade_link(assigns) do
~H"""
<.link
href={Routes.billing_path(PlausibleWeb.Endpoint, :upgrade)}
class="inline-block px-3 py-2 border border-transparent text-sm leading-4 font-medium rounded-md text-white bg-indigo-600 hover:bg-indigo-500 focus:outline-none focus:border-indigo-700 focus:ring active:bg-indigo-700 transition ease-in-out duration-150"
>
<PlausibleWeb.Components.Generic.button_link href={
Routes.billing_path(PlausibleWeb.Endpoint, :upgrade)
}>
Upgrade
</.link>
</PlausibleWeb.Components.Generic.button_link>
"""
end

View File

@ -4,6 +4,50 @@ defmodule PlausibleWeb.Components.Generic do
"""
use Phoenix.Component
attr(:type, :string, default: "button")
attr(:class, :string, default: "")
attr(:disabled, :boolean, default: false)
attr(:rest, :global)
slot(:inner_block)
def button(assigns) do
~H"""
<button
type={@type}
disabled={@disabled}
class={[
"inline-flex items-center justify-center gap-x-2 rounded-md bg-indigo-600 px-3.5 py-2.5 text-sm font-semibold text-white shadow-sm hover:bg-indigo-700 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600 disabled:bg-gray-400",
@class
]}
{@rest}
>
<%= render_slot(@inner_block) %>
</button>
"""
end
attr(:href, :string, required: true)
attr(:class, :string, default: "")
attr(:rest, :global)
slot(:inner_block)
def button_link(assigns) do
~H"""
<.link
href={@href}
class={[
"inline-flex items-center justify-center gap-x-2 rounded-md bg-indigo-600 px-3.5 py-2.5 text-sm font-semibold text-white shadow-sm hover:bg-indigo-700 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600 disabled:bg-gray-400",
@class
]}
{@rest}
>
<%= render_slot(@inner_block) %>
</.link>
"""
end
attr(:slug, :string, required: true)
def docs_info(assigns) do

View File

@ -19,7 +19,7 @@ defmodule PlausibleWeb.Components.Site.Feature do
~H"""
<div>
<div class="mt-4 mb-8 flex items-center">
<.button
<.feature_button
set_to={!@current_setting}
disabled?={@disabled?}
conn={@conn}
@ -49,7 +49,7 @@ defmodule PlausibleWeb.Components.Site.Feature do
Routes.site_path(conn, :update_feature_visibility, site.domain, setting, r: r, set: set_to)
end
defp button(assigns) do
defp feature_button(assigns) do
~H"""
<.form action={target(@site, @feature_mod.toggle_field(), @conn, @set_to)} method="put" for={nil}>
<button

View File

@ -123,11 +123,17 @@ defmodule PlausibleWeb.Live.FunnelSettings.Form do
</div>
<div class="mt-6">
<%= if has_steps_errors?(f) or map_size(@selections_made) < Funnel.min_steps() or length(@step_ids) > map_size(@selections_made) do %>
<.submit_button_inactive />
<% else %>
<.submit_button />
<% end %>
<PlausibleWeb.Components.Generic.button
id="save"
type="submit"
class="w-full"
disabled={
has_steps_errors?(f) or map_size(@selections_made) < Funnel.min_steps() or
length(@step_ids) > map_size(@selections_made)
}
>
Add Funnel
</PlausibleWeb.Components.Generic.button>
</div>
</div>
</.form>
@ -173,26 +179,6 @@ defmodule PlausibleWeb.Live.FunnelSettings.Form do
"""
end
def submit_button(assigns) do
~H"""
<button id="save" type="submit" class="button text-base font-bold w-full">
Add Funnel
</button>
"""
end
def submit_button_inactive(assigns) do
~H"""
<button
type="none"
id="save"
class="w-full text-base font-bold py-2 border border-gray-300 dark:border-gray-500 rounded-md text-gray-300 bg-white dark:bg-gray-800 hover:text-gray-500 dark:hover:text-gray-400 focus:outline-none focus:border-blue-300 focus:ring active:text-gray-800 active:bg-gray-50 transition ease-in-out duration-150 cursor-not-allowed"
>
Add Funnel
</button>
"""
end
attr(:at, :integer, required: true)
attr(:result, :map, required: true)

View File

@ -39,9 +39,9 @@ defmodule PlausibleWeb.Live.FunnelSettings.List do
</div>
</form>
<div class="mt-4 flex sm:ml-4 sm:mt-0">
<button type="button" phx-click="add-funnel" class="button">
<PlausibleWeb.Components.Generic.button phx-click="add-funnel">
+ Add Funnel
</button>
</PlausibleWeb.Components.Generic.button>
</div>
</div>
<%= if Enum.count(@funnels) > 0 do %>

View File

@ -74,9 +74,9 @@ defmodule PlausibleWeb.Live.GoalSettings.Form do
<.pageview_fields :if={@tabs.pageviews} f={f} site={@site} />
<div class="py-4">
<button type="submit" class="button text-base font-bold w-full">
<PlausibleWeb.Components.Generic.button type="submit" class="w-full">
Add Goal
</button>
</PlausibleWeb.Components.Generic.button>
</div>
</.form>
</div>

View File

@ -40,9 +40,9 @@ defmodule PlausibleWeb.Live.GoalSettings.List do
</div>
</form>
<div class="mt-4 flex sm:ml-4 sm:mt-0">
<button type="button" phx-click="add-goal" class="button">
<PlausibleWeb.Components.Generic.button phx-click="add-goal">
+ Add Goal
</button>
</PlausibleWeb.Components.Generic.button>
</div>
</div>
<%= if Enum.count(@goals) > 0 do %>

View File

@ -52,9 +52,9 @@ defmodule PlausibleWeb.Live.Plugins.API.Settings do
<div class="mt-4">
<div class="border-t border-gray-200 pt-4 grid">
<div class="mt-4 sm:ml-4 sm:mt-0 justify-self-end">
<button type="button" phx-click="add-token" class="button">
<PlausibleWeb.Components.Generic.button phx-click="add-token">
+ Add Token
</button>
</PlausibleWeb.Components.Generic.button>
</div>
</div>

View File

@ -86,9 +86,9 @@ defmodule PlausibleWeb.Live.Plugins.API.TokenForm do
</span>
</p>
<div class="py-4 mt-8">
<button type="submit" class="button text-base font-bold w-full">
<PlausibleWeb.Components.Generic.button type="submit" class="w-full">
Add Token
</button>
</PlausibleWeb.Components.Generic.button>
</div>
</.form>
</div>

View File

@ -90,9 +90,9 @@ defmodule PlausibleWeb.Live.PropsSettings.Form do
</div>
<div class="py-4">
<button type="submit" class="button text-base font-bold w-full">
<PlausibleWeb.Components.Generic.button type="submit" class="w-full">
Add Property
</button>
</PlausibleWeb.Components.Generic.button>
</div>
<button

View File

@ -40,13 +40,9 @@ defmodule PlausibleWeb.Live.PropsSettings.List do
</div>
</form>
<div class="mt-4 flex sm:ml-4 sm:mt-0">
<button
type="button"
phx-click="add-prop"
class="mt-2 block items-center rounded-md bg-indigo-600 p-2 text-sm text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600"
>
<PlausibleWeb.Components.Generic.button phx-click="add-prop">
+ Add Property
</button>
</PlausibleWeb.Components.Generic.button>
</div>
</div>
<%= if is_list(@props) && length(@props) > 0 do %>

View File

@ -167,10 +167,9 @@ defmodule PlausibleWeb.Live.RegisterForm do
else
"Start my free trial →"
end %>
<button id="register" type="submit" class="button mt-4 w-full">
<PlausibleWeb.Components.Generic.button id="register" type="submit" class="mt-4 w-full">
<%= submit_text %>
</button>
</PlausibleWeb.Components.Generic.button>
<p class="text-center text-gray-600 dark:text-gray-500 text-xs mt-4">
Already have an account? <%= link("Log in",

View File

@ -57,9 +57,9 @@ defmodule PlausibleWeb.Live.ResetPasswordForm do
class="transition bg-gray-100 dark:bg-gray-900 outline-none appearance-none border border-transparent rounded w-full p-2 text-gray-700 dark:text-gray-300 leading-normal appearance-none focus:outline-none focus:bg-white dark:focus:bg-gray-800 focus:border-gray-300 dark:focus:border-gray-500"
/>
</div>
<button id="set" type="submit" class="button mt-4 w-full">
<PlausibleWeb.Components.Generic.button id="set" type="submit" class="mt-4 w-full">
Set password
</button>
</PlausibleWeb.Components.Generic.button>
<p class="text-center text-gray-500 text-xs mt-4">
Don't have an account? <%= link("Register",
to: "/register",

View File

@ -232,7 +232,10 @@
"dark:bg-gray-900 mt-1 block w-full pl-3 pr-10 py-2 text-base border-gray-300 dark:border-gray-500 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm rounded-md dark:text-gray-100 cursor-pointer"
) %>
</div>
<%= submit("Save", class: "button mt-4") %>
<PlausibleWeb.Components.Generic.button type="submit" class="mt-4">
Save
</PlausibleWeb.Components.Generic.button>
<% end %>
</div>
@ -254,7 +257,9 @@
<%= error_tag(f, :name) %>
</div>
</div>
<%= submit("Save", class: "button mt-4") %>
<PlausibleWeb.Components.Generic.button type="submit" class="mt-4">
Save
</PlausibleWeb.Components.Generic.button>
<% end %>
</div>
@ -375,13 +380,13 @@
</div>
<% end %>
<.link
<PlausibleWeb.Components.Generic.button_link
:if={Plausible.Billing.Feature.StatsAPI.check_availability(@current_user) == :ok}
href={Routes.auth_path(@conn, :new_api_key)}
class="button mt-4"
class="mt-4"
>
+ New API Key
</.link>
</PlausibleWeb.Components.Generic.button_link>
</div>
</div>
</div>

View File

@ -31,7 +31,9 @@
for details.
</p>
<%= submit("Change Domain and add new Snippet →", class: "button mt-4 w-full") %>
<PlausibleWeb.Components.Generic.button type="submit" class="mt-4 w-full">
Change Domain and add new Snippet →
</PlausibleWeb.Components.Generic.button>
<div class="text-center mt-4">
<.styled_link

View File

@ -21,12 +21,13 @@
) %>
</div>
</div>
<span class="inline-flex rounded-md shadow-sm">
<%= link("Change Domain",
to: Routes.site_path(@conn, :change_domain, @site.domain),
class: "button"
) %>
</span>
<div>
<PlausibleWeb.Components.Generic.button_link href={
Routes.site_path(@conn, :change_domain, @site.domain)
}>
Change Domain
</PlausibleWeb.Components.Generic.button_link>
</div>
</div>
</div>
@ -54,9 +55,9 @@
) %>
</div>
</div>
<span class="inline-flex rounded-md shadow-sm">
<%= submit("Save", class: "button") %>
</span>
<PlausibleWeb.Components.Generic.button type="submit">
Save
</PlausibleWeb.Components.Generic.button>
</div>
</div>
<% end %>

View File

@ -226,17 +226,10 @@
</div>
<div class="mt-8">
<%= link(to: Routes.membership_path(@conn, :invite_member_form, @site.domain), class: "button") do %>
<svg
class="w-5 h-5 mr-1"
fill="currentColor"
viewBox="0 0 20 20"
xmlns="http://www.w3.org/2000/svg"
>
<path d="M8 9a3 3 0 100-6 3 3 0 000 6zM8 11a6 6 0 016 6H2a6 6 0 016-6zM16 7a1 1 0 10-2 0v1h-1a1 1 0 100 2h1v1a1 1 0 102 0v-1h1a1 1 0 100-2h-1V7z">
</path>
</svg>
Invite
<% end %>
<PlausibleWeb.Components.Generic.button_link href={
Routes.membership_path(@conn, :invite_member_form, @site.domain)
}>
<Heroicons.user_plus solid class="w-5 h-5" /> Invite
</PlausibleWeb.Components.Generic.button_link>
</div>
</div>

View File

@ -147,10 +147,12 @@
</div>
<% end %>
<%= link("+ New Link",
to: Routes.site_path(@conn, :new_shared_link, @site.domain),
class: "button mt-4"
) %>
<PlausibleWeb.Components.Generic.button_link
href={Routes.site_path(@conn, :new_shared_link, @site.domain)}
class="mt-4"
>
+ New Link
</PlausibleWeb.Components.Generic.button_link>
</div>
</div>
@ -220,7 +222,9 @@
</div>
<input type="hidden" id="base-url" value={plausible_url()} />
<button id="generate-embed" class="my-4 button">Generate Embed Code 👇</button>
<PlausibleWeb.Components.Generic.button id="generate-embed" class="mt-4">
Generate Embed Code 👇
</PlausibleWeb.Components.Generic.button>
<div class="mt-2">
<div class="max-w-xl">

View File

@ -232,11 +232,7 @@ defmodule PlausibleWeb.Live.FunnelSettingsTest do
|> element("li#dropdown-step-2-option-1 a")
|> render_click()
save_inactive = ~s/form button#save.cursor-not-allowed/
save_active = ~s/form button#save[type="submit"]/
refute element_exists?(doc, save_active)
assert element_exists?(doc, save_inactive)
assert element_exists?(doc, ~s/form button#save:disabled/)
doc =
lv
@ -251,8 +247,8 @@ defmodule PlausibleWeb.Live.FunnelSettingsTest do
}
})
assert element_exists?(doc, save_active)
refute element_exists?(doc, save_inactive)
assert element_exists?(doc, ~s/form button#save/)
refute element_exists?(doc, ~s/form button#save:disabled/)
end
@tag :slow