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

taj-consumer-ui

v0.1.9

Published

Shared uni-app consumer UI components for TAJ applications

Readme

taj-consumer-ui

用于 TAJ uni-app 项目的公共源码组件包。

安装

pnpm add taj-consumer-ui

使用方需要安装兼容版本的 vue@wot-ui/ui

使用

<script setup lang="ts">
import TajBusinessStatus from 'taj-consumer-ui/business-status'
</script>

<template>
  <TajBusinessStatus
    business-hours='{"days":[1,2,3,4,5],"end":"23:00","mode":"CUSTOM","start":"10:00"}'
    business-hours-label="营业时间"
  />
</template>

组件目录遵循 Wot UI 的命名方式:

components/
├── taj-business-status/
│   ├── index.scss
│   ├── taj-business-status.vue
│   └── types.ts
├── taj-goods-item/
│   ├── index.scss
│   ├── taj-goods-item.vue
│   └── types.ts
├── taj-order-item/
│   ├── index.scss
│   ├── taj-order-item.vue
│   └── types.ts
├── taj-store-appointment-popup/
│   ├── index.scss
│   ├── taj-store-appointment-popup.vue
│   └── types.ts
└── taj-store-info/
    ├── index.scss
    ├── taj-store-info.vue
    └── types.ts

也可以按组件路径引入:

import TajBusinessStatus from 'taj-consumer-ui/components/taj-business-status/taj-business-status.vue'

营业时间工具也可以单独引用:

import { isWithinBusinessHours } from 'taj-consumer-ui'

商品骨架

TajGoodsItem 只负责商品行布局,不接收业务数据。内容由 covertitletagssubtitlesoldpriceorigin-pricediscountaction 插槽提供。标题前默认展示“超值团”标签;可通过 show-deal-tagdeal-tag-text 配置,或使用 deal-tag 插槽完全覆盖。

<script setup lang="ts">
import TajGoodsItem from 'taj-consumer-ui/goods-item'
</script>

<template>
  <TajGoodsItem custom-class="package-item" @click="handleBuy">
    <template #cover>
      <image class="package-cover" :src="goods.cover" mode="aspectFill" />
    </template>
    <template #title>
      {{ goods.title }}
    </template>
    <template #tags>
      <wd-tag v-for="tag in goods.tags" :key="tag.text" size="small">
        {{ tag.text }}
      </wd-tag>
    </template>
    <template #subtitle>
      {{ goods.subtitle }}
    </template>
    <template #sold>
      {{ goods.soldText }}
    </template>
    <template #price>
      ¥{{ goods.price }}
    </template>
    <template #origin-price>
      ¥{{ goods.originPrice }}
    </template>
    <template #discount>
      {{ goods.discount }}
    </template>
    <template #action>
      抢购
    </template>
  </TajGoodsItem>
</template>

<style>
.package-cover {
  width: 100%;
  height: 100%;
}

.package-item {
  --xyj-goods-item-title-color: #202124;
  --xyj-goods-item-price-color: #e85d04;
  --xyj-goods-item-action-bg: #e85d04;
  --xyj-goods-item-action-color: #ffffff;
}
</style>

所有视觉变量均提供默认值,可按页面覆盖。常用变量包括:

  • --xyj-goods-item-title-color
  • --xyj-goods-item-deal-tag-bg
  • --xyj-goods-item-deal-tag-icon-color
  • --xyj-goods-item-deal-tag-text-color
  • --xyj-goods-item-subtitle-color
  • --xyj-goods-item-sold-color
  • --xyj-goods-item-price-color
  • --xyj-goods-item-origin-price-color
  • --xyj-goods-item-discount-color
  • --xyj-goods-item-action-bg
  • --xyj-goods-item-action-color

默认促销标签使用 Carbon 图标。使用方需安装 @iconify-json/carbon,在 UnoCSS 中加载 Carbon collection,并扫描组件包源码:

