8pt

File Dropzone

文件拖放区•输入
介绍

拖入或点击选择文件,拖拽悬停时边框高亮放大;每个文件有独立进度条,完成后打勾。附示例文件按钮。

纯 HTML、CSS 与少量原生 JS,没有框架依赖。复制提示词交给 Claude Code、Cursor、Trae 或 Codex,模型会把 File Dropzone 加进你的项目并换成你的配色。

适用场景

搜索框、AI 对话输入框、表单字段、文件上传和验证码等用户输入的地方。

安装

订阅 Builder 后,用 8pt CLI 装进项目,或在已接入 8pt MCP 的编辑器里直接调用。

$ npm i -g @8pt-dev/cli && 8pt add file-dropzone
mcp › 使用 8pt MCP 调用 get_component("file-dropzone")

代码

File Dropzone 的源码,动效只用 transform 与 opacity,并尊重减少动态效果设置。

<div class="x-drop">
  <label class="x-drop__zone">
    <input type="file" multiple hidden>
    <span class="x-drop__ic" aria-hidden="true"><svg viewBox="0 0 24 24" width="15" height="15" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><path d="M12 19V6M6 11l6-6 6 6"/></svg></span>
    <b>拖入文件,或点击选择</b>
    <small>PNG、SVG、PDF,单个不超过 10MB</small>
  </label>
  <ul class="x-drop__list"></ul>
  <button type="button" class="x-drop__demo">添加示例文件</button>
</div>
.x-drop{display:grid;gap:8px;width:min(320px,100%);color:var(--d-fg,#fff)}
.x-drop__zone{display:grid;justify-items:center;gap:4px;padding:16px 12px;border-radius:14px;border:1.5px dashed var(--d-line,rgba(255,255,255,.2));background:var(--d-card,#14141c);text-align:center;cursor:pointer;transition:transform .25s cubic-bezier(.2,.8,.2,1),border-color .2s,background-color .2s}
.x-drop__zone:hover{border-color:color-mix(in srgb,var(--d-accent,#4D74FF) 60%,transparent)}
.x-drop__zone.over{transform:scale(1.02);border-color:var(--d-accent,#4D74FF);background:color-mix(in srgb,var(--d-accent,#4D74FF) 10%,var(--d-card,#14141c))}
.x-drop__ic{display:grid;place-items:center;width:30px;height:30px;border-radius:50%;background:color-mix(in srgb,var(--d-accent,#4D74FF) 18%,transparent);color:var(--d-accent,#4D74FF);font:700 15px/1 var(--d-font,system-ui,sans-serif);transition:transform .3s}
.x-drop__zone.over .x-drop__ic{transform:translateY(-3px)}
.x-drop__zone b{font:600 13px/1.3 var(--d-font,system-ui,sans-serif)}
.x-drop__zone small{font:11px/1.3 var(--d-font,system-ui,sans-serif);color:var(--d-muted,#9b9ba8)}
.x-drop__list{display:grid;gap:6px;margin:0;padding:0;list-style:none}
.x-drop__list li{display:grid;grid-template-columns:1fr auto;gap:4px 10px;padding:8px 10px;border-radius:10px;border:1px solid var(--d-line,rgba(255,255,255,.1));background:var(--d-card,#14141c);font:12px/1.2 var(--d-font,system-ui,sans-serif);animation:x-drop-in .3s cubic-bezier(.2,.8,.2,1)}
@keyframes x-drop-in{from{opacity:0;transform:translateY(6px)}}
.x-drop__list li span{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}
…
const init = (root) => {
  const zone = root.querySelector('.x-drop__zone'), input = zone.querySelector('input'), list = root.querySelector('.x-drop__list');
  const timers = new Set();
  const add = (name, size) => {
    if (list.children.length >= 3) list.firstElementChild.remove();
    const li = document.createElement('li'); li.innerHTML = `<span></span><em>0%</em><div class="x-drop__bar"><i></i></div>`;
    li.querySelector('span').textContent = name; list.appendChild(li);
    let p = 0; const bar = li.querySelector('i'), em = li.querySelector('em');
    const tick = () => { p = Math.min(100, p + 6 + Math.random() * 16); bar.style.transform = `scaleX(${p / 100})`; em.textContent = Math.round(p) + '%';
      if (p < 100) { const id = setTimeout(tick, 160); timers.add(id); } else { li.classList.add('ok'); em.textContent = '✓ ' + size; } };
    tick();
  };
…
订阅 Builder 查看完整源码。查看价格

更多输入组件

查看全部

AI Prompt Composer

AI Prompt Input

Glowing Search Bar

Command Palette

OTP Input

Date Range Pill

更多组件

查看全部

Film Strip Carousel

Auto Tab Showcase

Media Bento Grid

Agent Chat Window

Model Pill Marquee

Director Art Cards

Mac File Window

Disk Cleanup Panel

继续探索