npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@sv-print/plugin-options-modify

v0.1.4

Published

sv-print option modify plugin

Readme

@sv-print/plugin-options-modify

安装

npm install @sv-print/plugin-options-modify

使用

sv-print 插件引入的两种方式见:sv-print 插件引入的两种方式:https://www.ibujian.cn/svp/plugin/a02.html

import pluginOptionsModify, {
  getSelectToInputModifyHandler,
  InputValueGetHandler,
  InputValueSetHandler,
  getSelectToMultiselectModifyHandler,
  PopupSelectValueGetHandler,
  PopupSelectValueSetHandler,
  PopupSelectDestroyHandler,
} from "@sv-print/plugin-options-modify";
const plugins = [
  pluginOptionsModify({
    list: [
      {
        optionNames: ["fontSize", "lineHeight"],
        modifyHandler: getSelectToInputModifyHandler(
          `<input type="number" value="1" step="1" min="1" class="auto-submit"/>`
        ),
        setValueHandler: (item, value) => {
          console.log(item, value);
          InputValueSetHandler(item, value || 9);
        },
        getValueHandler: InputValueGetHandler,
      },
      // 将默认 <select> 替换为弹窗式单选下拉
      {
        optionNames: ["textAlign", "fontWeight"],
        modifyHandler: getSelectToMultiselectModifyHandler(),
        getValueHandler: PopupSelectValueGetHandler,
        setValueHandler: PopupSelectValueSetHandler,
        destroyHandler: PopupSelectDestroyHandler,
      },
      {
        filter: (key, target) => {
          return key === "fontWeight";
        },
        modifyHandler: (key, target: JQuery<HTMLElement>) => {
          if (target.find(".hiprint-option-item-field select").length > 0) {
            target.find(".hiprint-option-item-field").empty();
            target
              .find(".hiprint-option-item-field")
              .append(
                `<input type="number" value="200" step="100" min="200" class="auto-submit"/>`
              );
          }
          return target;
        },
        setValueHandler: (item, value) => {
          console.log(item, value);
          InputValueSetHandler(item, value || 400);
        },
        getValueHandler: InputValueGetHandler,
      },
    ],
  }),
];

自定义

const fontSize = {
  filter: (key, target) => {
    return key === "fontSize";
  },
  modifyHandler: (key, target: JQuery<HTMLElement>) => {
    if (target.find(".hiprint-option-item-field select").length > 0) {
      target.find(".hiprint-option-item-field").empty();
      let list = [8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 26, 28, 36, 48, 72];
      let fontSizeList = '<option value="" >默认</option>';
      list.forEach(function (e) {
        fontSizeList += '<option value="' + e + '">' + e + "pt</option>";
      });
      target
        .find(".hiprint-option-item-field")
        .append(`<select class="auto-submit">${fontSizeList}</select>`);
    }
    return target;
  },
  setValueHandler: (item, value) => {
    console.log(item, value);
    if (value) {
      item.target.find('option[value="' + value + '"]').length ||
        item.target.find("select").prepend('<option value="' + value + '" >' + value + "</option>");
      item.target.find("select").val(value);
    }
  },
  getValueHandler: (item) => {
    var t = item.target.find("select").val();
    if (t) return parseFloat(t.toString());
  },
};

内置:弹窗式单选/多选下拉

getSelectToMultiselectModifyHandler 可以把默认的 <select> 直接替换成弹窗式下拉,外观与 hiprint 内置的多选下拉一致(trigger + 弹层 + 选项 + 底部按钮),支持单选/多选切换以及搜索、自定义值等扩展能力。

配置项(PopupSelectOptions)

| 字段 | 类型 | 默认值 | 说明 | | --- | --- | --- | --- | | mode | 'single' \| 'multiple' | 'single' | 单选 / 多选 | | showSearch | boolean | false | 顶部显示搜索框,按文字/值模糊匹配过滤选项 | | searchPlaceholder | string | '搜索…' | 搜索框占位文本 | | allowCustom | boolean | false | 顶部允许输入自定义值,按"添加"按钮新增为选项 | | customPlaceholder | string | '输入自定义值' | 自定义输入框占位文本 | | customButtonText | string | '添加' | 自定义添加按钮文本 | | beforeAddCustom | (v: string, key: string) => boolean \| void | - | 自定义值添加前的钩子,第二个参数为当前选项名;返回 false 取消添加 | | showReset | boolean | true | 是否显示"恢复默认"按钮 | | resetText | string | '恢复默认' | 恢复默认按钮文本 | | showConfirm | boolean | mode === 'multiple' | 是否显示"确认"按钮 | | confirmText | string | '确认' | 确认按钮文本 | | autoClose | boolean | mode === 'single' | 单选模式下选中后是否自动关闭弹窗 | | topbarThreshold | number | 5 | 选项数超过该阈值才显示顶部搜索/自定义输入;设 0 表示不限制 | | shouldShowTopbar | (count, key) => boolean | - | 自定义是否显示顶部栏;优先级高于 topbarThreshold |

单选模式(默认)

点击 trigger 弹出选项列表 → 点击任一选项立即选中、关闭弹窗、并触发 auto-submit 自动提交。点击外部 / 焦点离开自动收起。

