{"version":3,"file":"file-upload.cjs","sources":["../../../packages/components/src/file-upload.ts"],"sourcesContent":["import { LitElement, css, html, nothing } from 'lit'\nimport { property, query, state } from 'lit/decorators.js'\nimport { classMap } from 'lit/directives/class-map.js'\nimport { repeat } from 'lit/directives/repeat.js'\nimport { styleMap } from 'lit/directives/style-map.js'\nimport { safeCustomElement } from './base/define'\n\ntype UploadItem = {\n  name: string\n  url?: string\n  file?: File\n}\n\ntype UploadSuccessDetail = {\n  response: any\n  file: File\n  files: File[]\n  items: UploadItem[]\n}\n\nfunction normalizeExt(value: string) {\n  return value.trim().replace(/^\\./, '').split('/').pop()?.toLowerCase() ?? ''\n}\n\nfunction parseJsonResponse(responseText: string) {\n  try {\n    return JSON.parse(responseText)\n  }\n  catch {\n    return responseText\n  }\n}\n\n@safeCustomElement('qxs-file-upload')\nexport class QxsFileUpload extends LitElement {\n  static styles = css`\n    :host {\n      display: block;\n      width: 100%;\n      --upload-width: 160px;\n      --upload-height: 90px;\n      color: #0f172a;\n      font-size: 14px;\n    }\n\n    .upload {\n      display: grid;\n      gap: 12px;\n      justify-items: start;\n    }\n\n    .control {\n      display: flex;\n      flex-direction: column;\n      align-items: center;\n      justify-content: center;\n      box-sizing: border-box;\n      width: var(--upload-width);\n      min-height: var(--upload-height);\n      padding: 10px 12px;\n      cursor: pointer;\n      background: #f8fafc;\n      border: 1px dashed #cbd5e1;\n      border-radius: 16px;\n      transition: border-color 0.2s ease, background-color 0.2s ease;\n    }\n\n    .control.is-dragging {\n      background: #eef4ff;\n      border-color: #3d61e3;\n    }\n\n    .icon {\n      width: 28px;\n      height: 28px;\n      margin-bottom: 8px;\n      color: #3d61e3;\n    }\n\n    .text {\n      font-size: 12px;\n      line-height: 1.4;\n      color: #475569;\n      text-align: center;\n    }\n\n    .text em {\n      font-style: normal;\n      color: #3d61e3;\n    }\n\n    .list {\n      display: grid;\n      gap: 8px;\n    }\n\n    .item {\n      display: flex;\n      align-items: center;\n      justify-content: space-between;\n      gap: 12px;\n      padding: 10px 12px;\n      background: #fff;\n      border: 1px solid #e2e8f0;\n      border-radius: 12px;\n    }\n\n    .item-name {\n      flex: 1;\n      min-width: 0;\n      overflow: hidden;\n      text-overflow: ellipsis;\n      white-space: nowrap;\n    }\n\n    .remove {\n      padding: 0;\n      color: #94a3b8;\n      cursor: pointer;\n      background: transparent;\n      border: 0;\n    }\n\n    .status {\n      padding: 10px 12px;\n      line-height: 1.6;\n      border-radius: 12px;\n    }\n\n    .status.info {\n      color: #1d4ed8;\n      background: #eff6ff;\n    }\n\n    .status.warning {\n      color: #9a3412;\n      background: #fff7ed;\n    }\n\n    .status.error {\n      color: #b91c1c;\n      background: #fef2f2;\n    }\n  `\n\n  @property({ type: String }) action = ''\n  @property({ attribute: false }) headers?: Record<string, string>\n  @property({ attribute: false }) data?: Record<string, string | Blob>\n  @property({ type: String }) name = 'file'\n  @property({ type: Number }) size = 20\n  @property({ type: Number }) width = 160\n  @property({ type: Number }) height = 90\n  @property({ type: Number, attribute: 'max' }) max = 3\n  @property({ type: String }) accept = 'zip,rar'\n  @property({ attribute: false }) files: UploadItem[] = []\n  @property({ type: Boolean }) notip = false\n  @property({ attribute: false }) ext: string[] = []\n\n  @state() private _internalFiles: UploadItem[] = []\n  @state() private _isDragging = false\n  @state() private _message = ''\n  @state() private _messageType: 'info' | 'warning' | 'error' = 'info'\n\n  @query('input[type=\"file\"]') private _input?: HTMLInputElement\n  private _pendingUploadCount = 0\n\n  connectedCallback() {\n    super.connectedCallback()\n    this._syncFilesFromProps()\n  }\n\n  updated(changed: Map<string, unknown>) {\n    if (changed.has('files')) {\n      this._syncFilesFromProps()\n    }\n  }\n\n  private get _exts() {\n    const source = this.ext.length ? this.ext : this.accept.split(',')\n    return source.map(normalizeExt).filter(Boolean)\n  }\n\n  private _syncFilesFromProps() {\n    this._internalFiles = [...this.files]\n  }\n\n  private _setMessage(type: 'info' | 'warning' | 'error', message: string) {\n    this._messageType = type\n    this._message = message\n  }\n\n  private _clearMessage() {\n    this._message = ''\n    this._messageType = 'info'\n  }\n\n  private _validateFile(file: File) {\n    const fileExt = normalizeExt(file.name.split('.').pop() ?? '')\n    const isTypeOk = this._exts.includes(fileExt)\n    const isSizeOk = file.size / 1024 / 1024 < this.size\n\n    if (!isTypeOk) {\n      this._setMessage('error', `上传文件只支持 ${this._exts.join(' / ')} 格式！`)\n      return false\n    }\n\n    if (!isSizeOk) {\n      this._setMessage('error', `上传文件大小不能超过 ${this.size}MB！`)\n      return false\n    }\n\n    if (this._internalFiles.length + this._pendingUploadCount >= this.max) {\n      this._setMessage('warning', '文件上传超过限制')\n      return false\n    }\n\n    return true\n  }\n\n  private _dispatchUploadSuccess(detail: UploadSuccessDetail) {\n    this.dispatchEvent(new CustomEvent('upload-success', {\n      detail,\n      bubbles: true,\n      composed: true,\n    }))\n    this.dispatchEvent(new CustomEvent('on-success', {\n      detail,\n      bubbles: true,\n      composed: true,\n    }))\n\n    if (typeof (this as any).onSuccess === 'function') {\n      ;(this as any).onSuccess(detail.response, detail.file, detail.files)\n    }\n  }\n\n  private _dispatchFilesChange() {\n    this.dispatchEvent(new CustomEvent('files-change', {\n      detail: { items: this._internalFiles.slice() },\n      bubbles: true,\n      composed: true,\n    }))\n  }\n\n  private _handleSelectedFiles(files: File[]) {\n    this._clearMessage()\n    files.forEach((file) => {\n      if (this._validateFile(file)) {\n        this._uploadFile(file)\n      }\n    })\n  }\n\n  private _handleDrop(event: DragEvent) {\n    event.preventDefault()\n    this._isDragging = false\n    const files = event.dataTransfer?.files\n    if (!files) {\n      return\n    }\n    this._handleSelectedFiles(Array.from(files))\n  }\n\n  private _handleDragOver(event: DragEvent) {\n    event.preventDefault()\n    this._isDragging = true\n  }\n\n  private _handleDragLeave() {\n    this._isDragging = false\n  }\n\n  private _handleInputChange(event: Event) {\n    const target = event.target as HTMLInputElement\n    const files = target.files\n    if (!files) {\n      return\n    }\n\n    this._handleSelectedFiles(Array.from(files))\n    target.value = ''\n  }\n\n  private _uploadFile(file: File) {\n    if (!this.action) {\n      this._setMessage('warning', '请先配置上传地址 action')\n      return\n    }\n\n    const formData = new FormData()\n    formData.append(this.name, file)\n\n    if (this.data) {\n      Object.entries(this.data).forEach(([key, value]) => {\n        formData.append(key, value)\n      })\n    }\n\n    const xhr = new XMLHttpRequest()\n    xhr.open('POST', this.action)\n    this._pendingUploadCount += 1\n\n    if (this.headers) {\n      Object.entries(this.headers).forEach(([key, value]) => {\n        xhr.setRequestHeader(key, value)\n      })\n    }\n\n    xhr.onload = () => {\n      this._pendingUploadCount = Math.max(0, this._pendingUploadCount - 1)\n      if (xhr.status >= 200 && xhr.status < 300) {\n        const response = parseJsonResponse(xhr.responseText)\n        const nextItem: UploadItem = { name: file.name, file }\n        this._internalFiles = [...this._internalFiles, nextItem]\n        this._setMessage('info', `${file.name} 上传成功`)\n        this._dispatchFilesChange()\n        this._dispatchUploadSuccess({\n          response,\n          file,\n          files: this._internalFiles.map(item => item.file).filter(Boolean) as File[],\n          items: this._internalFiles.slice(),\n        })\n      }\n      else {\n        this._setMessage('error', '上传失败')\n      }\n    }\n\n    xhr.onerror = () => {\n      this._pendingUploadCount = Math.max(0, this._pendingUploadCount - 1)\n      this._setMessage('error', '上传失败')\n    }\n\n    xhr.send(formData)\n  }\n\n  private _handleRemove(index: number) {\n    this._internalFiles = this._internalFiles.filter((_, fileIndex) => fileIndex !== index)\n    this._dispatchFilesChange()\n  }\n\n  render() {\n    const controlClasses = {\n      control: true,\n      'is-dragging': this._isDragging,\n    }\n    const controlStyle = {\n      '--upload-width': `${this.width}px`,\n      '--upload-height': `${this.height}px`,\n    }\n\n    return html`\n      <div class=\"upload\" part=\"container\">\n        <div\n          class=${classMap(controlClasses)}\n          part=\"control\"\n          style=${styleMap(controlStyle)}\n          @click=${() => this._input?.click()}\n          @drop=${this._handleDrop}\n          @dragover=${this._handleDragOver}\n          @dragleave=${this._handleDragLeave}\n        >\n          <input\n            type=\"file\"\n            accept=${this.accept}\n            ?multiple=${this.max > 1}\n            style=\"display:none\"\n            @change=${this._handleInputChange}\n          >\n          <div class=\"icon\" part=\"icon\" aria-hidden=\"true\">\n            <svg viewBox=\"0 0 24 24\" fill=\"currentColor\" width=\"100%\" height=\"100%\">\n              <path d=\"M19.35 10.04C18.67 6.59 15.64 4 12 4 9.11 4 6.6 5.64 5.35 8.04 2.34 8.36 0 10.91 0 14c0 3.31 2.69 6 6 6h13c2.76 0 5-2.24 5-5 0-2.64-2.05-4.78-4.65-4.96zM14 13v4h-4v-4H7l5-5 5 5h-3z\"/>\n            </svg>\n          </div>\n          <div class=\"text\" part=\"text\">将文件拖到此处，或<em>点击上传</em></div>\n        </div>\n\n        ${this._internalFiles.length\n          ? html`\n              <div class=\"list\" part=\"list\">\n                ${repeat(this._internalFiles, item => `${item.name}-${item.url ?? ''}`, (item, index) => html`\n                  <div class=\"item\" part=\"item\">\n                    <span class=\"item-name\">${item.name}</span>\n                    <button\n                      class=\"remove\"\n                      part=\"remove\"\n                      type=\"button\"\n                      @click=${(event: Event) => {\n                        event.stopPropagation()\n                        this._handleRemove(index)\n                      }}\n                    >\n                      ×\n                    </button>\n                  </div>\n                `)}\n              </div>\n            `\n          : nothing}\n\n        ${this._message\n          ? html`<div class=\"status ${this._messageType}\" part=\"status\">${this._message}</div>`\n          : nothing}\n\n        ${this.notip\n          ? nothing\n          : html`\n              <div class=\"status info\" part=\"tip\">\n                <slot name=\"tip\">\n                  上传文件支持 ${this._exts.join(' / ')} 格式，单个文件大小不超过 ${this.size}MB，且文件数量不超过 ${this.max} 个\n                </slot>\n              </div>\n            `}\n      </div>\n    `\n  }\n}\n\ndeclare global {\n  interface HTMLElementTagNameMap {\n    'qxs-file-upload': QxsFileUpload\n  }\n}\n"],"names":["normalizeExt","value","parseJsonResponse","responseText","QxsFileUpload","LitElement","changed","type","message","file","fileExt","isTypeOk","isSizeOk","detail","files","event","target","formData","key","xhr","response","nextItem","item","index","_","fileIndex","controlClasses","controlStyle","html","classMap","styleMap","repeat","nothing","css","__decorateClass","property","state","query","safeCustomElement"],"mappings":"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"}