From d2e24eb089ef6e72093e4f6dde28d55faee25d87 Mon Sep 17 00:00:00 2001 From: Ajay Ghanwat Date: Tue, 25 Aug 2026 17:37:29 +0530 Subject: [PATCH] feat(ui): refine timeline and blockquote layouts --- packages/ui/components/Blockquote.wrn | 20 +++++++++++ packages/ui/components/Timeline.wrn | 35 +++++++++++++++---- packages/ui/test/ui-redesign-contract.test.ts | 15 ++++++++ 3 files changed, 63 insertions(+), 7 deletions(-) diff --git a/packages/ui/components/Blockquote.wrn b/packages/ui/components/Blockquote.wrn index 2edcb0a4..fbfbe3ef 100644 --- a/packages/ui/components/Blockquote.wrn +++ b/packages/ui/components/Blockquote.wrn @@ -12,6 +12,7 @@ component Blockquote { variant: string = "default" quoteMark: boolean = true italic: boolean = true + maxWidth: string = "xl" class: string = "" } @@ -24,6 +25,7 @@ component Blockquote { data-align="{align}" data-variant="{variant}" data-italic="{italic}" + data-max-width="{maxWidth}" >
{#if quoteMark} @@ -73,10 +75,17 @@ component Blockquote { display: grid; gap: 1.25rem; width: 100%; + max-width: var(--wrn-blockquote-max-width, 48rem); color: var(--wrn-color-text); text-align: left; } + .wrn-next--blockquote[data-max-width="sm"] { --wrn-blockquote-max-width: 32rem; } + .wrn-next--blockquote[data-max-width="md"] { --wrn-blockquote-max-width: 40rem; } + .wrn-next--blockquote[data-max-width="lg"] { --wrn-blockquote-max-width: 48rem; } + .wrn-next--blockquote[data-max-width="xl"] { --wrn-blockquote-max-width: 64rem; } + .wrn-next--blockquote[data-max-width="full"] { --wrn-blockquote-max-width: 100%; } + .wrn-next--blockquote[data-size="xs"] { --wrn-blockquote-font-size: 0.875rem; --wrn-blockquote-mark-size: 3rem; @@ -189,8 +198,19 @@ component Blockquote { .wrn-next--blockquote[data-align="center"] { text-align: center; + margin-inline: auto; } + .wrn-next--blockquote:is([data-variant="contained"], [data-variant="spotlight"], [data-variant="card"]) { + padding: clamp(1.5rem, 4vw, 3rem); + border: 1px solid color-mix(in srgb, var(--wrn-blockquote-color) 24%, var(--wrn-color-border)); + border-radius: calc(var(--wrn-radius) * 2); + background: linear-gradient(145deg, color-mix(in srgb, var(--wrn-blockquote-color) 8%, var(--wrn-color-surface-raised)), var(--wrn-color-surface-raised)); + box-shadow: var(--wrn-shadow-1); + } + + .wrn-next--blockquote[data-variant="spotlight"] > blockquote { padding-top: calc(var(--wrn-blockquote-mark-size) * 0.55); } + .wrn-next--blockquote[data-align="right"], .wrn-next--blockquote[data-align="end"] { text-align: right; diff --git a/packages/ui/components/Timeline.wrn b/packages/ui/components/Timeline.wrn index 85b22c0a..18020ce7 100644 --- a/packages/ui/components/Timeline.wrn +++ b/packages/ui/components/Timeline.wrn @@ -10,6 +10,7 @@ component Timeline { description: string = "" items: unknown[] = [] variant: string = "default" + numbered: boolean = false class: string = "" } @@ -18,6 +19,9 @@ component Timeline { data-ui-component="Timeline" aria-label='{title}' class='wrn-timeline {class}' + data-size='{size}' + data-color='{color}' + data-variant='{variant}' > {#if title || description}
@@ -34,13 +38,18 @@ component Timeline { {#each items as item, index}
  • - + {#if numbered} + + {:else} + + {/if}
    { expect(source).toContain('.wrn-hero[data-full-bleed="true"]'); }); + test("Timeline supports numbered data items without styling every row as interactive", async () => { + const source = await readFile(join(componentsDir, "Timeline.wrn"), "utf8"); + expect(source).toContain("numbered: boolean = false"); + expect(source).toContain("data-interactive"); + expect(source).toContain('data-interactive="true"'); + expect(source).toContain('.wrn-timeline__item[data-interactive="true"] { cursor: pointer; }'); + }); + + test("Blockquote provides constrained contained presentation", async () => { + const source = await readFile(join(componentsDir, "Blockquote.wrn"), "utf8"); + expect(source).toContain('maxWidth: string = "xl"'); + expect(source).toContain('data-variant="spotlight"'); + expect(source).toContain('data-max-width="full"'); + }); + test("contains every replacement and new component", async () => { const files = new Set(await readdir(componentsDir));