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

hhong-mobile

v0.3.1

Published

react mobile ui

Readme

hhong-mobile

描述

基于 React 开发的移动端 UI 组件库

开始

安装

npm install hhong-mobile

# or

yarn add hhong-mobile

使用

main.tsxApp.tsx 入口文件中引入样式。

import 'hhong-mobile/index.css' // 引入样式

按需引入即可使用

import React from 'react'
import { HHButton } from 'hhong-mobile' // 按需引入

export default () => <HHButton type="primary">按钮</HHButton>

组件

HHButton

Button 按钮组件。

HHCalendar

Calendar 日历类组件,主要用作展示,例如签到界面,传入 startActiveDate 数组,如 ['2025-3-20', '2025-3-19', '2025-4-9'] 即可。

使用示例

import { useState } from 'react'
import { HHCalendar } from '..'

const TryCalendar = () => {
  const [dates, setDates] = useState<string[]>(['2025-3-20', '2025-3-19', '2025-4-10', '2025-4-9'])

  const handleCalendarChange = (date: string) => {
    console.log(123, date)
    console.log(new Date(date).getTime())
    if (dates.includes(date)) {
      setDates(dates.filter((item) => item !== date))
    } else {
      setDates([...dates, date])
    }
  }
  return (
    <div>
      <HHCalendar
        minDate="2025-2"
        maxDate="2025-9"
        startActiveDate={dates}
        onChangeDate={handleCalendarChange}
      />
    </div>
  )
}

export default TryCalendar

HHCurtain

Curtain 幕帘组件。

使用示例

import { useState } from 'react'
import { HHCurtain, HHButton } from '..'

const TryCurtain = () => {
  const [visible, setVisible] = useState(false)
  const handleVisibleChange = (flag: boolean) => {
    console.log(123)

    setVisible(flag)
  }
  return (
    <div style={{ width: '100%', height: '2000px' }}>
      <HHButton type="primary" onClick={() => handleVisibleChange(true)}>
        Curtain使用示例
      </HHButton>
      <HHCurtain
        visible={visible}
        width={300}
        height={300}
        clickEmptyToClose
        onClose={() => handleVisibleChange(false)}
      >
        <div style={{ background: '#000' }}>123</div>
      </HHCurtain>
    </div>
  )
}

export default TryCurtain

HHDivider

Divider 分割组件。

Spin

Spin 加载指示器组件。

使用示例

import { useState } from 'react'
import { HHSpin } from '..'

const TrySpin = () => {
  const [visible, setVisible] = useState(true)
  return (
    <div>
      <HHSpin loading={false}>123123</HHSpin>
      <HHSpin loading={true} type="line" />
      <HHSpin loading={true} type="snow" color="#ff0000" />
    </div>
  )
}

export default TrySpin

Modal

Modal 弹窗组件.

使用示例

import { useState } from 'react'
import { HHModal, HHButton } from '..'
const TryModal = () => {
  const [visible, setVisible] = useState(false)

  const onCancel = () => {
    console.log('取消')
  }
  const onOk = () => {
    console.log('确定')
  }
  return (
    <>
      <HHButton onClick={() => setVisible(true)}>测试Modal操作弹窗</HHButton>
      <HHModal
        visible={visible}
        title="我是弹窗"
        description="我是描述"
        onCancel={onCancel}
        onConfirm={onOk}
        onClose={() => setVisible(false)}
      >
        <div>测试弹窗测试弹窗</div>
      </HHModal>
    </>
  )
}

export default TryModal

Expand

Expand 折叠展开组件。

使用示例

import { useState } from 'react'
import { HHExpand } from '..'

