Skip to content

原生 JS

@selkit/dom 以純 DOM 渲染 controller,不需要任何框架。

掛載

createSelkitDom(target, config) 接受元素或選擇器字串,回傳一個 instance:

js
import { createSelkitDom } from '@selkit/dom'

const instance = createSelkitDom('#fruit', {
  options: [
    { value: 'apple', label: 'Apple' },
    { value: 'banana', label: 'Banana' },
  ],
  placeholder: 'Pick a fruit…',
  clearable: true,
})

回傳的 instance 為:

ts
interface SelkitDomInstance {
  controller: SelkitController // headless 大腦
  element: HTMLElement // 渲染出的根節點
  destroy(): void // 解除綁定並移除
}

所有行為相關操作都透過 instance.controller — 監聽事件、以程式選取等:

js
instance.controller.on('change', ({ value }) => console.log(value))
instance.controller.select('banana')

簡寫別名

為了貼近 select2 / Tom Select 的手感,提供兩個別名:

js
import { sk, Selkit } from '@selkit/dom'

sk('#fruit', { options }) // createSelkitDom 的函式別名
const s = new Selkit('#fruit', { options }) // class 風格別名

增強既有的 <select>

若掛載目標是 <select>,Selkit 會讀取它的 <option>valuemultiplename,隱藏原生元素並保持同步。這是漸進式增強 — 表單仍透過原生控制項送出,且 destroy() 會還原它。

html
<select id="fruit" name="fruit">
  <option value="apple">Apple</option>
  <option value="banana" selected>Banana</option>
</select>
js
createSelkitDom('#fruit') // 選項來自 <select>

<optgroup> 會自動成為 Selkit 分組。

僅限 DOM 的設定

SelkitDomConfigSelkitConfig 之上多了幾個渲染期選項:

選項型別說明
classPrefixstringBEM class 前綴,預設 "selkit"
namestring維護 hidden input 以供傳統表單送出。見表單
virtualScrollboolean只渲染可視切片。見虛擬捲動
itemHeightnumber虛擬捲動的固定列高,預設 36
dropdownParentHTMLElement | string把下拉浮層 portal 到其他容器(如 document.body),逃離 overflow:hidden 容器或 modal 等會裁切的祖先。
templateOption(option, meta) => string | Node自訂下拉選項內容。meta{ index, active, selected }
templateSelection(option, meta) => string | Node自訂已選 tag/單值內容。meta{ index, multiple }

兩者回傳字串皆設為 textContent(安全,不注入 HTML);要包含 icon 等標記請回傳 Node

js
createSelkitDom(el, {
  options,
  multiple: true,
  // 下拉選項
  templateOption: (option, { selected }) => {
    const span = document.createElement('span')
    span.textContent = `${selected ? '✓ ' : ''}${option.label}`
    return span
  },
  // 已選 tag/單值
  templateSelection: (option) => {
    const span = document.createElement('span')
    span.textContent = `🔖 ${option.label}`
    return span
  },
})

清理

移除元件時務必呼叫 destroy() 以解除事件綁定,並在增強模式下還原原生 <select>

js
instance.destroy()

依 MIT 授權釋出。