diff --git a/src/docs/components/accordion/index.md b/src/docs/components/accordion/index.md index 275e7fd2..5d65d3cc 100644 --- a/src/docs/components/accordion/index.md +++ b/src/docs/components/accordion/index.md @@ -3,6 +3,10 @@ title: Accordion 手风琴 lang: zh-CN --- +:::warning 注 +Highly experimental +::: + ## 基本使用 \ No newline at end of file diff --git a/src/docs/components/calendar/index.md b/src/docs/components/calendar/index.md index 032dd871..c9aa5f09 100644 --- a/src/docs/components/calendar/index.md +++ b/src/docs/components/calendar/index.md @@ -3,6 +3,10 @@ title: Calendar 日历 lang: zh-CN --- +:::warning 注 +Highly experimental +::: + ## 基本使用 默认选择单个日期,设置`multiple`可选择多个日期;设置`range`时可选择一个日期范围,同时设置`multiple`和`range`时可选择多个日期范围,多个范围之间不能重叠,但一个区间的结尾可以与另一个区间的开始相同 diff --git a/src/docs/components/input/index.md b/src/docs/components/input/index.md index 4a8cd6e8..98831f8e 100644 --- a/src/docs/components/input/index.md +++ b/src/docs/components/input/index.md @@ -134,3 +134,7 @@ const label = { ``` + +:::warning 注 +轮播标签使用了`overflow: clip`和`overflow-clip-margin: 1px`来防止聚焦时的outline被截断,safari暂不兼容 +::: diff --git a/src/docs/components/static-config/index.md b/src/docs/components/static-config/index.md index 35b4bc6f..518d251e 100644 --- a/src/docs/components/static-config/index.md +++ b/src/docs/components/static-config/index.md @@ -29,8 +29,6 @@ export declare const GlobalStaticConfig: { preferCSSStyleSheet: boolean; /** define every components' static styles, also can set global common style with `common` key */ styles: ComponentStyles; - /** readonly */ - computedStyles: Readonly; /** must define the breakpoints from smallest to largest */ breakpoints: { xs: string; @@ -48,6 +46,13 @@ export declare const GlobalStaticConfig: { animationRegistry: Record; /** useless for now, consider to remove it */ elAnimationRegistry: WeakMap>; + /** + * define every components' event init map, it's used to initialize the event object when dispatch event + * every entry accepts object or array value: + * - object value: `{ button: { composed: true, bubbles: true } }`, the object will be used for every event for that component + * - array value: `{ button: [{ composed: true }, { validClick: { bubbles: true } }] }` the first value will be used for every event, the second object can be the corresponding event's init(event name must be camelCase) + */ + eventInitMap: Record | [Omit, Record>])> /** define the math preset methods used to process numbers */ math: Required>; /** define the date preset methods used to process dates */ diff --git a/src/docs/en/components/static-config/index.md b/src/docs/en/components/static-config/index.md index 96f44684..c02480fc 100644 --- a/src/docs/en/components/static-config/index.md +++ b/src/docs/en/components/static-config/index.md @@ -30,8 +30,6 @@ export declare const GlobalStaticConfig: { preferCSSStyleSheet: boolean; /** define every components' static styles, also can set global common style with `common` key */ styles: ComponentStyles; - /** readonly */ - computedStyles: Readonly; /** must define the breakpoints from smallest to largest */ breakpoints: { xs: string; diff --git a/src/docs/guides/caveat/index.md b/src/docs/guides/caveat/index.md index d36b2908..38880b22 100644 --- a/src/docs/guides/caveat/index.md +++ b/src/docs/guides/caveat/index.md @@ -7,7 +7,7 @@ lang: zh-CN 在某些组件中,我们会将一些实用的方法或属性暴露到 DOM 上,你可能会在组件加载时调用这些方法。但需要注意的是,你**可能需要在组件加载后的下一个微任务才能访问到这些方法或属性**。 -以 Vue 为例,在组件的`onMounted`中可能还需要`queueMicrotask`或`Promise.resolve()`才能访问到最内层 DOM 暴露的方法或属性 +以 Vue 为例,在组件的`onMounted`中可能还需要`queueMicrotask`或`Promise.resolve()`才能访问到**最内层 DOM**暴露的方法或属性 查看下面的示例代码并打开控制台查看输出,可以看到在`onMounted`我们可以获取到`l-popover`的方法,但是无法获取`l-button`的方法,而下个微任务后就都可以访问到了 diff --git a/src/docs/guides/events/index.md b/src/docs/guides/events/index.md index 25d31dae..1e6a2f73 100644 --- a/src/docs/guides/events/index.md +++ b/src/docs/guides/events/index.md @@ -12,4 +12,29 @@ button.addEventListener('validClick', () => {}) button.addEventListener('valid-click', () => {}) ``` -派发的事件均为`CustomEvent`,**不会冒泡**,通过`event.detail`可获取传递的数据(如果有的话)。 \ No newline at end of file +派发的事件均为`CustomEvent`,通过`event.detail`可获取传递的数据(如果有的话)。事件的其他参数均为默认,也就是`bubbles: false, cancelable: false, composed: false`,**默认不冒泡, 不可取消,不会穿越 Shadow DOM 边界**。如果需要修改,可通过`GlobalStaticConfig.eventInitMap`进行配置,支持配置每个组件所有事件的默认参数,或某个事件的默认参数 + +```js +// 如果是对象,则该组件所有事件使用这个对象初始化 +GlobalStaticConfig.eventInitMap.button = { + bubbles: true, + cancelable: true, + composed: true +} +// 如果是数组,第一个对象用于所有对象初始化,第二个对象用于指定某个事件的初始化 +GlobalStaticConfig.eventInitMap.button = [ + { + bubbles: true, + }, + { + // key必须为驼峰格式 + validClick: { + composed: true + } + } +] + +// 也可以针对所有组件设置相同的 +GlobalStaticConfig.eventInitMap.common = {} +GlobalStaticConfig.eventInitMap.common = [] +``` \ No newline at end of file diff --git a/src/docs/guides/usage/index.md b/src/docs/guides/usage/index.md index 449a1c69..5a7dd152 100644 --- a/src/docs/guides/usage/index.md +++ b/src/docs/guides/usage/index.md @@ -3,11 +3,17 @@ title: 如何使用 lang: zh-CN --- +目前提供以下的库: - `@lun/utils`:js 工具函数库 - `@lun/core`:提供组件功能的钩子函数库 - `@lun/components`:组件库 - `@lun/theme`:主题库 -- `@lun/react`:为 react19之前的版本封装的组件库,详细见下文[React 中使用](#react-中使用) +- `@lun/react`:为 react19 之前的版本封装的组件库,详细见下文[React 中使用](#react-中使用) +- `@lun/plugins`: 为 JSX 或 Vue template 提供自定义指令 + +:::tip 注 +在使用本组件库之前,你需要了解[自定义元素](https://developer.mozilla.org/zh-CN/docs/Web/API/Web_components/Using_custom_elements)的相关知识,只需知道如何使用即可,无需了解如何创建 +::: ## 安装 @@ -23,7 +29,7 @@ lang: zh-CN ## React 中使用 -React 是目前流行 web 框架唯一不支持`customElement`的,详情见[`Custom Elements Everywhere`](https://custom-elements-everywhere.com/)。在 React 18 及之前版本中使用自定义元素,只会将属性设置为 attribute,不会自动设置为元素的 property,也无法使用`onXXX`监听自定义元素的事件 +React 是目前流行 web 框架中唯一不支持`customElement`的,详情见[`Custom Elements Everywhere`](https://custom-elements-everywhere.com/)。在 React 18 及之前版本中使用自定义元素,只会将属性设置为 attribute,不会自动设置为元素的 property,也无法使用`onXXX`监听自定义元素的事件 React 19 即将支持`customElement`,但目前还处于实验阶段。本文档使用的是 React 19 RC,在文档的 React 代码中可正常使用自定义元素。 @@ -65,8 +71,19 @@ importSolidTheme(); defineAllComponents(); ``` -- 全量引入的组件会使用`GlobalStaticConfig.namespace`加上组件本身的名字作为命名,例如`namespace`默认为`l`,那么`button`组件的默认名字便是`l-button`。引入组件后你便可以在任何地方使用它们 - 全局静态配置需要在组件被使用前修改,但最好在定义前就统一修改,因为`namespace`在定义时就会使用 +- 全量引入的组件会使用`GlobalStaticConfig.namespace`加上组件本身的名字作为命名,例如`namespace`默认为`l`,那么`button`组件的默认名字便是`l-button`。引入组件后你便可以在任何地方使用它们 +- 为保证视觉效果,你需要自行向页面添加类似于下面的样式,在组件未定义时隐藏它们,以避免它们的 children 被渲染出来而造成闪烁 + +```css +:not(:defined) { + visibility: hidden; +} +/** or */ +:not(:defined) { + opacity: 0; +} +``` ## 动态引入 @@ -106,9 +123,63 @@ defineButton('my-button', { 需要这么做的原因是,大部分组件都有继承关系,部分状态由父组件提供。在 SSR 场景下,页面上的元素已经存在,如果子组件先被定义,此时它无法探测到父组件(组件未被定义时是无效组件),等父组件再被定义时子组件也不会被更新,便会出现问题 ::: +## TS 支持 + +目前提供了`Vue`和`React`的组件类型定义,你需要在 TS 配置对应引入`@lun/components/elements-types-vue`或`@lun/components/elements-types-react` + +需要注意的是,提供的类型文件是针对默认`namespace`,也就是`l-button`, `l-input`等以`l`开头的组件,如果你自定义了命名空间,可以仿造以下示例编写 + +```ts +// Vue +import * as Vue from 'vue'; +// Vue template +declare module 'vue' { + interface GlobalComponents { + LButton: Vue.DefineComponent; + } +} +// Vue JSX +declare module 'vue/jsx-runtime' { + namespace JSX { + interface IntrinsicElements { + 'l-button': Vue.HTMLAttributes & Vue.ReservedProps & import('@lun/components').ButtonProps; + } + } +} + +// React +import * as React from 'react'; +declare module 'react/jsx-runtime' { + namespace JSX { + interface IntrinsicElements { + 'l-button': React.HTMLAttributes & React.RefAttributes & import('@lun/components').ButtonProps; + } + } +} +``` + +每个组件都有一个class和两个类型,注意区分 +```ts +import { Button, tButton, iButton } from '@lun/components'; +Button // 组件的class,这是值,不是类型,一般用不到 +tButton // 组件class的类型,相当于typeof Button +iButton // 组件实例的类型,相当于InstanceType +``` + +当需要组件实例类型时,你可以像下面这样使用: +```ts +import { iButton } from '@lun/components'; +const button = document.querySelector('l-button') as iButton; +button.asyncHandler = () => console.log(''); + +const buttonRef = ref(); +const render = () => ; +``` + + ## 兼容性 -至少需要兼容`customElement`, 考虑到以下特性版本要求不高, 若不支持你需要自行 polyfill 或不使用某些特性,CSS可考虑使用全局配置`stylePreprocessor`处理或自行编写样式 +至少需要兼容`customElement`, 考虑到以下特性版本要求不高, 若不支持你需要自行 polyfill 或不使用某些特性,CSS 可考虑使用全局配置`stylePreprocessor`处理或自行编写样式 - [customElement](https://caniuse.com/?search=customElement) - [BigInt](https://caniuse.com/?search=BigInt) @@ -146,10 +217,11 @@ defineButton('my-button', { - [CSS Subgrid](https://caniuse.com/?search=Subgrid) - [CSS color()]() -某些特性无法做兼容,但它们影响不大,只是出于技术探索添加了那些特性,不使用那些功能即可 +某些特性无法或不好做兼容,但它们影响不大,不使用那些功能即可 - [`doc-pip`](/components/doc-pip/): [DocumentPictureInPicture](https://caniuse.com/?search=DocumentPictureInPicture) - [`mentions`](/components/mentions/): [CSS highlight](https://caniuse.com/?search=highlight) +- [`input`](/components/input/#轮播标签): [CSS overflow-clip-margin](https://caniuse.com/?search=overflow-clip-margin)