From b8d8b1741c7c775c3757ae23f2d98df9ea3532cb Mon Sep 17 00:00:00 2001 From: Ronan Berder Date: Tue, 4 Nov 2025 20:41:23 +0800 Subject: [PATCH] Fixing issues with field --- docs/src/assets/styles.css | 171 +++++++++++----------------------- docs/src/components/field.njk | 91 ++++++++++++------ src/css/basecoat.css | 22 ++++- 3 files changed, 131 insertions(+), 153 deletions(-) diff --git a/docs/src/assets/styles.css b/docs/src/assets/styles.css index 89183ce..498f08d 100644 --- a/docs/src/assets/styles.css +++ b/docs/src/assets/styles.css @@ -5,7 +5,6 @@ :root, :host { --font-sans: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; - --font-serif: ui-serif, Georgia, Cambria, "Times New Roman", Times, serif; --font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; --color-red-500: oklch(63.7% 0.237 25.331); @@ -72,13 +71,6 @@ --radius-md: calc(var(--radius) - 2px); --radius-lg: var(--radius); --radius-xl: calc(var(--radius) + 4px); - --shadow-2xs: 0 1px rgb(0 0 0 / 0.05); - --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.05); - --shadow-sm: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1); - --shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1); - --shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1); - --shadow-xl: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1); - --shadow-2xl: 0 25px 50px -12px rgb(0 0 0 / 0.25); --ease-in-out: cubic-bezier(0.4, 0, 0.2, 1); --animate-spin: spin 1s linear infinite; --animate-pulse: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite; @@ -261,9 +253,6 @@ } } @layer utilities { - .\@container { - container-type: inline-size; - } .pointer-events-none { pointer-events: none; } @@ -302,9 +291,6 @@ .top-0 { top: calc(var(--spacing) * 0); } - .top-1 { - top: calc(var(--spacing) * 1); - } .top-1\/2 { top: calc(1/2 * 100%); } @@ -314,15 +300,9 @@ .top-22 { top: calc(var(--spacing) * 22); } - .right-1 { - right: calc(var(--spacing) * 1); - } .right-1\.5 { right: calc(var(--spacing) * 1.5); } - .right-2 { - right: calc(var(--spacing) * 2); - } .right-2\.5 { right: calc(var(--spacing) * 2.5); } @@ -332,9 +312,6 @@ .bottom-0 { bottom: calc(var(--spacing) * 0); } - .left-1 { - left: calc(var(--spacing) * 1); - } .left-1\.5 { left: calc(var(--spacing) * 1.5); } @@ -416,9 +393,6 @@ .mb-12 { margin-bottom: calc(var(--spacing) * 12); } - .-ml-1 { - margin-left: calc(var(--spacing) * -1); - } .-ml-1\.5 { margin-left: calc(var(--spacing) * -1.5); } @@ -571,30 +545,18 @@ .w-0 { width: calc(var(--spacing) * 0); } - .w-1 { - width: calc(var(--spacing) * 1); - } .w-1\/2 { width: calc(1/2 * 100%); } - .w-2 { - width: calc(var(--spacing) * 2); - } .w-2\/3 { width: calc(2/3 * 100%); } - .w-3 { - width: calc(var(--spacing) * 3); - } .w-3\/4 { width: calc(3/4 * 100%); } .w-4 { width: calc(var(--spacing) * 4); } - .w-7 { - width: calc(var(--spacing) * 7); - } .w-7\.5 { width: calc(var(--spacing) * 7.5); } @@ -697,29 +659,14 @@ .shrink-0 { flex-shrink: 0; } - .border-collapse { - border-collapse: collapse; - } - .-translate-x-1 { - --tw-translate-x: calc(var(--spacing) * -1); - translate: var(--tw-translate-x) var(--tw-translate-y); - } .-translate-x-1\/2 { --tw-translate-x: calc(calc(1/2 * 100%) * -1); translate: var(--tw-translate-x) var(--tw-translate-y); } - .-translate-y-1 { - --tw-translate-y: calc(var(--spacing) * -1); - translate: var(--tw-translate-x) var(--tw-translate-y); - } .-translate-y-1\/2 { --tw-translate-y: calc(calc(1/2 * 100%) * -1); translate: var(--tw-translate-x) var(--tw-translate-y); } - .translate-y-0 { - --tw-translate-y: calc(var(--spacing) * 0); - translate: var(--tw-translate-x) var(--tw-translate-y); - } .translate-y-0\.5 { --tw-translate-y: calc(var(--spacing) * 0.5); translate: var(--tw-translate-x) var(--tw-translate-y); @@ -736,9 +683,6 @@ .cursor-pointer { cursor: pointer; } - .resize { - resize: both; - } .scroll-m-20 { scroll-margin: calc(var(--spacing) * 20); } @@ -793,9 +737,6 @@ .justify-start { justify-content: flex-start; } - .gap-0 { - gap: calc(var(--spacing) * 0); - } .gap-0\.5 { gap: calc(var(--spacing) * 0.5); } @@ -857,9 +798,6 @@ margin-block-end: calc(calc(var(--spacing) * 6) * calc(1 - var(--tw-space-y-reverse))); } } - .gap-x-1 { - column-gap: calc(var(--spacing) * 1); - } .gap-x-1\.5 { column-gap: calc(var(--spacing) * 1.5); } @@ -1045,9 +983,6 @@ .bg-transparent { background-color: transparent; } - .mask-repeat { - mask-repeat: repeat; - } .object-cover { object-fit: cover; } @@ -1099,9 +1034,6 @@ .px-\[0\.3rem\] { padding-inline: 0.3rem; } - .py-1 { - padding-block: calc(var(--spacing) * 1); - } .py-1\.5 { padding-block: calc(var(--spacing) * 1.5); } @@ -1117,9 +1049,6 @@ .py-\[0\.2rem\] { padding-block: 0.2rem; } - .pt-1 { - padding-top: calc(var(--spacing) * 1); - } .pt-1\.5 { padding-top: calc(var(--spacing) * 1.5); } @@ -1275,9 +1204,6 @@ .text-balance { text-wrap: balance; } - .text-wrap { - text-wrap: wrap; - } .break-words { overflow-wrap: break-word; } @@ -1975,11 +1901,6 @@ } } } - .\[\&_\.text-muted-foreground\]\:hidden { - & .text-muted-foreground { - display: none; - } - } .\[\&_\[data-name\]\]\:hidden { & [data-name] { display: none; @@ -2142,11 +2063,6 @@ padding-top: calc(var(--spacing) * 2); } } - .\[\&_span\]\:hidden { - & span { - display: none; - } - } .\[\&_svg\]\:pointer-events-none { & svg { pointer-events: none; @@ -2201,11 +2117,6 @@ padding-left: calc(var(--spacing) * 4); } } - .\[\&\.text-muted-foreground\]\:hidden { - &.text-muted-foreground { - display: none; - } - } .md\:\*\:\[\.card\]\:basis-1\/4 { @media (width >= 48rem) { :is(& > *) { @@ -2234,16 +2145,6 @@ } } } - .\[\&\>\.text-muted-foreground\]\:hidden { - &>.text-muted-foreground { - display: none; - } - } - .\[\&\>\[data-name\]\]\:hidden { - &>[data-name] { - display: none; - } - } .\[\&\>a\]\:underline { &>a { text-decoration-line: underline; @@ -2259,16 +2160,6 @@ color: var(--color-primary); } } - .\[\&\>em\]\:hidden { - &>em { - display: none; - } - } - .\[\&\>span_\.text-muted-foreground\]\:hidden { - &>span .text-muted-foreground { - display: none; - } - } .\[\&\>svg\]\:mb-3 { &>svg { margin-bottom: calc(var(--spacing) * 3); @@ -3666,9 +3557,7 @@ --tw-font-weight: var(--font-weight-medium); font-weight: var(--font-weight-medium); & + p { - font-size: var(--text-sm); - line-height: var(--tw-leading, var(--text-sm--line-height)); - color: var(--color-muted-foreground); + margin-top: calc(var(--spacing) * -1.5); } } } @@ -3686,17 +3575,63 @@ &>.sr-only { width: auto; } - .description { - font-size: var(--text-sm); - line-height: var(--tw-leading, var(--text-sm--line-height)); - color: var(--color-muted-foreground); - } - .error { + h2, h3 { + display: flex; + width: fit-content; + align-items: center; + gap: calc(var(--spacing) * 2); font-size: var(--text-sm); line-height: var(--tw-leading, var(--text-sm--line-height)); + --tw-leading: var(--leading-snug); + line-height: var(--leading-snug); --tw-font-weight: var(--font-weight-medium); font-weight: var(--font-weight-medium); + } + [role="alert"] { + font-size: var(--text-sm); + line-height: var(--tw-leading, var(--text-sm--line-height)); + --tw-font-weight: var(--font-weight-normal); + font-weight: var(--font-weight-normal); color: var(--color-destructive); + ul { + margin-left: calc(var(--spacing) * 4); + display: flex; + list-style-type: disc; + flex-direction: column; + gap: calc(var(--spacing) * 1); + } + } + section { + display: flex; + flex: 1; + flex-direction: column; + gap: calc(var(--spacing) * 1.5); + --tw-leading: var(--leading-snug); + line-height: var(--leading-snug); + } + } + .fieldset legend + p, .field p { + font-size: var(--text-sm); + line-height: var(--tw-leading, var(--text-sm--line-height)); + --tw-leading: var(--leading-normal); + line-height: var(--leading-normal); + --tw-font-weight: var(--font-weight-normal); + font-weight: var(--font-weight-normal); + color: var(--color-muted-foreground); + &:last-child { + margin-top: calc(var(--spacing) * 0); + } + &:nth-last-child(2) { + margin-top: calc(var(--spacing) * -1); + } + &>a { + text-decoration-line: underline; + } + &>a { + text-underline-offset: 4px; + } + &>a:hover { + color: var(--color-primary); } } } diff --git a/docs/src/components/field.njk b/docs/src/components/field.njk index 3589847..74e7f7e 100644 --- a/docs/src/components/field.njk +++ b/docs/src/components/field.njk @@ -27,6 +27,11 @@ toc: {% from "macros/code_preview.njk" import code_preview %} {% from "macros/code_block.njk" import code_block %} +
+ {% lucide "triangle-alert"%} +

