@openpicker/sdk
v0.2.5
Published
Open-source CSS element picker — SDK for invoking the openpicker browser extension.
Maintainers
Readme
@openpicker/sdk
SDK for invoking the OpenPicker browser extension to pick a CSS selector on any page. Website: openpicker.dev · Docs: docs.openpicker.dev · Live demo: demo.openpicker.dev
npm install @openpicker/sdkimport { createOpenpicker, OpenpickerError } from "@openpicker/sdk"
const op = createOpenpicker({ appName: "My App" })
if (await op.isAvailable()) {
// `url` is required: the extension opens it in a tab, the user picks there,
// and the selector is routed back here.
const { selector, matchCount, element } = await op.pick({
url: "https://app.example.com",
screenshot: "element", // optional: "none" | "element" | "viewport"
})
console.log(selector, matchCount, element)
} else {
// Prompt the user to install the OpenPicker extension.
}Constrain the selector
Pass per-dimension rules into a pick (id / class / attribute / tag, each with an allow and an
ignore regex), lock the picker UI so the user can't loosen them, and/or require a unique match:
const { selector } = await op.pick({
url: "https://app.example.com",
selector: {
attr: { allow: "^data-step$" }, // only the data-step attribute
id: { enabled: false },
class: { enabled: false },
tag: { enabled: false },
},
lockSelectorSettings: true, // rule settings shown read-only
lockSelectorEdit: true, // selector field read-only
requireUniqueMatch: true, // confirm only when exactly one element matches
})SDK rules compose with the user's own saved rules — each layer can only narrow. Since the user can
still hand-edit the selector unless you set lockSelectorEdit, validate the result against your
config with matchesSelectorConfig:
import { matchesSelectorConfig } from "@openpicker/sdk"
const config = { attr: { allow: "^data-step$" }, tag: { enabled: false } }
const { selector } = await op.pick({ url, selector: config })
if (!matchesSelectorConfig(selector, config)) {
// doesn't meet your requirement — ask the user to pick again
}The picker won't return a selector that violates the active rules — it offers a conforming one or none. See Configuring selectors for the full model.
Restrict which element can be picked
selector shapes how a selector is built; mustMatch controls which element can be picked.
Pass a CSS selector and only matching elements are selectable (hovering a descendant snaps to the
nearest matching ancestor; non-matching elements aren't selectable):
op.pick({ url, mustMatch: "input, textarea, select, [contenteditable]" })The two axes are independent and compose — e.g. "only inputs, identified by id":
op.pick({
url,
mustMatch: "input, textarea, select, [contenteditable]",
selector: { class: { enabled: false }, attr: { enabled: false }, tag: { enabled: false } },
})An invalid mustMatch rejects the pick with invalid_params.
More
See the protocol spec for the wire format, and the main README for the full API.