export default defineConfig({
  content: {
    filesystem: [
      'node_modules/taj-consumer-ui/**/*.{vue,ts}',
    ],
  },
  presets: [
    presetIcons({
      collections: {
        carbon: () => import('@iconify-json/carbon/icons.json').then(module => module.default),
      },
    }),
  ],
})

门店信息卡片

TajStoreInfo 展示门店名称、营业时间、地址、快捷操作和停车指引。组件只回传交互事件,地图、电话、路由等业务逻辑由使用方处理。

<script setup lang="ts">
import TajStoreInfo from 'taj-consumer-ui/store-info'

const actions = [
  { key: 'navigate', label: '地图', iconClass: 'i-carbon:send-alt text-lg' },
  { key: 'call', label: '电话', iconClass: 'i-carbon:phone text-lg' },
]
</script>

<template>
  <TajStoreInfo
    store-name="示例门店"
    business-hours="09:00-22:00"
    address="示例地址"
    guide-text="停车场入口位于大楼西侧"
    :actions="actions"
    @detail="handleDetail"
    @guide="handleGuide"
    @action="handleAction"
  />
</template>

订单列表项

TajOrderItem 只负责订单卡片的展示与详情事件。订单状态枚举仍由使用方维护,并在传入组件前转换为 status-labelstatus-typeactive-price,避免公共组件依赖具体业务状态。

<script setup lang="ts">
import TajOrderItem from 'taj-consumer-ui/order-item'

const order = {
  title: '精品洗鞋套餐',
  statusLabel: '待使用',
  statusType: 'primary' as const,
  activePrice: true,
}
</script>

<template>
  <TajOrderItem
    :title="order.title"
    :status-label="order.statusLabel"
    :status-type="order.statusType"
    service-type="到店服务"
    time-label="下单时间"
    time="2026-08-09 20:30"
    price="39.90"
    :active-price="order.activePrice"
    @detail="handleDetail"
  />
</template>

常用视觉变量包括:

  • --xyj-order-item-bg
  • --xyj-order-item-radius
  • --xyj-order-item-shadow
  • --xyj-order-item-title-color
  • --xyj-order-item-meta-color
  • --xyj-order-item-price-color
  • --xyj-order-item-price-inactive-color
  • --xyj-order-item-button-color
  • --xyj-order-item-button-border-color

门店预约弹窗

TajStoreAppointmentPopup 负责预约表单、日期选择和输入校验,不依赖项目 API、登录状态或状态管理。校验通过后仅触发 confirm,接口请求由使用方执行。

<script setup lang="ts">
import type {
  StoreAppointmentConfirmPayload,
  StoreAppointmentPopupExpose,
} from 'taj-consumer-ui'
import { ref } from 'vue'
import TajStoreAppointmentPopup from 'taj-consumer-ui/store-appointment-popup'

const popupRef = ref<StoreAppointmentPopupExpose>()
const submitting = ref(false)

function openAppointment() {
  popupRef.value?.open('store-id', '示例门店')
}

async function handleConfirm(payload: StoreAppointmentConfirmPayload) {
  submitting.value = true
  try {
    await submitAppointment({
      storeId: payload.storeId,
      arrivalTimestamp: payload.arrivalTimestamp,
      peopleCount: payload.peopleCount,
      contactPhone: payload.contactPhone,
      remark: payload.remark,
    })
    popupRef.value?.close()
  }
  finally {
    submitting.value = false
  }
}
</script>

<template>
  <button @click="openAppointment">
    预约
  </button>
  <TajStoreAppointmentPopup
    ref="popupRef"
    :submitting="submitting"
    @confirm="handleConfirm"
  />
</template>

confirm 参数包含:

  • storeId:调用 open() 时传入的门店 ID
  • storeName:调用 open() 时传入的门店名称
  • arrivalTimestamp:用户选择日期的时间戳
  • peopleCount:衣物件数
  • contactPhone:会员手机号
  • remark:可选备注

组件不会自动关闭。接口成功后由外部调用 popupRef.value?.close();提交期间通过 submitting 禁止重复确认并显示提交中文字。