const TryExpand = () => {
  const [expand, setExpand] = useState(true)
  const expandContent = () => {
    return (
      <div style={{ width: '100%' }}>
        <div style={{ height: '20px' }}>1</div>
        <div style={{ height: '20px' }}>2</div>
        <div style={{ height: '20px' }}>3</div>
        <div style={{ height: '20px' }}>4</div>
        <div style={{ height: '20px' }}>5</div>
        <div style={{ height: '20px' }}>6</div>
        <div style={{ height: '20px' }}>7</div>
        <div style={{ height: '20px' }}>8</div>
        <div style={{ height: '20px' }}>9</div>
        <div style={{ height: '20px' }}>10</div>
      </div>
    )
  }
  const expandContent2 = () => {
    return (
      <div
        style={{
          width: '100%',
          background: '#eee',
          border: '1px solid #ccc',
          boxSizing: 'border-box',
        }}
      >
        <div style={{ height: '20px' }}>1</div>
        <div style={{ height: '20px' }}>2</div>
        <div style={{ height: '20px' }}>3</div>
        <div style={{ height: '20px' }}>4</div>
        <div style={{ height: '20px' }}>5</div>
        <div style={{ height: '20px' }}>6</div>
        <div style={{ height: '20px' }}>7</div>
        <div style={{ height: '20px' }}>8</div>
        <div style={{ height: '20px' }}>9</div>
        <div style={{ height: '20px' }}>10</div>
      </div>
    )
  }

  return (
    <>
      <HHExpand visible={expand} expandKey="test-expand1" expandContent={expandContent()}>
        外层内容1
      </HHExpand>
      <HHExpand visible={false} expandKey="test-expand2" expandContent={expandContent2()}>
        <div style={{ width: '100%', height: '25px', background: '#ccc' }}>我是外层内容</div>
      </HHExpand>
      <div>ndasndja</div>
      <div>那就是的那家打赏</div>
    </>
  )
}

export default TryExpand

FtBtn

FtBtn 悬浮按钮组件

import { HHFtBtn } from '..'

const TryFtBtn = () => {
  return (
    <div>
      <div style={{ width: '100%', height: '1600px', background: '#f5f5f5' }}>内容内容</div>
      <HHFtBtn>+</HHFtBtn>
    </div>
  )
}

export default TryFtBtn

Progress

Progress 进度条组件

import { useEffect, useState } from 'react'
import { HHProgress, HHDivider } from '..'
const TryProgress = () => {
  const [persent, setPercent] = useState(40)
  useEffect(() => {
    const timer = setInterval(() => {
      const value = Math.floor(Math.random() * 100) + 1 // 生成1到100之间的随机整数
      setPercent(value)
    }, 1000)
    return () => {
      clearInterval(timer)
    }
  }, [])
  return (
    <div>
      <HHProgress
        progressKey="1"
        width={300}
        activeColor="#8a6de9"
        bgColor="#e6e6e6"
        animation
        percent={20}
      />
      <HHDivider />
      <HHProgress
        progressKey="2"
        activeColor="#1890ff"
        bgColor="#e6e6e6"
        animation
        borderRadius={100}
        percent={persent}
      />
    </div>
  )
}

export default TryProgress

CircularProgress

CircularProgress 环形进度条组件。

import { useEffect, useState } from 'react'
import { HHCircularProgress } from '..'

const TryProgress = () => {
  const [persent, setPercent] = useState(40)
  useEffect(() => {
    const timer = setInterval(() => {
      const value = Math.floor(Math.random() * 100) + 1 // 生成1到100之间的随机整数
      setPercent(value)
    }, 1000)
    return () => {
      clearInterval(timer)
    }
  }, [])
  return (
    <div>
      <HHCircularProgress
        percent={persent}
        colorRanges={[
          { percentage: 0, color: '#ff0000' }, // 0-30% 红色
          { percentage: 30, color: '#ffd700' }, // 30-60% 金色
          { percentage: 60, color: '#00ff00' }, // 60-90% 绿色
          { percentage: 90, color: '#0000ff' }, // 90-100% 蓝色
        ]}
        radius={80}
        strokeWidth={6}
        backgroundColor="#f0f0f0"
        showText
      />
    </div>
  )
}

export default TryProgress

BackTop

BackTop 回到顶部悬浮按钮组件。

import { HHBackTop } from '..'
const TryBackTop = () => {
  return (
    <div>
      <div style={{ height: '500px', background: '#eee', marginBottom: 20 }}>111</div>
      <div style={{ height: '2000px', background: '#ddd', marginBottom: 20 }}>222</div>
      <div style={{ height: '2000px', background: '#ccc' }}>333</div>
      <HHBackTop scrollYShow={200} />
    </div>
  )
}

export default TryBackTop

Select

Select 下拉选择器组件。

import { useState } from 'react'
import { HHSelect } from '..'