This component is still under development, API may change.

+
+ {% set code_demo %}
@@ -41,7 +46,7 @@ toc:
-

Enter your 16-digit card number

+

Enter your 16-digit card number

@@ -115,18 +120,44 @@ toc:

Usage

-

Field provides semantic HTML patterns for accessible forms:

+

Field uses semantic HTML with minimal classes. Two main patterns can be used independently or composed together:

    -
  • <fieldset> and <legend> for grouping related fields
  • -
  • <p> after <legend> is automatically styled as description text
  • -
  • role="group" with .field class for individual field containers
  • -
  • .description class for field-level helper text (requires aria-describedby)
  • -
  • .error class with role="alert" for error messages
  • +
  • <div role="group" class="field"> for individual field containers (label, input, helper text, errors)
  • +
  • <fieldset class="fieldset"> for grouping multiple related fields together
+

Elements inside these containers are styled automatically based on their purpose. Use aria-describedby to connect helper text and errors to inputs for accessibility.

+

Fields have the following HTML structure:

+
+
<div role="group" class="field">
+
Field container. +
+
<label>
+
Label for the input.
+
<input>, <select> or <textarea>
+
Form input.
+
<p> Optional
+
Helper text. Use aria-describedby on the input to reference this element's id.
+
<p role="alert"> Optional
+
Error message. Use aria-describedby on the input and aria-invalid="true" to reference this element's id.
+
+
+
+

Fieldsets have the following HTML structure:

+
+
<fieldset class="fieldset">
+
Container for grouping related fields. +
+
<legend>
+
Heading for the fieldset.
+
<p> Optional
+
Description text. When placed directly after <legend>, automatically styled as muted text.
+
<div role="group" class="field"> Optional
+
Individual field containers (see structure above). You can include multiple .field elements, or place form controls directly in the fieldset.
+
+
+
-{{ code_block(code) }} -

Examples

Input

@@ -136,12 +167,12 @@ toc:
-

Choose a unique username for your account.

+

Choose a unique username for your account.

-

Must be at least 8 characters long.

+

Must be at least 8 characters long.

@@ -155,7 +186,7 @@ toc:
-

Share your thoughts about our service.

+

Share your thoughts about our service.

{% endset %} @@ -177,7 +208,7 @@ toc: -

Select your department or area of work.

+

Select your department or area of work.

{% endset %} @@ -188,7 +219,7 @@ toc: {% set code %}
-

Set your budget: $150

+

Set your budget: $150