Nicer passkey styles
This commit is contained in:
@@ -1,29 +1,34 @@
|
|||||||
@layer components {
|
@layer components {
|
||||||
.passkey-icon--dark {
|
.credential {
|
||||||
display: none;
|
border-block-start: var(--border);
|
||||||
|
list-style: none;
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
border-block-end: var(--border);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.passkey-icon--light {
|
.credential__link {
|
||||||
html[data-theme="dark"] & {
|
align-items: center;
|
||||||
display: none;
|
block-size: 1.75lh;
|
||||||
}
|
color: currentcolor;
|
||||||
|
display: flex;
|
||||||
|
gap: 1ch;
|
||||||
|
padding-inline: 1ch;
|
||||||
|
|
||||||
@media (prefers-color-scheme: dark) {
|
@media (any-hover: hover) {
|
||||||
html:not([data-theme]) & {
|
&:hover {
|
||||||
display: none;
|
background: var(--color-ink-lightest);
|
||||||
|
|
||||||
|
.credential__arrow {
|
||||||
|
opacity: 0.66;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.passkey-icon--dark {
|
.credential__arrow {
|
||||||
html[data-theme="dark"] & {
|
margin-inline-start: auto;
|
||||||
display: inline;
|
opacity: 0;
|
||||||
}
|
|
||||||
|
|
||||||
@media (prefers-color-scheme: dark) {
|
|
||||||
html:not([data-theme]) & {
|
|
||||||
display: inline;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,9 +31,10 @@
|
|||||||
.txt-capitalize-first-letter::first-letter { text-transform: capitalize; }
|
.txt-capitalize-first-letter::first-letter { text-transform: capitalize; }
|
||||||
.txt-link { color: var(--color-link); text-decoration: underline; }
|
.txt-link { color: var(--color-link); text-decoration: underline; }
|
||||||
|
|
||||||
.font-weight-normal { font-weight: normal; }
|
.font-weight-normal { font-weight: 400; }
|
||||||
|
.font-weight-medium { font-weight: 500; }
|
||||||
.font-weight-semibold { font-weight: 600; }
|
.font-weight-semibold { font-weight: 600; }
|
||||||
.font-weight-bold { font-weight: bold; }
|
.font-weight-bold { font-weight: 700; }
|
||||||
.font-weight-black { font-weight: 900; }
|
.font-weight-black { font-weight: 900; }
|
||||||
|
|
||||||
/* Flexbox and Grid */
|
/* Flexbox and Grid */
|
||||||
@@ -283,4 +284,28 @@
|
|||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.hide-on-dark-mode {
|
||||||
|
html[data-theme="dark"] & {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
html:not([data-theme]) & {
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.hide-on-light-mode {
|
||||||
|
html[data-theme="light"] & {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
html:not([data-theme]) & {
|
||||||
|
@media (prefers-color-scheme: light) {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
<li class="list-style-none margin-none" style="view-transition-name: <%= dom_id(credential) %>">
|
<li class="credential" style="view-transition-name: <%= dom_id(credential) %>">
|
||||||
<%= link_to edit_user_credential_path(Current.user, credential), class: "txt-ink flex align-center gap txt-medium full-width" do %>
|
<%= link_to edit_user_credential_path(Current.user, credential), class: "credential__link" do %>
|
||||||
<% authenticator = credential.authenticator %>
|
<% authenticator = credential.authenticator %>
|
||||||
<%= image_tag authenticator&.icon&.[](:light) || "passkeys/generic_light.svg", size: 24, class: "flex-item-no-shrink passkey-icon passkey-icon--light", aria: { hidden: true } %>
|
<%= image_tag authenticator&.icon&.[](:light) || "passkeys/generic_light.svg", size: 24, class: "flex-item-no-shrink hide-on-dark-mode", aria: { hidden: true } %>
|
||||||
<%= image_tag authenticator&.icon&.[](:dark) || "passkeys/generic_dark.svg", size: 24, class: "flex-item-no-shrink passkey-icon passkey-icon--dark", aria: { hidden: true } %>
|
<%= image_tag authenticator&.icon&.[](:dark) || "passkeys/generic_dark.svg", size: 24, class: "flex-item-no-shrink hide-on-light-mode", aria: { hidden: true } %>
|
||||||
<strong class="overflow-ellipsis min-width"><%= credential.name.presence || "Passkey" %></strong>
|
<strong class="overflow-ellipsis min-width"><%= credential.name.presence || "Passkey" %></strong>
|
||||||
<hr class="separator--horizontal flex-item-grow" style="--border-color: var(--color-ink-medium); --border-style: dashed" aria-hidden="true">
|
<strong class="credential__arrow">→</strong>
|
||||||
<%= icon_tag "arrow-right", class: "txt-subtle txt-xx-small flex-item-no-shrink" %>
|
|
||||||
<% end %>
|
<% end %>
|
||||||
</li>
|
</li>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<% @page_title = "Name your passkey" %>
|
<% @page_title = "Edit Passkey" %>
|
||||||
|
|
||||||
<% content_for :header do %>
|
<% content_for :header do %>
|
||||||
<div class="header__actions header__actions--start">
|
<div class="header__actions header__actions--start">
|
||||||
@@ -15,11 +15,11 @@
|
|||||||
|
|
||||||
<%= form_with model: @credential, scope: :credential, url: user_credential_path(Current.user, @credential), html: { class: "flex flex-column gap" } do |form| %>
|
<%= form_with model: @credential, scope: :credential, url: user_credential_path(Current.user, @credential), html: { class: "flex flex-column gap" } do |form| %>
|
||||||
<div class="flex flex-column gap-half">
|
<div class="flex flex-column gap-half">
|
||||||
<strong><%= form.label :name %></strong>
|
<strong><%= form.label "Name your passkey" %></strong>
|
||||||
<%= form.text_field :name, autofocus: true, class: "input", placeholder: "e.g. MacBook Pro, iPhone", data: { "1p-ignore": "" }, autocomplete: "off" %>
|
<%= form.text_field :name, autofocus: true, class: "input", placeholder: "e.g. MacBook Pro, iPhone", data: { "1p-ignore": "" }, autocomplete: "off" %>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<%= form.submit "Save", class: "btn btn--primary" %>
|
<%= form.submit "Save", class: "btn btn--link center" %>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<div class="txt-align-center">
|
<div class="txt-align-center">
|
||||||
|
|||||||
@@ -13,28 +13,31 @@
|
|||||||
data-credential-public-key-value="<%= @creation_options.as_json.to_json %>"
|
data-credential-public-key-value="<%= @creation_options.as_json.to_json %>"
|
||||||
data-credential-register-url-value="<%= user_credentials_path(Current.user) %>">
|
data-credential-register-url-value="<%= user_credentials_path(Current.user) %>">
|
||||||
|
|
||||||
<p class="margin-none-block-start"><strong>Passkeys let you sign in securely without a password or email code.</strong></p>
|
<p class="font-weight-medium margin-none-block-start">Passkeys let you sign in securely without a password or email code.</p>
|
||||||
|
|
||||||
<% if @credentials.any? %>
|
<% if @credentials.any? %>
|
||||||
<ul class="flex flex-column gap margin-none-block-start unpad full-width">
|
<ul class="margin-none-block-start margin-block-end-double unpad">
|
||||||
<%= render partial: "users/credentials/credential", collection: @credentials %>
|
<%= render partial: "users/credentials/credential", collection: @credentials %>
|
||||||
</ul>
|
</ul>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<p class="txt-small pad-inline-double pad-block-half">Your browser will prompt you to create a passkey
|
<footer>
|
||||||
using your device's biometrics, PIN, or security key</p>
|
<button type="button" data-action="credential#create" data-credential-target="button" class="btn btn--link center txt-medium">
|
||||||
|
<%= icon_tag "add" %>
|
||||||
|
<span>Register a passkey</span>
|
||||||
|
</button>
|
||||||
|
|
||||||
<button type="button" data-action="credential#create" data-credential-target="button" class="btn btn--link center txt-medium">
|
<p class="txt-small txt-subtle txt-balance margin-none-block-end">
|
||||||
<%= icon_tag "add" %>
|
Your browser will prompt you to create a passkey using your device's biometrics, PIN, or security key
|
||||||
<span>Register passkey</span>
|
</p>
|
||||||
</button>
|
|
||||||
|
|
||||||
<p data-credential-target="error" class="txt-negative" hidden>
|
<p data-credential-target="error" class="txt-negative" hidden>
|
||||||
Something went wrong while registering your passkey.
|
Something went wrong while registering your passkey.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p data-credential-target="cancelled" class="txt-subtle" hidden>
|
<p data-credential-target="cancelled" class="txt-subtle" hidden>
|
||||||
Passkey registration was cancelled.
|
Passkey registration was cancelled.
|
||||||
Try again when you are ready.
|
Try again when you are ready.
|
||||||
</p>
|
</p>
|
||||||
|
</footer>
|
||||||
</section>
|
</section>
|
||||||
|
|||||||
Reference in New Issue
Block a user