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

rhjy-ui

v0.2.10

Published

Vue 3 and Element Plus business UI components

Readme

rhjy-ui

rhjy-ui is a Vue 3 and Element Plus business UI component library. The first release contains a configurable data-center suite for displaying asynchronous import, export, generation and other background tasks.

Install

pnpm add rhjy-ui vue element-plus @element-plus/icons-vue

Import the package stylesheet once in the application entrypoint:

import 'rhjy-ui/style.css'

Responsive Info Grid

Responsive Info Grid arranges title-content pairs in a configurable grid and switches column counts at the 1200px and 768px breakpoints.

<script setup lang="ts">
import {
  RhResponsiveInfoGrid,
  RhResponsiveInfoGridItem,
} from 'rhjy-ui'
</script>

<template>
  <RhResponsiveInfoGrid>
    <RhResponsiveInfoGridItem title="Project: " content="Smart Campus" />
    <RhResponsiveInfoGridItem title="Owner: " content="Operations Team" />
    <RhResponsiveInfoGridItem title="Devices: " :content="128" />
    <RhResponsiveInfoGridItem title="Summary: " content="All systems operational" :span="2" />
  </RhResponsiveInfoGrid>
</template>

See the Responsive Info Grid component README for subpath imports, the complete props and slots reference, responsive behavior, and more examples.

Data center panel

rhjy-ui never receives an API URL. Each application supplies a loadTasks function and converts its own response into the standard task model.

<script setup lang="ts">
import { RhDataCenter } from 'rhjy-ui'
import type {
  RhDataCenterCategory,
  RhDataCenterLoadTasks,
} from 'rhjy-ui/data-center'

const categories: RhDataCenterCategory[] = [
  { key: 'all', label: '全部任务' },
  { key: 'generate', label: '数据生成' },
  { key: 'import', label: '数据导入' },
  { key: 'export', label: '数据导出' },
]

const loadTasks: RhDataCenterLoadTasks = async ({ category }) => {
  const response = await requestTaskList({
    taskType: category.key === 'all' ? undefined : category.key,
  })

  return {
    items: response.list,
    total: response.total,
  }
}

const handleTaskAction = ({ action, task }) => {
  if (action === 'download') {
    window.open(task.raw.fileUrl)
  }
}
</script>

<template>
  <RhDataCenter
    :categories="categories"
    :load-tasks="loadTasks"
    sidebar-width="160px"
    @task-action="handleTaskAction"
  />
</template>

The “全部任务” rule is application-owned. It may omit taskType, pass a fixed value, or combine multiple requests without changing the component.

Reuse the business adapter

When multiple applications use the same data-center protocol, use createRhDataCenterAdapter to share response conversion, status messages, sorting, counts, and default download actions. The application still injects its own API functions; the package never receives an API URL.

import {
  createRhDataCenterAdapter,
  type RhDataCenterCategory,
} from 'rhjy-ui/data-center'
import { clickDownloadBtByTaskId, getMyTaskList } from '@/services/dataCenter'

const categories: RhDataCenterCategory[] = [
  { key: 'all', label: '全部任务', query: { taskType: 0 } },
  { key: 2, label: '数据导入', query: { taskType: 2 } },
  { key: 3, label: '数据导出', query: { taskType: 3 } },
]

const { loadTasks, handleTaskAction } = createRhDataCenterAdapter({
  api: {
    getTaskList: getMyTaskList,
    downloadTask: ({ taskId }) => clickDownloadBtByTaskId({ taskId }),
  },
  categories,
  taskTagFieldByTaskType: { 1: 'doTypeName' },
  taskKind: { import: [2], export: [3] },
  completedDownloadKinds: ['other'],
})

The adapter provides default task actions for completed exports, import failure records, and failed tasks. Use completedDownloadKinds when another task kind should show a file download action after completion and its raw task contains fileUrl. Use parseResponse when the application response wrapper or success rule differs. Use mapTask or resolveActions for an application-specific field or operation without changing the shared adapter. RhDataCenter remains responsible for polling; the adapter handles one query and one task action at a time.

Use sidebar-width with a number or CSS size string to adjust the data type panel width. Its default value is 124px.

Category counts are optional and application-owned. Set show-category-count to false to hide every category count, or pass category-counts to display values before individual categories are loaded:

<RhDataCenter
  :categories="categories"
  :load-tasks="loadTasks"
  :show-category-count="true"
  :category-counts="{ all: 20, generate: 8, import: 4, export: 8 }"
/>

When counts are enabled, the component uses categoryCounts, then a loaded result's counts, and finally the category result's total.

When the backend provides a separate count endpoint, configure it on the shared adapter. The count request runs in parallel with each task-list refresh, so the sidebar stays synchronized with polling without moving API details into RhDataCenter:

const { loadTasks, handleTaskAction } = createRhDataCenterAdapter<
  RawTask,
  TaskQuery,
  TaskListResponse,
  TaskCountResponse
>({
  api: {
    getTaskList: requestTaskList,
    getTaskCounts: () => requestTaskCounts({ taskType: 0 }),
  },
  categories,
  parseResponse: (response) => response.data.list,
  parseCounts: (response) => ({
    all: response.data.totalTaskCount,
    import: response.data.taskCountList.find((item) => item.taskType === 2)?.taskCount ?? 0,
  }),
})