const TrySelect = () => {
  const [value, setValue] = useState('10')
  const options = [
    { label: '选项1', value: '1' },
    { label: '选项2', value: '2' },
    { label: '选项3', value: '3' },
    { label: '选项4', value: '4' },
    { label: '选项5', value: '5' },
    { label: '选项6', value: '6' },
    { label: '选项7', value: '7' },
    { label: '选项8', value: '8' },
    { label: '选项9', value: '9' },
    { label: '选项10', value: '10' },
  ]
  const handleChange = (item: any) => {
    console.log('接收到的值:', item)
    setValue(item.value)
  }

  return (
    <div style={{ height: '100vh', overflow: 'hidden', width: '100%' }}>
      <HHSelect onlyKey="1" options={options} value={value} onChange={handleChange} />
      <div>内容内容</div>
      <div style={{ marginTop: '700px' }}>
        <HHSelect
          onlyKey="2"
          width={300}
          maxHeight={150}
          options={options}
          value={'2'}
          onChange={handleChange}
          expandStyle={{ width: 350 }}
        />
      </div>
    </div>
  )
}

export default TrySelect

DateTimePicker

DateTimePicker 简易版日期时间选择器,通过下拉选择。

import { HHDateTimePicker } from '..'


<DateTimePicker
        value={new Date()}
        onChange={(date) => console.log(date)}
        minDate="2023-01-01"
        maxDate="2026-12-31"
        precision="minute"
/>

Image、ImagePreview

Image 图片组件,ImagePreview 图片预览组件。

import { useState } from 'react'
import { HHImage, HHImagePreview } from '..'

const TryImage = () => {
  const img = 'https://xxx.png'
  const [visible, setVisible] = useState(false)
  const imgList = [
    'https://xxx.png',
    'https://xxx.png',
    'https://xxx.png',
  ]

  return (
    <div>
      <HHImage src={img} width={200} height={200} fit="cover" onClick={() => setVisible(true)} />
      <HHImagePreview
        startIndex={1}
        imgUrls={imgList}
        visible={visible}
        onClose={() => setVisible(false)}
      />
    </div>
  )
}

export default TryImage

Switch

Switch 开关组件。

import { HHSwitch } from '..'

const TrySwitch = () => {
  return (
    <div>
      <div>
        <HHSwitch checked={true} onChange={(e) => console.log(123, e)} />
        <HHSwitch checked={true} type="danger" onChange={(e) => console.log(123, e)} />
        <HHSwitch checked={true} type="success" onChange={(e) => console.log(123, e)} />
        <HHSwitch checked={true} type="warning" onChange={(e) => console.log(123, e)} />
        <HHSwitch checked={true} type="view" onChange={(e) => console.log(123, e)} />
        <HHSwitch checked={true} openBackgroundColor="#000" onChange={(e) => console.log(123, e)} />
        <HHSwitch
          checked={false}
          openBackgroundColor="#000"
          closeBackgroundColor="#eee"
          onChange={(e) => console.log(123, e)}
        />
      </div>
      <div>
        <HHSwitch checked={false} disabled />
      </div>
    </div>
  )
}

export default TrySwitch

FileChoose

FileChoose 文件选择组件,返回所选择的文件。

import { HHFileChoose } from '..'

const TryFileChoose= () => {

  const handleFileChange = (e: File) => {
    console.log('file', e)
  }

  return (
    <div>
      <FileChoose acceptTypes=".pdf,.png" onChange={(e) => handleFileChange(e)} />
    </div>
  )
}

export default TryFileChoose

ImageUpload

ImageUpload 图片上传组件。

import { HHImageUpload } from '..'

const TryImageUpload = () => {
  const imgList = [
    'https://xxx',
    'https://xxx',
    'https://xxx',
  ]

  const handleChange = (imgUrls: string[], files: File[]) => {
    console.log('imgUrls', imgUrls)
    console.log('files', files)
  }

  return (
    <div>
      <HHImageUpload
        imgUrls={imgList}
        onChange={(imgUrls: string[], files: File[]) => handleChange(imgUrls, files)}
      />
    </div>
  )
}

export default TryImageUpload

QRCode

QRCode 二维码组件。

import { HHQRCode } from '..'

const TryImageUpload = () => {
  return (
    <div>
      <HHQRCode value="https://www.baidu.com" bgColor="#eee" ftColor="#3b82f6" />
    </div>
  )
}

export default TryImageUpload

Hooks

useToast

全局 toast 提示。

使用示例

import { successToast, errorToast, infoToast, warningToast } from 'hhong-mobile'

successToast({ message: '成功提示' })
errorToast({ message: '错误提示' })
infoToast({ message: '消息提示' })
warningToast({ message: '警告提示' })