Skip to content

ranui

基于 Web Components开发方案

Feature 特点

  1. 高度跨框架兼容: 能够轻松适配多种主流前端框架,包括ReactVuePreactSolidJSSvelte等,甚至任何基于JavaScript并遵循W3C标准的项目也能无缝集成。无论您的技术栈如何选择,我们都能提供稳定且一致的支持。
  2. 原生纯粹的体验: 无需依赖npmReact/Vue等前端框架,也无需webpack/vite等复杂的构建工具,真正回归Web技术的最本质。您可以像操作原生div标签一样轻松上手,即刻感受技术的纯粹与直观。这样的设计不仅简化了项目的结构,更降低了学习和使用的成本,让每一个开发者都能体验到Web技术的原生魅力。
  3. 极致模块化设计: 采用最小模块化原则,将庞大复杂的系统或应用程序精心拆解为尺寸极小、功能独立且易于复用的组件单元。有助于提高代码的可维护性、可扩展性和可重用性
  4. 全面开源自由学习: 项目完全遵循MIT开源协议,所有源代码毫无保留地对外开放。这意味着可以自由地访问、学习、参考甚至修改我们的代码,无论是为了个人提升还是商业应用,我们都为您提供了一个开放、透明的平台。坚信,开源是促进技术进步和创新的重要途径
  5. 交互式丰富文档: 提供详尽且互动性强的文档,其中所有组件实例均可进行实时交互,让您在阅读的同时能够直接体验组件功能,加深理解并快速上手。这样的设计旨在为您提供最直观、最高效的学习体验。
  6. 支持类型校验: 开发环境完全基于TypeScript构建,配备了完整的声明文件和类型定义,确保无论是JavaScript还是TypeScript项目都能得到顺畅的集成。通过强大的类型检查功能,我们极大地提升了代码的可读性、可维护性,以及项目的稳健性,为开发工作带来前所未有的便捷与安心。
  7. 更加持久和稳定:具备出色的稳定性,无需担忧类似于React15版升级到16版(fiber),或Vue2版升级到3版时(hooks)可能遭遇的破坏性更新问题。我们确保您的组件不会因此被迫进行不必要的更新或重新开发,从而避免了潜在的项目中断和额外工作量。意味着选择了持续、无忧的项目运行。

Situation 项目情况

Build Statusnpm-vnpm-dbrotlimodule formats: umd, esm

Usage 使用

大多数情况都可以像原生的 div 标签一样使用。

接下来是一些使用例子

  1. html
  2. js
  3. jsx
  4. vue
  5. tsx

1.html

html
<script src="./ranui/dist/umd/index.umd.cjs"></script>

<body>
  <r-button>Button</r-button>
</body>

2.js

js
import 'ranui';

const Button = document.createElement('r-button');
Button.appendChild('this is button text');
document.body.appendChild(Button);

3.jsx

由于react有合成事件,为了更加方便的使用,通过react高阶组件进行封装ranui,输出了@ranui/react

react中,使用@ranui/react会更加丝滑,通过高阶函数包裹后,与react生态系统完全融合。

然而,ranui仍然可以在任何js或者ts中使用。

jsx
import 'ranui';
const App = () => {
  return (
    <>
      <r-button>Button</r-button>
    </>
  );
};

4.vue

vue
<template>
  <r-button>Button</r-button>
</template>
<script>
import 'ranui';
</script>

5.tsx

由于react有合成事件,为了更加方便的使用,通过react高阶组件进行封装ranui,于是有了@ranui/react

react中,使用@ranui/react会更加丝滑,通过高阶函数包裹后,与react生态系统完全融合。

然而,ranui仍然可以在任何js或者ts中使用。

tsx
// react 18
import type { SyntheticEvent } from 'react';
import React, { useRef } from 'react';
import 'ranui';

const FilePreview = () => {
  const ref = useRef<HTMLDivElement | null>(null);
  const uploadFile = (e: SyntheticEvent<HTMLDivElement>) => {
    if (ref.current) {
      const uploadFile = document.createElement('input');
      uploadFile.setAttribute('type', 'file');
      uploadFile.click();
      uploadFile.onchange = (e) => {
        const { files = [] } = uploadFile;
        if (files && files?.length > 0 && ref.current) {
          ref.current.setAttribute('src', '');
          const file = files[0];
          const url = URL.createObjectURL(file);
          ref.current.setAttribute('src', url);
        }
      };
    }
  };
  return (
    <div>
      <r-preview ref={ref}></r-preview>
      <r-button type="primary" onClick={uploadFile}>
        choose file to preview
      </r-button>
    </div>
  );
};