常用视觉变量包括:

  • --xyj-store-appointment-title-color
  • --xyj-store-appointment-subtitle-color
  • --xyj-store-appointment-label-color
  • --xyj-store-appointment-value-color
  • --xyj-store-appointment-placeholder-color
  • --xyj-store-appointment-textarea-bg
  • --xyj-store-appointment-confirm-bg
  • --xyj-store-appointment-confirm-color

发布

本包发布到 npm 官方公共仓库。即使本机默认使用淘宝镜像,登录、查询和发布命令也必须显式指定 https://registry.npmjs.org/

1. 进入项目并确认环境

cd /Users/pengxiongkun/Documents/extra-income/xyj/wx-group/taj-consumer-ui
node --version
pnpm --version

Node.js 版本必须满足 package.json 中的 engines 要求,pnpm 建议使用项目声明的版本。

2. 查询线上版本

发布前先确认当前 npm 最新版本,避免重复发布:

npm view taj-consumer-ui version --registry=https://registry.npmjs.org/
npm view taj-consumer-ui versions --json --registry=https://registry.npmjs.org/

npm 不允许覆盖已发布的同名同版本包。每次发布都必须先更新 package.jsonversion

可根据变更范围选择版本升级命令:

# 修复或小幅兼容更新,例如 0.1.7 -> 0.1.8
npm version patch --no-git-tag-version

# 新增向后兼容功能,例如 0.1.7 -> 0.2.0
npm version minor --no-git-tag-version

# 存在不兼容修改,例如 0.1.7 -> 1.0.0
npm version major --no-git-tag-version

如果已经手动修改过 package.json 的版本号,则不需要再执行 npm version

3. 登录 npm 官方源

本机默认 registry 可能是 registry.npmmirror.com,因此不要直接执行不带 registry 的 npm login

npm login --auth-type=web --registry=https://registry.npmjs.org/

浏览器验证完成后检查登录身份:

pnpm publish:whoami

也可以直接执行完整命令:

npm whoami --registry=https://registry.npmjs.org/

命令必须输出正确的 npm 用户名。如果返回 401 Unauthorized,说明登录凭证无效或已过期,需要重新登录。

4. 发布前检查

先检查工作区,避免把临时文件、密钥或错误版本发布出去:

git status --short
git diff --check

执行类型检查和 npm 压缩包内容预览:

pnpm publish:check

该命令等价于:

pnpm type-check
pnpm pack:check

重点确认 npm pack --dry-run 输出中包含新增组件、类型、样式、README.mdindex.tsglobal.d.ts,且不包含 .env、Token、日志或其他敏感文件。

5. 发布公共包

确认版本号、登录身份和打包内容无误后执行:

pnpm publish:public

该命令等价于:

npm publish --access public --registry=https://registry.npmjs.org/

如果 npm 账号启用了双重验证,发布过程中可能要求输入一次性验证码。按提示输入当前 OTP 即可。

6. 验证发布结果

npm view taj-consumer-ui version --registry=https://registry.npmjs.org/
npm view taj-consumer-ui@最新版本号 dist --registry=https://registry.npmjs.org/

例如验证 0.1.7

npm view [email protected] version --registry=https://registry.npmjs.org/
npm view [email protected] dist --registry=https://registry.npmjs.org/

常见错误

  • Public registration is not allowed:登录时使用了淘宝镜像。重新执行带 npm 官方 registry 的登录命令。
  • 401 Unauthorized:npm 登录凭证已失效,重新登录官方源。
  • 发布时返回 404 Not Found - PUT,但旧版本可查询:通常也是发布凭证失效。先执行 pnpm publish:whoami,确认身份后重试。
  • EOTP:账号开启了双重验证,需要提供 OTP,或使用允许发布的 granular access token。
  • EPUBLISHCONFLICT:当前版本已经发布,先升级 package.json 版本号。
  • 403 Forbidden:账号没有该包的发布权限,或 npm 账号安全策略未满足发布要求。

本包为公开源码包,禁止发布 API 密钥、Token、环境变量、内部接口凭证及用户数据。