feat: add focus-visible rings and refactor accordion chevron
Add global :focus-visible outline style and migrate form components from :focus box-shadow to :focus-visible outline. Refactor accordion chevron from CSS ::after pseudo-element to explicit span element.
This commit is contained in:
@@ -26,7 +26,9 @@
|
||||
base-attrs (cond-> (merge {:class classes} attrs)
|
||||
open (assoc :open true))]
|
||||
[:details base-attrs
|
||||
[:summary {:class "accordion-trigger"} title]
|
||||
[:summary {:class "accordion-trigger"}
|
||||
[:span {:class "accordion-trigger-text"} title]
|
||||
[:span {:class "accordion-chevron" :aria-hidden "true"}]]
|
||||
(into [:div {:class "accordion-content"}] children)])
|
||||
|
||||
:cljs
|
||||
@@ -35,7 +37,9 @@
|
||||
base-attrs (cond-> (merge {:class classes} attrs)
|
||||
open (assoc :open true))]
|
||||
[:details base-attrs
|
||||
[:summary {:class ["accordion-trigger"]} title]
|
||||
[:summary {:class ["accordion-trigger"]}
|
||||
[:span {:class ["accordion-trigger-text"]} title]
|
||||
[:span {:class ["accordion-chevron"] :aria-hidden "true"}]]
|
||||
(into [:div {:class ["accordion-content"]}] children)])
|
||||
|
||||
:clj
|
||||
@@ -44,5 +48,7 @@
|
||||
base-attrs (cond-> (merge {:class classes} attrs)
|
||||
open (assoc :open true))]
|
||||
[:details base-attrs
|
||||
[:summary {:class "accordion-trigger"} title]
|
||||
[:summary {:class "accordion-trigger"}
|
||||
[:span {:class "accordion-trigger-text"} title]
|
||||
[:span {:class "accordion-chevron" :aria-hidden "true"}]]
|
||||
(into [:div {:class "accordion-content"}] children)])))
|
||||
|
||||
@@ -9,6 +9,10 @@
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.accordion-trigger:focus-visible {
|
||||
outline-offset: -2px;
|
||||
}
|
||||
|
||||
.accordion + .accordion {
|
||||
margin-top: -1px;
|
||||
border-top-left-radius: 0;
|
||||
@@ -25,7 +29,6 @@
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: var(--size-2);
|
||||
width: 100%;
|
||||
padding: var(--size-4);
|
||||
font-weight: 500;
|
||||
font-size: inherit;
|
||||
@@ -50,15 +53,20 @@
|
||||
background: var(--bg-1);
|
||||
}
|
||||
|
||||
.accordion-trigger::after {
|
||||
content: "";
|
||||
.accordion-trigger-text {
|
||||
flex: 1;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.accordion-chevron {
|
||||
display: block;
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
flex-shrink: 0;
|
||||
background-color: currentColor;
|
||||
mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
|
||||
mask-size: contain;
|
||||
mask-repeat: no-repeat;
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%2371717a' stroke-width='2'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
|
||||
background-size: contain;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
transition: transform 150ms ease;
|
||||
}
|
||||
|
||||
@@ -66,7 +74,7 @@
|
||||
border-bottom: var(--border-0);
|
||||
}
|
||||
|
||||
.accordion[open] > .accordion-trigger::after {
|
||||
.accordion[open] > .accordion-trigger .accordion-chevron {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
|
||||
@@ -63,6 +63,17 @@
|
||||
margin: 0;
|
||||
background: var(--bg-0);
|
||||
color: var(--fg-0);
|
||||
}
|
||||
|
||||
:focus-visible {
|
||||
outline: 2px solid var(--accent);
|
||||
outline-offset: 2px;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
:focus:not(:focus-visible) {
|
||||
outline: none;
|
||||
box-shadow: none;
|
||||
}")
|
||||
|
||||
(defn collect-component-css
|
||||
|
||||
@@ -23,10 +23,10 @@
|
||||
border-color: var(--danger);
|
||||
}
|
||||
|
||||
.form-field--error .form-input:focus,
|
||||
.form-field--error .form-textarea:focus,
|
||||
.form-field--error .form-select:focus {
|
||||
box-shadow: 0 0 0 2px color-mix(in srgb, var(--danger) 20%, transparent);
|
||||
.form-field--error .form-input:focus-visible,
|
||||
.form-field--error .form-textarea:focus-visible,
|
||||
.form-field--error .form-select:focus-visible {
|
||||
outline-color: var(--danger);
|
||||
}
|
||||
|
||||
/* ── Label ─────────────────────────────────────────────────────── */
|
||||
@@ -60,12 +60,11 @@
|
||||
color: var(--fg-2);
|
||||
}
|
||||
|
||||
.form-input:focus,
|
||||
.form-textarea:focus,
|
||||
.form-select:focus {
|
||||
outline: none;
|
||||
.form-input:focus-visible,
|
||||
.form-textarea:focus-visible,
|
||||
.form-select:focus-visible {
|
||||
border-color: var(--accent);
|
||||
box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent) 20%, transparent);
|
||||
outline-offset: -1px;
|
||||
}
|
||||
|
||||
.form-input:disabled,
|
||||
@@ -81,9 +80,9 @@
|
||||
border-color: var(--danger);
|
||||
}
|
||||
|
||||
.form-input--error:focus,
|
||||
.form-textarea--error:focus {
|
||||
box-shadow: 0 0 0 2px color-mix(in srgb, var(--danger) 20%, transparent);
|
||||
.form-input--error:focus-visible,
|
||||
.form-textarea--error:focus-visible {
|
||||
outline-color: var(--danger);
|
||||
}
|
||||
|
||||
/* ── Textarea ──────────────────────────────────────────────────── */
|
||||
@@ -148,10 +147,9 @@
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
.form-checkbox:focus,
|
||||
.form-radio:focus {
|
||||
outline: none;
|
||||
box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent) 20%, transparent);
|
||||
.form-checkbox:focus-visible,
|
||||
.form-radio:focus-visible {
|
||||
outline-offset: 0;
|
||||
}
|
||||
|
||||
.form-checkbox:disabled,
|
||||
|
||||
Reference in New Issue
Block a user