From 5c2c6a0a8f1854f11bbc1ece0908ca367b55987d Mon Sep 17 00:00:00 2001 From: Ajay Ghanwat Date: Sun, 9 Aug 2026 13:58:13 +0530 Subject: [PATCH] refactor(ui): replace Tailwind utilities with local styles --- docs/ui-visual-contract-0.8.json | 14 ++-- packages/cli/src/update.ts | 17 ++++ packages/ui/README.md | 14 ++-- packages/ui/components/InputNumber.wrn | 108 +++++++++++++++++++------ packages/ui/components/List.wrn | 95 +++++++++++++--------- packages/ui/components/Map.wrn | 54 ++++++++----- packages/ui/components/Marquee.wrn | 59 +++++++++----- packages/ui/components/SearchBox.wrn | 91 ++++++++++++++++++--- packages/ui/components/TextLink.wrn | 94 ++++++++++++++------- packages/ui/components/Timeline.wrn | 73 +++++++++++------ packages/ui/test/ui.test.ts | 38 +++++++++ 11 files changed, 473 insertions(+), 184 deletions(-) diff --git a/docs/ui-visual-contract-0.8.json b/docs/ui-visual-contract-0.8.json index a81ef0ff..8f7c7a60 100644 --- a/docs/ui-visual-contract-0.8.json +++ b/docs/ui-visual-contract-0.8.json @@ -46,16 +46,16 @@ "packages/ui/components/HeroActions.wrn": "c5720efe2ce7f6c114eb2ea4ccc3e8102a1099078ba23fd13770eddeb6aec640", "packages/ui/components/Image.wrn": "8113441bf90ab0d1d8618d477125ad339021f39e853db89d656c72c492e7a20b", "packages/ui/components/InputGroup.wrn": "7347865ff9b90dde690cf0753adc753a91d2ae599e92405f47e5b35806f58e06", - "packages/ui/components/InputNumber.wrn": "3850f1cbcd314367e17244c644f1115e5ecddc7dc8248aa33fee88936c2981db", + "packages/ui/components/InputNumber.wrn": "0ec020084f3e556d438f8264d61f836cfab4951c52d4df60e4944fb734fb38a9", "packages/ui/components/Kbd.wrn": "5afaabbb15902bd8fb82cb4155cf6cbfff55600927b54d564d27e2dd8b752386", "packages/ui/components/LayoutSplitter.wrn": "6bd6812e364420ed5d3439862116c58d0b011b298679005795bdccdbb7455066", "packages/ui/components/LegendIndicator.wrn": "6a7607b27a17196f899132eb952203a1073e4077365a94935f485e700cbac665", "packages/ui/components/Link.wrn": "b986abcc66bc0b1c6296f3ff4e560812e35d89cc680d5251d7a3883e68c1d053", - "packages/ui/components/List.wrn": "11e07bbf25956c9b0116ac100c2deda0455d5e1679bfc3395450ea3a8bf23f22", + "packages/ui/components/List.wrn": "9bfa9613f388e5b126fc27d505e8165d7aa4a058e72132b755585464e116490e", "packages/ui/components/ListGroup.wrn": "37e2ec61ceab20ed020a834da03208c493702b41abcf586816e29f2e50d8ee11", - "packages/ui/components/Map.wrn": "2e2335a8ef3da51519478ccbc380adeb37c97ae84336c4e94d4d0ceb857f391e", + "packages/ui/components/Map.wrn": "9023a7a188480b24222a3910d26f6926918470369a1ab610f841c31a6120b9aa", "packages/ui/components/MarketingSectionHeader.wrn": "7d6ffcc01a9331474475ea57ca58598be757abd9428b66bdfaf6f3603c5b145b", - "packages/ui/components/Marquee.wrn": "59c6b30bfa4d3a2084a7454c856dcd2f24d20d67c559cb2434f466f418c6cd87", + "packages/ui/components/Marquee.wrn": "2a88c8bd8378469add26b0d937adccac4aa9f2c2005393010298e8e4fa89693e", "packages/ui/components/MegaMenu.wrn": "8a9a9b348ca1c5e182914ff55d981a91f47a49c52ef5e5efd8e4cb6e56361a43", "packages/ui/components/MetricCard.wrn": "6451182739298691908f68258c0250cce2a78b0dc27c97115579ece30d7d9f92", "packages/ui/components/MetricGrid.wrn": "6018a98c10628ed240ed236ed916c0ff60994d192c3aadafd10bc876be0f9364", @@ -72,7 +72,7 @@ "packages/ui/components/RangeSlider.wrn": "90ef35ceb94899dfd6e07ef3f3a88f2fb49c8dfe4596def67fe39fd9911d73c7", "packages/ui/components/Rating.wrn": "a2d74dc748fc7d98892684c760518b87fa65411b1102e3611252b87245b3ffcb", "packages/ui/components/Scrollspy.wrn": "76d1c17580c8d460f1222ce97585bdcac9779141f2f30d5460c84ff9f75413d8", - "packages/ui/components/SearchBox.wrn": "ab6a78b88aef494b85a87470d4392303d9d1937a5327f1c8aa8d910f1b1829c7", + "packages/ui/components/SearchBox.wrn": "717f7647fabd762f8ed60a7c3306eac3ddb83c0da292a53c76d91886c2b8f94f", "packages/ui/components/Section.wrn": "33eb8a82a2102229c2b1f64cec497e9e8e70b67adab8dbe396be860fccbb699c", "packages/ui/components/SectionHeader.wrn": "8eecf2ea7a93139512260e3d46ca2a1afeb341b8bd46b7c30baa6e2c75e25d10", "packages/ui/components/Sidebar.wrn": "03f1bbce75ca6d50ed940e62df39c539610e89eadd2064fe24abc7d5470f98bf", @@ -82,9 +82,9 @@ "packages/ui/components/StrongPassword.wrn": "9559756cacd10d613aea7a4ab9845a011f7f2f4613f82f83c87ab5fd2bad2ea9", "packages/ui/components/StyledIcon.wrn": "4a4504e357dee9dd0418edbe85fc90b824ccdb3752123a2125da95b77bf0b336", "packages/ui/components/Tabs.wrn": "e38336d28876caa4e97da32a569749e3803b030284a85ce9f35fa788e51cc5b0", - "packages/ui/components/TextLink.wrn": "30782039293eb36d63b7b3a4f32a71a47177a3a68c7e90184be7cf7b4385eb19", + "packages/ui/components/TextLink.wrn": "6e18906337cd3d30c2a0122593d249bde8f7cedc697b90ae388e2bd0e8eff3e1", "packages/ui/components/TimePicker.wrn": "b3f24767448cb04ddd56e06540b52e5cc32ea21ed4acd2a5eb4f7e46f8617aba", - "packages/ui/components/Timeline.wrn": "eaa6764b9e62c28cb6919ac1e86d3ebe9abc3cd8036091cdb703540dbfc33873", + "packages/ui/components/Timeline.wrn": "686a37ebc62732842846d004491336970db94945bca942f226097d863e159d1c", "packages/ui/components/Toaster.wrn": "288b2b370f65bf823e8d2a6f8c8cf66972332b8174303d33ebe8546d5e1d52c4", "packages/ui/components/ToggleCount.wrn": "ee706b191fcfc01dd7bde0ddba1940af400ed2d01b639016134699963b1000ab", "packages/ui/components/TogglePassword.wrn": "c644436c3435b8a9b39c6b7a9f75671b76ca74f273952ce5c032ca169b0470e5", diff --git a/packages/cli/src/update.ts b/packages/cli/src/update.ts index 6d79fb18..e68d2b87 100644 --- a/packages/cli/src/update.ts +++ b/packages/cli/src/update.ts @@ -2098,6 +2098,23 @@ const MIGRATIONS: Migration[] = [ // start painting where they previously rendered as nothing. }, }, + { + version: "0.8.7", + id: "0.8.7-ui-component-depth", + description: + "Removes superseded UI scaffolds and moves the remaining utility-styled components to self-contained wire-* BEM styles.", + apply() { + // AdvancedDatePicker -> DatePicker; AdvancedRangeSlider -> RangeSlider; + // FileUpload -> FileInput + FileUploadProgress (or @wrnexus/uploader); + // Toast and ToastNotifications -> Toaster. + // + // List, InputNumber, Marquee, TextLink, Map, SearchBox and Timeline no + // longer render Tailwind utility class names. Application CSS selecting + // those internal utilities must move to the component's wire-* BEM + // classes or its data-size/data-variant attributes. List now emits + // select for non-link items as well as navigation items. + }, + }, ]; /** Release tooling uses this to require an explicit migration entry per version. */ diff --git a/packages/ui/README.md b/packages/ui/README.md index 14e79db6..5ddddced 100644 --- a/packages/ui/README.md +++ b/packages/ui/README.md @@ -118,16 +118,12 @@ are `.wrn` files rendered server-side. The framework serves this stylesheet once at `/__wrnexus/ui.css`, so pages get all component styles from a single request. -### Tailwind and motion +### Component styles and motion -Components use static Tailwind utility classes alongside the shared `.wire-*` -layer. If the package is consumed by a separate Tailwind build, include its -component sources so every utility is generated: - -```css -@import "tailwindcss"; -@source "../node_modules/@wrnexus/ui/components/*.wrn"; -``` +Components own their BEM styles in local `style {}` blocks and do not require a +Tailwind scan. `ui.css` supplies only global tokens, resets, and shared +primitives. Applications can still use Tailwind independently in their own +source files. The shared stylesheet gives all component boundaries consistent, GPU-friendly entry and interaction motion. Override `--wire-motion-fast`, diff --git a/packages/ui/components/InputNumber.wrn b/packages/ui/components/InputNumber.wrn index f6e62742..4671f82f 100644 --- a/packages/ui/components/InputNumber.wrn +++ b/packages/ui/components/InputNumber.wrn @@ -418,19 +418,20 @@ component InputNumber { data-value='{currentValue}' data-invalid='{isInvalid() ? "true" : "false"}' data-disabled='{disabled ? "true" : "false"}' + data-full-width='{fullWidth ? "true" : "false"}' style='--input-number-accent: {componentColor()};' - class='relative flex flex-col gap-1.5 text-[var(--wire-color-text)] {fullWidth ? "w-full" : variant === "compact" ? "w-fit max-w-full" : "w-full max-w-sm"} {disabled ? "opacity-60" : ""} {class}' + class='wire-input-number {class}' > {#if label !== "" && variant !== "labeled" && variant !== "seat"} @@ -439,14 +440,14 @@ component InputNumber { {#if description !== "" && variant !== "labeled" && variant !== "seat"}

{description}

{/if}
{#if variant === "horizontal" && showButtons} {/if}
{#if variant === "labeled" || variant === "seat"} -
+
{#if label !== ""} @@ -487,7 +488,7 @@ component InputNumber { {#if description !== ""} {description} @@ -496,12 +497,12 @@ component InputNumber { {/if}
{#if prefix !== ""} @@ -531,13 +532,13 @@ component InputNumber { @change='handleChange(event)' @keydown='handleKeydown(event)' @wheel='handleWheel(event)' - class='min-w-0 flex-1 appearance-none border-0 bg-transparent p-0 font-medium leading-none text-[var(--wire-color-text)] outline-none placeholder:text-[var(--wire-color-muted)] read-only:cursor-default disabled:cursor-not-allowed [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none {variant === "horizontal" || variant === "compact" || variant === "seat" ? "text-center" : "text-left"} {variant === "seat" ? "w-10 flex-none" : "w-full"}' + class='wire-input-number__input' /> {#if suffix !== ""} @@ -552,11 +553,11 @@ component InputNumber { aria-controls='{inputId()}' disabled='{incrementDisabled()}' @click='incrementValue(event)' - class='inline-flex shrink-0 items-center justify-center border-l border-[var(--wire-color-border)] bg-transparent text-[var(--wire-color-muted)] transition-[color,background-color] duration-[var(--wire-motion-fast)] hover:bg-[var(--wire-color-surface-2)] hover:text-[var(--input-number-accent)] focus-visible:z-10 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-[var(--input-number-accent)] disabled:cursor-not-allowed disabled:opacity-40 {size === "xs" ? "w-8" : size === "sm" ? "w-9" : size === "lg" ? "w-12" : size === "xl" ? "w-14" : "w-10"}' + class='wire-input-number__button wire-input-number__button--end' > {:else} @@ -564,7 +565,7 @@ component InputNumber {
@@ -586,11 +587,11 @@ component InputNumber { aria-controls='{inputId()}' disabled='{incrementDisabled()}' @click='incrementValue(event)' - class='inline-flex items-center justify-center bg-transparent text-[var(--wire-color-muted)] transition-[color,background-color] duration-[var(--wire-motion-fast)] hover:bg-[var(--wire-color-surface-2)] hover:text-[var(--input-number-accent)] focus-visible:z-10 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-[var(--input-number-accent)] disabled:cursor-not-allowed disabled:opacity-40 {variant === "vertical" ? "flex-1" : ""} {size === "xs" ? "w-8" : size === "sm" ? "w-9" : size === "lg" ? "w-12" : size === "xl" ? "w-14" : "w-10"}' + class='wire-input-number__button wire-input-number__button--increment' >
@@ -603,11 +604,11 @@ component InputNumber { id='{messageId()}' role="alert" aria-live="polite" - class='m-0 flex items-center gap-1.5 text-xs leading-5 text-[var(--wire-color-danger)]' + class='wire-input-number__message wire-input-number__message--error' > {validationMessage()}

@@ -616,11 +617,66 @@ component InputNumber { {#if (!showValidationMessage || !isInvalid() || validationMessage() === "") && helpText !== ""}

{helpText}

{/if}
} + + style { + .wire-input-number { position: relative; display: flex; width: 100%; max-width: 24rem; flex-direction: column; gap: 0.375rem; color: var(--wire-color-text); } + .wire-input-number[data-full-width="true"] { max-width: none; } + .wire-input-number[data-variant="compact"] { width: fit-content; max-width: 100%; } + .wire-input-number[data-disabled="true"] { opacity: 0.6; } + .wire-input-number__label { display: inline-flex; align-items: center; gap: 0.25rem; color: var(--wire-color-text); font-size: 0.875rem; font-weight: 600; line-height: 1.25rem; } + .wire-input-number__required { margin-left: 0.125rem; color: var(--wire-color-danger); } + .wire-input-number__description, .wire-input-number__message { margin: 0; color: var(--wire-color-muted); font-size: 0.75rem; line-height: 1.25rem; } + .wire-input-number__control { display: flex; min-width: 0; min-height: 2.5rem; overflow: hidden; border: 1px solid var(--wire-color-border); border-radius: var(--wire-radius-sm); color: var(--wire-color-text); background: var(--wire-color-surface); box-shadow: var(--wire-shadow-1); transition: border-color var(--wire-motion-base), box-shadow var(--wire-motion-base), background var(--wire-motion-base); } + .wire-input-number__control:focus-within { border-color: var(--input-number-accent); box-shadow: 0 0 0 3px color-mix(in srgb, var(--input-number-accent) 18%, transparent); } + .wire-input-number[data-invalid="true"] .wire-input-number__control { border-color: var(--wire-color-danger); } + .wire-input-number[data-invalid="true"] .wire-input-number__control:focus-within { box-shadow: 0 0 0 3px color-mix(in srgb, var(--wire-color-danger) 18%, transparent); } + .wire-input-number[data-disabled="true"] .wire-input-number__control { cursor: not-allowed; background: var(--wire-color-surface-2); } + .wire-input-number[data-variant="compact"] .wire-input-number__control { border-radius: 999px; } + .wire-input-number[data-size="xs"] .wire-input-number__control { min-height: 2rem; font-size: 0.75rem; } + .wire-input-number[data-size="sm"] .wire-input-number__control { min-height: 2.25rem; font-size: 0.875rem; } + .wire-input-number[data-size="lg"] .wire-input-number__control { min-height: 3rem; font-size: 1rem; } + .wire-input-number[data-size="xl"] .wire-input-number__control { min-height: 3.5rem; font-size: 1.125rem; } + .wire-input-number__content { display: flex; min-width: 0; flex: 1; align-items: center; padding-inline: 0.75rem; } + .wire-input-number[data-size="xs"] .wire-input-number__content { padding-inline: 0.5rem; } + .wire-input-number[data-size="sm"] .wire-input-number__content { padding-inline: 0.625rem; } + .wire-input-number[data-size="lg"] .wire-input-number__content { padding-inline: 1rem; } + .wire-input-number[data-size="xl"] .wire-input-number__content { padding-inline: 1.25rem; } + .wire-input-number[data-variant="labeled"] .wire-input-number__content { flex-direction: column; align-items: stretch; justify-content: center; gap: 0.125rem; } + .wire-input-number[data-variant="seat"] .wire-input-number__content { justify-content: space-between; gap: 0.75rem; } + .wire-input-number__copy { min-width: 0; flex: 1; } + .wire-input-number__inner-label, .wire-input-number__inner-description { display: block; overflow: hidden; color: var(--wire-color-text); font-size: 0.875rem; font-weight: 600; line-height: 1rem; text-overflow: ellipsis; white-space: nowrap; } + .wire-input-number__inner-description { color: var(--wire-color-muted); font-size: 0.75rem; font-weight: 400; } + .wire-input-number[data-variant="labeled"] .wire-input-number__inner-label { color: var(--wire-color-muted); font-size: 0.75rem; font-weight: 500; } + .wire-input-number__field { display: flex; width: 100%; min-width: 0; align-items: center; } + .wire-input-number[data-variant="seat"] .wire-input-number__field { width: auto; flex: none; } + .wire-input-number__prefix, .wire-input-number__suffix { flex: none; color: var(--wire-color-muted); } + .wire-input-number__prefix { padding-right: 0.375rem; } .wire-input-number__suffix { padding-left: 0.375rem; } + .wire-input-number__input { width: 100%; min-width: 0; flex: 1; padding: 0; border: 0; outline: none; color: var(--wire-color-text); background: transparent; font: inherit; font-weight: 500; line-height: 1; appearance: textfield; } + .wire-input-number__input::-webkit-inner-spin-button, .wire-input-number__input::-webkit-outer-spin-button { appearance: none; } + .wire-input-number__input::placeholder { color: var(--wire-color-muted); } + .wire-input-number__input:read-only { cursor: default; } + .wire-input-number__input:disabled { cursor: not-allowed; } + .wire-input-number:is([data-variant="horizontal"], [data-variant="compact"], [data-variant="seat"]) .wire-input-number__input { text-align: center; } + .wire-input-number[data-variant="seat"] .wire-input-number__input { width: 2.5rem; flex: none; } + .wire-input-number__buttons { display: flex; flex: none; border-left: 1px solid var(--wire-color-border); } + .wire-input-number[data-variant="vertical"] .wire-input-number__buttons { flex-direction: column; } + .wire-input-number__button { display: inline-flex; width: 2.5rem; flex: none; align-items: center; justify-content: center; padding: 0; border: 0; color: var(--wire-color-muted); background: transparent; transition: color var(--wire-motion-fast), background var(--wire-motion-fast); } + .wire-input-number[data-size="xs"] .wire-input-number__button { width: 2rem; } .wire-input-number[data-size="sm"] .wire-input-number__button { width: 2.25rem; } .wire-input-number[data-size="lg"] .wire-input-number__button { width: 3rem; } .wire-input-number[data-size="xl"] .wire-input-number__button { width: 3.5rem; } + .wire-input-number__button--start { border-right: 1px solid var(--wire-color-border); } .wire-input-number__button--end { border-left: 1px solid var(--wire-color-border); } + .wire-input-number__button--decrement { border-right: 1px solid var(--wire-color-border); } + .wire-input-number[data-variant="vertical"] .wire-input-number__button--decrement { border-right: 0; border-bottom: 1px solid var(--wire-color-border); } + .wire-input-number__button:hover { color: var(--input-number-accent); background: var(--wire-color-surface-2); } + .wire-input-number__button:focus-visible { z-index: 1; outline: 2px solid var(--input-number-accent); outline-offset: -2px; } + .wire-input-number__button:disabled { cursor: not-allowed; opacity: 0.4; } + .wire-input-number__icon { width: 1rem; height: 1rem; } + .wire-input-number__message--error { display: flex; align-items: center; gap: 0.375rem; color: var(--wire-color-danger); } + .wire-input-number__error-icon { width: 0.875rem; height: 0.875rem; flex: none; } + } } diff --git a/packages/ui/components/List.wrn b/packages/ui/components/List.wrn index 6593807c..87fe43cd 100644 --- a/packages/ui/components/List.wrn +++ b/packages/ui/components/List.wrn @@ -17,89 +17,76 @@ component List {
{#if title || description} -
+
{#if title} -

{title}

+

{title}

{/if} {#if description} -

{description}

+

{description}

{/if}
{/if}
} + + style { + .wire-list { width: 100%; } + .wire-list__header { margin-bottom: 1rem; } + .wire-list__title { color: var(--wire-color-text); font-size: 1.125rem; font-weight: 700; } + .wire-list__description { margin-top: 0.25rem; color: var(--wire-color-text-muted); font-size: 0.875rem; line-height: 1.5rem; } + .wire-list__items { overflow: hidden; } + .wire-list__items:is([data-variant="default"], [data-variant="divided"]) > .wire-list__item + .wire-list__item { border-top: 1px solid var(--wire-color-border); } + .wire-list__items[data-variant="card"] { border: 1px solid var(--wire-color-border); border-radius: calc(var(--wire-radius) * 1.5); background: var(--wire-color-surface-raised); } + .wire-list__items[data-variant="separated"] { display: grid; gap: 0.75rem; } + .wire-list__item { min-width: 0; } + .wire-list__item[data-variant="separated"] { border: 1px solid var(--wire-color-border); border-radius: var(--wire-radius); background: var(--wire-color-surface-raised); } + .wire-list__row { display: flex; min-width: 0; align-items: flex-start; gap: 0.75rem; padding: 0.75rem 1rem; outline: none; transition: background var(--wire-motion-base); } + a.wire-list__row:hover { background: var(--wire-color-surface-soft); } + .wire-list__row:focus-visible { box-shadow: inset 0 0 0 2px var(--wire-color-focus); } + .wire-list__row[data-size="sm"] { padding: 0.625rem 0.75rem; } + .wire-list__row[data-size="lg"] { padding: 1rem 1.25rem; } + .wire-list__leading-icon { display: flex; width: 2.5rem; height: 2.5rem; flex: none; align-items: center; justify-content: center; border-radius: var(--wire-radius); color: var(--wire-color-primary); background: var(--wire-color-primary-soft); } + .wire-list__leading-icon > span { width: 1.25rem; height: 1.25rem; } + .wire-list__image { width: 3rem; height: 3rem; flex: none; border-radius: var(--wire-radius); object-fit: cover; } + .wire-list__body { min-width: 0; flex: 1; } + .wire-list__heading { display: flex; align-items: flex-start; justify-content: space-between; gap: 0.75rem; } + .wire-list__item-title { overflow: hidden; color: var(--wire-color-text); font-weight: 600; text-overflow: ellipsis; white-space: nowrap; } + .wire-list__meta { flex: none; color: var(--wire-color-text-muted); font-size: 0.75rem; } + .wire-list__item-description { display: -webkit-box; margin-top: 0.25rem; overflow: hidden; color: var(--wire-color-text-muted); font-size: 0.875rem; line-height: 1.25rem; -webkit-box-orient: vertical; -webkit-line-clamp: 2; } + .wire-list__badge { display: inline-flex; margin-top: 0.5rem; padding: 0.25rem 0.625rem; border-radius: 999px; color: var(--wire-color-primary); background: var(--wire-color-primary-soft); font-size: 0.75rem; font-weight: 600; } + .wire-list__chevron { width: 1rem; height: 1rem; flex: none; margin-top: 0.25rem; color: var(--wire-color-text-muted); transition: color var(--wire-motion-base), transform var(--wire-motion-base); } + .wire-list__row:hover .wire-list__chevron { color: var(--wire-color-primary); transform: translateX(0.125rem); } + .wire-list__empty { padding: 1.5rem; border: 1px dashed var(--wire-color-border); border-radius: var(--wire-radius); color: var(--wire-color-text-muted); font-size: 0.875rem; text-align: center; } + } } diff --git a/packages/ui/components/Map.wrn b/packages/ui/components/Map.wrn index 57fe068a..1daccf5a 100644 --- a/packages/ui/components/Map.wrn +++ b/packages/ui/components/Map.wrn @@ -21,37 +21,34 @@ component Map {
{#if title || description} -
+
{#if title} -

{title}

+

{title}

{/if} {#if description} -

{description}

+

{description}

{/if}
- - +
{/if}
-
+
@@ -60,7 +57,7 @@ component Map {
} + + style { + .wire-map { overflow: hidden; border: 1px solid var(--wire-color-border); border-radius: calc(var(--wire-radius) * 1.5); background: var(--wire-color-surface-raised); box-shadow: var(--wire-shadow-1); } + .wire-map__header { display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem; padding: 1.25rem; border-bottom: 1px solid var(--wire-color-border); } + .wire-map__title { color: var(--wire-color-text); font-size: 1.125rem; font-weight: 700; } + .wire-map__description { margin-top: 0.25rem; color: var(--wire-color-text-muted); font-size: 0.875rem; line-height: 1.5rem; } + .wire-map__header-icon { display: flex; width: 2.5rem; height: 2.5rem; flex: none; align-items: center; justify-content: center; border-radius: var(--wire-radius); color: var(--wire-color-primary); background: var(--wire-color-primary-soft); } + .wire-map__header-icon > span { width: 1.25rem; height: 1.25rem; } + .wire-map__viewport { position: relative; isolation: isolate; height: 20rem; overflow: hidden; background: var(--wire-color-surface-soft); } + .wire-map__viewport[data-size="sm"] { height: 16rem; } + .wire-map__viewport[data-size="lg"] { height: 28rem; } + .wire-map__grid { position: absolute; inset: 0; opacity: 0.5; pointer-events: none; } + .wire-map__content { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; padding: 1.5rem; } + .wire-map__marker { position: absolute; display: inline-flex; width: 2.5rem; height: 2.5rem; align-items: center; justify-content: center; padding: 0; border: 4px solid var(--wire-color-surface-raised); border-radius: 50%; color: var(--wire-color-on-primary); background: var(--wire-color-primary); box-shadow: var(--wire-shadow-3); transition: transform var(--wire-motion-base) var(--wire-ease-standard); } + .wire-map__marker:hover { transform: scale(1.1); } + .wire-map__controls { position: absolute; right: 1rem; bottom: 1rem; display: flex; flex-direction: column; gap: 0.5rem; } + .wire-map__control { display: inline-flex; width: 2.5rem; height: 2.5rem; align-items: center; justify-content: center; padding: 0; border: 1px solid var(--wire-color-border); border-radius: var(--wire-radius); color: var(--wire-color-text); background: var(--wire-color-surface-raised); box-shadow: var(--wire-shadow-1); transition: background var(--wire-motion-base); } + .wire-map__control:hover { background: var(--wire-color-surface-soft); } + .wire-map__marker:focus-visible, .wire-map__control:focus-visible { outline: 2px solid var(--wire-color-focus); outline-offset: 2px; } + .wire-map__control-icon { width: 1rem; height: 1rem; } + } } diff --git a/packages/ui/components/Marquee.wrn b/packages/ui/components/Marquee.wrn index 1f61a96a..41f237cb 100644 --- a/packages/ui/components/Marquee.wrn +++ b/packages/ui/components/Marquee.wrn @@ -21,46 +21,44 @@ component Marquee {
-
+
{#if title} -
- - {title} +
+ + {title}
{/if}
{#each items as item} {item.label || item.title} {#if item.meta} - {item.meta} + {item.meta} {/if} {:empty} -

{description || "No announcements available."}

+

{description || "No announcements available."}

{/each} {#if items.length > 0} @@ -69,9 +67,9 @@ component Marquee { href='{item.href || "#"}' aria-hidden="true" tabindex="-1" - class="flex shrink-0 items-center gap-3 px-5 py-3 text-sm font-medium text-[var(--wire-color-text)]" + class="wire-marquee__item" > - + {item.label || item.title} {/each} @@ -82,11 +80,11 @@ component Marquee {
@@ -95,9 +93,28 @@ component Marquee { } style { - .wire-marquee-track { + .wire-marquee { overflow: hidden; border-block: 1px solid var(--wire-color-border); background: var(--wire-color-surface-raised); } + .wire-marquee__layout { display: flex; align-items: stretch; } + .wire-marquee__title { position: relative; z-index: 1; display: flex; flex: none; align-items: center; gap: 0.5rem; padding: 0.75rem 1rem; border-right: 1px solid var(--wire-color-border); color: var(--wire-color-on-primary); background: var(--wire-color-primary); font-size: 0.875rem; font-weight: 700; } + .wire-marquee__window { position: relative; min-width: 0; flex: 1; overflow: hidden; } + .wire-marquee__track { + display: flex; width: max-content; min-width: 100%; align-items: center; animation: wire-marquee 32s linear infinite; } + .wire-marquee-paused { animation-play-state: paused; } + .wire-marquee__item { display: flex; flex: none; align-items: center; gap: 0.75rem; padding: 0.75rem 1.25rem; color: var(--wire-color-text); font-size: 0.875rem; font-weight: 500; transition: color var(--wire-motion-base), background var(--wire-motion-base); } + .wire-marquee__item:hover { color: var(--wire-color-primary); background: var(--wire-color-primary-soft); } + .wire-marquee__item:focus-visible, .wire-marquee__toggle:focus-visible { outline: 2px solid var(--wire-color-focus); outline-offset: -2px; } + .wire-marquee__dot { width: 0.5rem; height: 0.5rem; flex: none; border-radius: 50%; background: var(--wire-color-primary); } + .wire-marquee__dot[data-color="danger"] { background: var(--wire-color-danger); } + .wire-marquee__dot[data-color="warning"] { background: var(--wire-color-warning); } + .wire-marquee__dot[data-color="success"] { background: var(--wire-color-success); } + .wire-marquee__meta { color: var(--wire-color-text-muted); font-size: 0.75rem; } + .wire-marquee__empty { padding: 0.75rem 1.25rem; color: var(--wire-color-text-muted); font-size: 0.875rem; } + .wire-marquee__toggle { display: flex; flex: none; align-items: center; justify-content: center; padding-inline: 1rem; border: 0; border-left: 1px solid var(--wire-color-border); color: var(--wire-color-text-muted); background: transparent; transition: color var(--wire-motion-base), background var(--wire-motion-base); } + .wire-marquee__toggle:hover { color: var(--wire-color-text); background: var(--wire-color-surface-soft); } + .wire-marquee__icon { width: 1rem; height: 1rem; } + @media (min-width: 40rem) { .wire-marquee__title { padding-inline: 1.25rem; } } .wire-marquee-paused { animation-play-state: paused; @@ -109,7 +126,7 @@ component Marquee { } @media (prefers-reduced-motion: reduce) { - .wire-marquee-track { + .wire-marquee__track { animation: none; } } diff --git a/packages/ui/components/SearchBox.wrn b/packages/ui/components/SearchBox.wrn index ca935db8..ddea8531 100644 --- a/packages/ui/components/SearchBox.wrn +++ b/packages/ui/components/SearchBox.wrn @@ -26,19 +26,19 @@ component SearchBox {