jsxTypeScript中定义了所有html原生组件的类型。web component类型不在jsx定义中。需要手动添加。否则会有类型问题,但它实际上是有效的。

ts
// typings.d.ts
interface RButton {
  type?: string;
  onClick?: React.MouseEventHandler<HTMLDivElement> | undefined;
}

interface RPreview {
  src?: string | Blob | ArrayBuffer;
  onClick?: React.MouseEventHandler<HTMLDivElement> | undefined;
  ref?: React.MutableRefObject<HTMLDivElement | null>;
}

declare namespace JSX {
  interface IntrinsicElements {
    'r-preview': React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement> & RPreview;
    'r-button': React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement> & RButton;
  }
}

Import 导入方式

支持按需引入

js
import 'ranui/button';

对于一些全局展示的组件,比如 previewmessage,需要加载一些额外的样式

js
import 'ranui/preview';
import 'ranui/style';

也可以全局导入,更加方便,这样什么都不用考虑了,梭哈完事。

  • ES module
js
import 'ranui';
  • UMD, IIFE, CJS
html
<script src="./ranui/dist/umd/index.umd.cjs"></script>

Overview 组件总览

  • Button
主要按钮
警告按钮
文本按钮
默认按钮
  • Icon
  • Skeleton
  • Input
  • message
信息提示警告提示错误提示成功提示toast 提示
  • Tab
tab1tab2tab3
  • Radar
  • Progress
  • Player
  • Select
MikeTomLucy

Event 事件

  • react

@ranui/react 是由react高阶函数封装ranui而成,Event 事件遵循react事件规范。跟W3C标准略有不同。

  • 现代web标准

W3C标准中,你可以使用on属性在HTML元素上定义事件处理程序。但这是旧的事件处理程序的方法。

现代的web开发推荐使用addEventListener方法。

html
<r-button id="button">按钮</r-button>

<script>
  const button = document.getElementById('button');
  button.addEventListener('click', function (event) {
    alert('新的点击事件!');
  });
</script>

然而,如果你确实需要使用on属性,下面是一个示例:

html
<r-input onchange="change(this.value)"></r-input>

<script>
  function change(e) {
    console.log('e--->', e);
  }
</script>

请注意,使用on属性来定义事件处理程序有一些限制和缺点。

例如,你不能使用事件捕获或事件委托,而且每个事件类型都需要一个单独的属性。

这也是为什么现代的web开发推荐使用addEventListener方法的原因。

还可以使用property的方式:

html
<r-input id="input"></r-input>

<script>
  const input = document.getElementById("input")
  input.onchange = (e) {
    console.log('e--->', e)
  }
</script>

style 自定义样式

::part伪类

html
<r-input id="input"></r-input>

<style>
  /* #input 指的是当前的自定义元素
  ::part(input) 中的input指的是,当前自定义元素内部的 Shadow DOM 元素的类 */
  #input::part(input) {
    width: 100px;
  }
</style>

具体的伪类名称可以查看具体的具体介绍

通过sheet属性传入

会在所有的组件上加一个sheet属性,传入CSSStyleSheet字符串。会直接插入到Shadow DOM

css3变量var

通过给组件设置css3变量,从而自定义组件内部的指定样式,比如:


html
<r-progress percent="0.7" type="drag"></r-progress>
<r-progress
  percent="0.70"
  type="drag"
  style="--ran-progress-wrap:linear-gradient(to right, #ff0000, #ffff00, #00ff00, #00ffff, #0000ff, #ff00ff, #ff0000);"
></r-progress>

具体css3变量名称可以参考每个组件的介绍和说明

Compatibility 兼容性

  • 不支持 IE,其他均有较好支持

Contributors 贡献者

Other 相关资源

  1. 优秀的组件设计
  2. 在线生成 CSS 渐变色
  3. 优秀设计作品,有 psd 和 sketch
  4. 3D UI 设计,类似于 3D 版的 figma
  5. 设计规范
  6. 优秀设计作品
  7. element UI 中文网
  8. Ant design 中文网
  9. 在线绘制 CSS 动画
  10. tailwindcss 组件库
  11. animate css 非常优秀的 css 动画
  12. can i use 检测兼容性 API 网站
  13. figma

协议和标准

  1. RFCs
  2. ECMA
  3. w3c

Released under the MIT License.