Pattern

Reusable solution to a recurring interaction or layout problem.

  1. User clicks Delete
  2. A dialog asks to confirm
  3. Action proceeds only after Yes
  4. Summary shown by default
  5. "Show more" reveals detail
  6. Advanced options stay hidden until asked for

A reusable solution — the confirmation pattern, applied wherever it fits

html

<div class="uif-pat-stage" data-kind="confirmation">
  <ol class="uif-pat-steps uif-pat-steps--numbered">
    <li class="uif-pat-step uif-pat-step--confirmation">User clicks Delete</li>
    <li class="uif-pat-step uif-pat-step--confirmation">A dialog asks to confirm</li>
    <li class="uif-pat-step uif-pat-step--confirmation">Action proceeds only after Yes</li>
    <li class="uif-pat-step uif-pat-step--progressive-disclosure">Summary shown by default</li>
    <li class="uif-pat-step uif-pat-step--progressive-disclosure">"Show more" reveals detail</li>
    <li class="uif-pat-step uif-pat-step--progressive-disclosure">Advanced options stay hidden until asked for</li>
  </ol>
  <p class="uif-pat-caption">A reusable solution &mdash; the confirmation pattern, applied wherever it fits</p>
</div>
<style>
.uif-pat-stage { width: 100%; max-width: 320px; padding: 16px; background: #FAF7F2; border: 1px solid #24143022; border-radius: 12px; font: 13px system-ui, sans-serif; color: #241430; }
.uif-pat-steps { margin: 0; padding-left: 20px; }
.uif-pat-steps:not(.uif-pat-steps--numbered) { list-style: none; padding-left: 0; }
.uif-pat-step { display: none; padding: 6px 0; border-bottom: 1px dashed #24143022; }
[data-kind="confirmation"] .uif-pat-step--confirmation,
[data-kind="progressive-disclosure"] .uif-pat-step--progressive-disclosure { display: list-item; }
.uif-pat-steps--numbered .uif-pat-step::marker { color: #241430; font-weight: 700; }
.uif-pat-caption { margin: 12px 0 0; font-size: 12px; color: #241430aa; }
</style>

tailwind

<div class="w-full max-w-[320px] p-4 bg-[#FAF7F2] border border-[#24143022] rounded-xl font-sans text-sm text-[#241430]" data-kind="confirmation">
  <ol class="tw-pat-steps tw-pat-numbered m-0 pl-5">
    <li class="tw-pat-confirmation hidden py-1.5 border-b border-dashed border-[#24143022]">User clicks Delete</li>
    <li class="tw-pat-confirmation hidden py-1.5 border-b border-dashed border-[#24143022]">A dialog asks to confirm</li>
    <li class="tw-pat-confirmation hidden py-1.5 border-b border-dashed border-[#24143022]">Action proceeds only after Yes</li>
    <li class="tw-pat-progressive-disclosure hidden py-1.5 border-b border-dashed border-[#24143022]">Summary shown by default</li>
    <li class="tw-pat-progressive-disclosure hidden py-1.5 border-b border-dashed border-[#24143022]">"Show more" reveals detail</li>
    <li class="tw-pat-progressive-disclosure hidden py-1.5 border-b border-dashed border-[#24143022]">Advanced options stay hidden until asked for</li>
  </ol>
  <p class="mt-3 text-xs text-[#241430]/70">A reusable solution &mdash; the confirmation pattern, applied wherever it fits</p>
</div>
<style>
.tw-pat-steps:not(.tw-pat-numbered) { list-style: none; padding-left: 0; }
[data-kind="confirmation"] .tw-pat-confirmation,
[data-kind="progressive-disclosure"] .tw-pat-progressive-disclosure { display: list-item; }
.tw-pat-numbered li::marker { color: #241430; font-weight: 700; }
</style>

react

export function Pattern({
  kind = "confirmation",
  accent = "#241430",
  showNumbers = true,
}) {
  const steps = {
    confirmation: ["User clicks Delete", "A dialog asks to confirm", "Action proceeds only after Yes"],
    "progressive-disclosure": ["Summary shown by default", '"Show more" reveals detail', "Advanced options stay hidden until asked for"],
  }[kind];
  const Tag = showNumbers ? "ol" : "ul";
  return (
    <div style={{ width: "100%", maxWidth: 320, padding: 16, background: "#FAF7F2", border: "1px solid #24143022", borderRadius: 12, fontFamily: "system-ui, sans-serif", fontSize: 13, color: "#241430" }}>
      <Tag style={{ margin: 0, paddingLeft: showNumbers ? 20 : 0, listStyle: showNumbers ? "decimal" : "none" }}>
        {steps.map((s) => (
          <li key={s} style={{ padding: "6px 0", borderBottom: "1px dashed #24143022" }}>{s}</li>
        ))}
      </Tag>
      <p style={{ margin: "12px 0 0", fontSize: 12, color: "#241430aa" }}>A reusable solution &mdash; the {kind} pattern, applied wherever it fits</p>
    </div>
  );
}