parseCounts converts the shared backend response into category keys. If the count request or parser fails, the adapter keeps the task list available and falls back to resolveCounts or the loaded result totals.

Task tags read raw.taskTypeName by default. When an API uses another field name, pass task-tag-field without changing the task adapter:

<RhDataCenter
  :categories="categories"
  :load-tasks="loadTasks"
  task-tag-field="taskTypeName"
/>

If only one category uses a different task tag field, configure taskTagField on that category. The category-level setting takes precedence over the global task-tag-field and the adapter's default tag value:

const categories: RhDataCenterCategory[] = [
  { key: 1, label: '数据生成', query: { taskType: 1 }, taskTagField: 'doTypeName' },
  { key: 2, label: '数据导入', query: { taskType: 2 } },
  { key: 3, label: '数据导出', query: { taskType: 3 } },
]

If the same task type can appear in multiple categories, use task-tag-field-by-task-type. The task type mapping takes precedence over the category setting, so a data-generation task uses doTypeName even when it is displayed in the “全部任务” tab:

<RhDataCenter
  :categories="categories"
  :load-tasks="loadTasks"
  :task-tag-field-by-task-type="{ 1: 'doTypeName' }"
  task-tag-field="taskTypeName"
/>

Task tip flow

Use useRhDataCenter after a page successfully creates a background task:

<script setup lang="ts">
import { RhDataCenterTip, useRhDataCenter } from 'rhjy-ui'

const { tipVisible, tipConfig, showTip } = useRhDataCenter()

const startExport = async () => {
  const result = await createExportTask()
  showTip({
    type: 'export',
    minutes: Number(result.minutes),
    title: '导出文件生成中,大概需要',
    content: '现在你可关闭弹框,去做其他事情了。',
  })
}
</script>

<template>
  <RhDataCenterTip v-model="tipVisible" v-bind="tipConfig" />
</template>

RhDataCenterTip 默认使用简化引导动画;需要使用带数据处理中心图片、手势和方向切换的引导时,可传入 guideVariant="normal" 或 guideVariant="super"。

Standard task model

The adapter returns id, categoryKey, title, createdAt, progress, and one of waiting, processing, success, or failed. Optional tag, message, actions, and raw provide display and application action context.

For completed tasks with rejected records, pass the normalized failCount field. The task item keeps the completed progress bar, shows 失败记录(xx条) in red, and hides the normal completion message when the count is zero. The application still supplies the failure-record action and handles its download event.

For processing tasks, pass taskSeconds to show 总时长约X分XX秒 instead of the default processing message. If taskSeconds is omitted, the provided message is displayed.

Styling

Override CSS variables at the application root when needed:

:root {
  --rh-ui-data-center-primary: #00828a;
  --rh-ui-data-center-panel-width: 606px;
  --rh-ui-data-center-panel-height: 500px;
}

For business-specific styles, pass custom-class. The class is applied to both the trigger and the Teleport panel container, so it can scope overrides for the panel rendered under body:

<RhDataCenter
  class="after-school-data-center"
  custom-class="restaurant-data-center"
  :categories="categories"
  :load-tasks="loadTasks"
  :show-category-count="true"
  :category-counts="categoryCounts"
/>
.restaurant-data-center {
  .rh-data-center-panel__category.is-active {
    color: #409eff;
  }

  .rh-data-center-panel__progressBar {
    background: #409eff;
  }
}

The existing class prop remains supported. If the consuming component uses <style scoped>, use :deep() for selectors inside the Teleport panel:

.restaurant-data-center {
  :deep(.rh-data-center-panel__category.is-active) {
    color: #409eff;
  }
}

The task status icons use the built-in images by default. Use status-icons when a business needs different images; omitted statuses continue to use the defaults:

<script setup lang="ts">
import successIcon from './images/data-center-success.png'
import failedIcon from './images/data-center-failed.png'

const statusIcons = {
  success: successIcon,
  failed: failedIcon,
}
</script>

<template>
  <RhDataCenter
    :categories="categories"
    :load-tasks="loadTasks"
    :status-icons="statusIcons"
  />
</template>

The available keys are waiting, processing, success, and failed. The current default waiting, success, and failed icons keep their existing class name rh-data-center-panel__progressStatusIcon, so size and layout can also be overridden through custom-class.

Build and publish

After changing the source code or component assets, run the package script in the rh-ui directory to regenerate dist:

cd D:\workfile\sass-workspace\packages\rh-ui
npm run package

The workspace equivalent is:

pnpm --filter rhjy-ui package

Before publishing, increment the package version without creating a Git tag:

npm run version:patch

Use npm run version:minor only for a backward-compatible feature release. You can inspect the files that will be published with:

npm pack --dry-run

After confirming the tarball contents, publish the public package:

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

If the account uses two-factor authentication, npm opens the browser authentication flow. After publishing, synchronize the school admin project from this package directory:

cd D:\workfile\sass-workspace\packages\rh-ui
npm run sync:wise-school-admin

The script installs the latest public rhjy-ui release with an exact version and synchronizes D:\workfile\wise-school-admin\package.json and package-lock.json. It is intended for the fixed local workspace path; add another explicit sync:<project> script when a new application needs this workflow.

Releases

The package is published with compiled dist output. Consumers should use an explicit version such as [email protected]; application-specific API adapters remain in the consuming project.