import pluginOptionsModify, {
  getSelectToMultiselectModifyHandler,
  PopupSelectValueGetHandler,
  PopupSelectValueSetHandler,
  PopupSelectDestroyHandler,
} from "@sv-print/plugin-options-modify";

pluginOptionsModify({
  list: [
    {
      optionNames: ["textAlign", "fontWeight", "paperNumberFormat"],
      modifyHandler: getSelectToMultiselectModifyHandler(),
      getValueHandler: PopupSelectValueGetHandler,
      setValueHandler: PopupSelectValueSetHandler,
      destroyHandler: PopupSelectDestroyHandler,
    },
  ],
});

多选模式

弹层内每一项为 checkbox,点击不立刻关闭,需点击底部"确认"提交;可点击"恢复默认"清空。

{
  optionNames: ["someOptionName"],
  modifyHandler: getSelectToMultiselectModifyHandler({ mode: "multiple" }),
  getValueHandler: PopupSelectValueGetHandler,
  setValueHandler: PopupSelectValueSetHandler,
  destroyHandler: PopupSelectDestroyHandler,
}

PopupSelectValueGetHandler 在 mode: 'multiple' 下返回字符串数组,mode: 'single' 下返回字符串或 undefined。

搜索 + 自定义值

开启顶部搜索与自定义输入后,用户可:

  • 在搜索框输入关键字过滤选项
  • 在自定义输入框里输入新值,按 Enter 或点击"添加"作为新选项加入列表
{
  filter: (key) => key === "fontSize",
  modifyHandler: getSelectToMultiselectModifyHandler({
    mode: "single",
    showSearch: true,
    allowCustom: true,
    // 自定义添加前的校验:只接受数字
    beforeAddCustom: (v, key) => !isNaN(Number(v)) || (alert("请输入数字"), false),
  }),
  setValueHandler: (item, value) => {
    const v = value == null ? "" : String(value);
    item.target.find('input[type="radio"][value="' + v + '"]').length ||
      item.target.find(".hiprint-multiselect-list").append(
        '<div class="hiprint-multiselect-item" data-value="' + v + '" data-text="' + v + '">' +
          '<input type="radio" name="fontSize_single" class="auto-submit" value="' + v + '"><span>' + v + '</span>' +
        '</div>'
      );
    PopupSelectValueSetHandler(item, value);
  },
  getValueHandler: (item) => {
    const v = PopupSelectValueGetHandler(item);
    return v === undefined || v === "" ? undefined : parseFloat(v);
  },
  destroyHandler: PopupSelectDestroyHandler,
}

数值类型选项

PopupSelectValueGetHandler 会根据 setValue 传入值的类型还原返回类型:

  • setValue(9) → 后续 getValue() 返回 9(number)
  • setValue("9") → 后续 getValue() 返回 "9"(string)
  • setValue([1, 2]) → 后续 getValue() 返回 [1, 2](number 数组)
  • setValue(["1", "2"]) → 后续 getValue() 返回 ["1", "2"](string 数组)

类型映射缓存于 target.data("popupSelectTypedMap"),destroy 时自动清理。

旧版本兼容性

如果你的旧代码使用了如下包装,无需再手动 parseFloat / String:

// 旧版本需要手动 parseFloat / String
const NumberPopupSelectGetHandler = (item) => {
  const v = PopupSelectValueGetHandler(item);
  return v === undefined || v === "" ? undefined : parseFloat(v);
};

const NumberPopupSelectSetHandler = (item, value) => {
  PopupSelectValueSetHandler(item, value == null ? "" : String(value));
};

{
  optionNames: ["fontSize"],
  modifyHandler: getSelectToMultiselectModifyHandler(),
  getValueHandler: NumberPopupSelectGetHandler,
  setValueHandler: NumberPopupSelectSetHandler,
  destroyHandler: PopupSelectDestroyHandler,
}

新版本下,可直接使用内置 handler:

{
  optionNames: ["fontSize"],
  modifyHandler: getSelectToMultiselectModifyHandler(),
  getValueHandler: PopupSelectValueGetHandler,
  setValueHandler: PopupSelectValueSetHandler,
  destroyHandler: PopupSelectDestroyHandler,
}

// 在 setValue 之前确保传入原始类型:
setOption("fontSize", 9);          // → getValue() 返回 9
setOption("fontSize", "9pt");      // → getValue() 返回 "9pt"

TIPS

可根据自身项目的组件自定义 modifyHandler,实现对选项的自修改。 同时搭配 setValueHandler 和 getValueHandler,实现对选项的自获取和设置。

比如 vue 项目 可使用 vue 组件实现对选项的自修改。

react 项目,可使用 react 组件实现对选项的自修改。

License

LGPL

开源使用须知

1.请自觉遵守 LGPL 协议,其他用途可联系作者;

2.允许用于个人学习、毕业设计、教学案例、公益事业、商业使用;

3.如果商用必须保留版权信息,请自觉遵守;

4.禁止将本开源的代码和资源进行任何形式任何名义的出售,否则产生的一切任何后果责任由侵权者自负;

5.商用请仔细审查代码和漏洞,不得用于任一国家许可范围之外的商业应用,产生的一切任何后果责任自负;