@greypan/web-ui 2.0.2 → 2.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.CN.md +60 -20
- package/README.md +56 -15
- package/dist/components/checkbox/index.js +1 -1
- package/dist/components/checkbox/index.js.map +1 -1
- package/dist/components/checkbox/style.js +1 -1
- package/dist/components/checkbox/style.js.map +1 -1
- package/dist/components/radio/index.js +1 -1
- package/dist/components/radio/index.js.map +1 -1
- package/dist/components/radio/style.js +1 -1
- package/dist/components/radio/style.js.map +1 -1
- package/dist/components/segmented/index.d.ts +2 -0
- package/dist/components/segmented/index.js +18 -11
- package/dist/components/segmented/index.js.map +1 -1
- package/dist/components/segmented/style.js +1 -1
- package/dist/components/segmented/style.js.map +1 -1
- package/dist/components/segmented-trigger/index.d.ts +3 -0
- package/dist/components/segmented-trigger/index.js +19 -12
- package/dist/components/segmented-trigger/index.js.map +1 -1
- package/dist/components/segmented-trigger/style.js +1 -1
- package/dist/components/segmented-trigger/style.js.map +1 -1
- package/dist/types/react.d.ts +5 -4
- package/dist/types/utils.d.ts +4 -11
- package/package.json +1 -1
package/README.CN.md
CHANGED
|
@@ -4,6 +4,11 @@
|
|
|
4
4
|
|
|
5
5
|
[English](./README.md) | 简体中文
|
|
6
6
|
|
|
7
|
+
## 演示
|
|
8
|
+
|
|
9
|
+
[查看 vue 使用演示](https://pan-z2l0ahvi.github.io/mono/vue-web-ui-demo/)
|
|
10
|
+
[查看 react 使用演示](https://pan-z2l0ahvi.github.io/mono/react-web-ui-demo/)
|
|
11
|
+
|
|
7
12
|
## 安装
|
|
8
13
|
|
|
9
14
|
```bash
|
|
@@ -56,6 +61,39 @@ function App() {
|
|
|
56
61
|
}
|
|
57
62
|
```
|
|
58
63
|
|
|
64
|
+
#### React 自定义元素事件与布尔属性
|
|
65
|
+
|
|
66
|
+
React 19 按 JSX 键名中的 `on` 后缀原样注册 Custom Element 事件。事件名大小写敏感:`open-change`
|
|
67
|
+
必须绑定为 `onopen-change`,不能写成 `onOpenChange`。标准 `input` 和 `change` 事件仍使用 React
|
|
68
|
+
惯用的 `onInput` 和 `onChange`。默认值为 `true` 的属性应使用驼峰 JavaScript 属性传入,这样 `false`
|
|
69
|
+
才会传递给组件。
|
|
70
|
+
|
|
71
|
+
```tsx
|
|
72
|
+
<web-ui-dialog
|
|
73
|
+
open={open}
|
|
74
|
+
lockScroll={false}
|
|
75
|
+
onopen-change={event => setOpen(event.detail.open)}
|
|
76
|
+
/>
|
|
77
|
+
<web-ui-select value={value} onChange={event => setValue(event.currentTarget.value)} />
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
当组件会把子元素移入自身的 Portal Shadow DOM(例如 `web-ui-dropdown` 的菜单项)时,React 根节点的
|
|
81
|
+
合成 `onClick` 无法收到该子元素的事件。需要通过 `ref` 直接绑定原生事件:
|
|
82
|
+
|
|
83
|
+
```tsx
|
|
84
|
+
const itemRef = useRef<HTMLElement>(null)
|
|
85
|
+
|
|
86
|
+
useEffect(() => {
|
|
87
|
+
const item = itemRef.current
|
|
88
|
+
if (!item) return
|
|
89
|
+
const close = () => setOpen(false)
|
|
90
|
+
item.addEventListener('click', close)
|
|
91
|
+
return () => item.removeEventListener('click', close)
|
|
92
|
+
}, [])
|
|
93
|
+
|
|
94
|
+
<web-ui-dropdown-item ref={itemRef}>粘贴并关闭</web-ui-dropdown-item>
|
|
95
|
+
```
|
|
96
|
+
|
|
59
97
|
### Vue
|
|
60
98
|
|
|
61
99
|
需要 `vue >= 3` 作为可选 peer 依赖。
|
|
@@ -296,12 +334,12 @@ ArrowUp/ArrowDown 键增减数值。
|
|
|
296
334
|
|
|
297
335
|
分段控制——单选按钮组。
|
|
298
336
|
|
|
299
|
-
| 属性 | 类型 | 默认值 | 说明
|
|
300
|
-
| ---------- | --------- | ------- |
|
|
301
|
-
| `value` | `string` | `''` | 当前选中值
|
|
302
|
-
| `name` | `string` | `''` | 表单字段名
|
|
303
|
-
| `disabled` | `boolean` | `false` |
|
|
304
|
-
| `required` | `boolean` | `false` | 必填校验
|
|
337
|
+
| 属性 | 类型 | 默认值 | 说明 |
|
|
338
|
+
| ---------- | --------- | ------- | ---------------- |
|
|
339
|
+
| `value` | `string` | `''` | 当前选中值 |
|
|
340
|
+
| `name` | `string` | `''` | 表单字段名 |
|
|
341
|
+
| `disabled` | `boolean` | `false` | 禁用全部 trigger |
|
|
342
|
+
| `required` | `boolean` | `false` | 必填校验 |
|
|
305
343
|
|
|
306
344
|
**事件:** `input`, `change`
|
|
307
345
|
|
|
@@ -309,24 +347,24 @@ ArrowUp/ArrowDown 键增减数值。
|
|
|
309
347
|
|
|
310
348
|
与原生 `<form>` 集成(通过 `ElementInternals`)。
|
|
311
349
|
|
|
312
|
-
根据 `value` 同步子 trigger 的 `checked`
|
|
350
|
+
根据 `value` 同步子 trigger 的 `checked` 状态。`disabled` 提供继承的有效禁用状态,不改写 trigger 自身的 `disabled` 属性。直接设 `value` 不派发事件。
|
|
313
351
|
|
|
314
352
|
#### `<web-ui-checkbox-group>`
|
|
315
353
|
|
|
316
354
|
多选复选框组。
|
|
317
355
|
|
|
318
|
-
| 属性 | 类型 | 默认值 | 说明
|
|
319
|
-
| ---------- | ---------- | ------- |
|
|
320
|
-
| `value` | `string[]` | `[]` | 已选项的值数组
|
|
321
|
-
| `name` | `string` | `''` | 表单字段名
|
|
322
|
-
| `disabled` | `boolean` | `false` |
|
|
323
|
-
| `required` | `boolean` | `false` | 必填校验
|
|
356
|
+
| 属性 | 类型 | 默认值 | 说明 |
|
|
357
|
+
| ---------- | ---------- | ------- | -------------- |
|
|
358
|
+
| `value` | `string[]` | `[]` | 已选项的值数组 |
|
|
359
|
+
| `name` | `string` | `''` | 表单字段名 |
|
|
360
|
+
| `disabled` | `boolean` | `false` | 禁用全部子项 |
|
|
361
|
+
| `required` | `boolean` | `false` | 必填校验 |
|
|
324
362
|
|
|
325
363
|
**事件:** `input`, `change`
|
|
326
364
|
|
|
327
365
|
**插槽:** `default`(投影 `<web-ui-checkbox>` 元素)
|
|
328
366
|
|
|
329
|
-
|
|
367
|
+
同步子 checkbox 的 `checked` 状态。`disabled` 提供继承的有效禁用状态,不改写子项自身的 `disabled` 属性。监听子项 `change` 事件。
|
|
330
368
|
|
|
331
369
|
#### `<web-ui-radio-group>`
|
|
332
370
|
|
|
@@ -336,13 +374,15 @@ ArrowUp/ArrowDown 键增减数值。
|
|
|
336
374
|
| ---------- | --------- | ------- | ------------------------ |
|
|
337
375
|
| `value` | `string` | `''` | 当前选中值 |
|
|
338
376
|
| `name` | `string` | `''` | 表单字段名(传递到子项) |
|
|
339
|
-
| `disabled` | `boolean` | `false` |
|
|
377
|
+
| `disabled` | `boolean` | `false` | 禁用全部子项 |
|
|
340
378
|
| `required` | `boolean` | `false` | 必填校验 |
|
|
341
379
|
|
|
342
380
|
**事件:** `input`, `change`
|
|
343
381
|
|
|
344
382
|
**插槽:** `default`(投影 `<web-ui-radio>` 元素)
|
|
345
383
|
|
|
384
|
+
`disabled` 提供继承的有效禁用状态,不改写子项自身的 `disabled` 属性。
|
|
385
|
+
|
|
346
386
|
---
|
|
347
387
|
|
|
348
388
|
### 按钮
|
|
@@ -760,11 +800,11 @@ toast.updateMessage(id, { message: '上传已完成 60%', heading: '正在上传
|
|
|
760
800
|
|
|
761
801
|
`<web-ui-segmented>` 的分段按钮。
|
|
762
802
|
|
|
763
|
-
| 属性 | 类型 | 默认值 | 说明
|
|
764
|
-
| ---------- | --------- | ------- |
|
|
765
|
-
| `value` | `string` | `''` | 分段值
|
|
766
|
-
| `checked` | `boolean` | `false` | 当前选中
|
|
767
|
-
| `disabled` | `boolean` | `false` |
|
|
803
|
+
| 属性 | 类型 | 默认值 | 说明 |
|
|
804
|
+
| ---------- | --------- | ------- | ------------------ |
|
|
805
|
+
| `value` | `string` | `''` | 分段值 |
|
|
806
|
+
| `checked` | `boolean` | `false` | 当前选中 |
|
|
807
|
+
| `disabled` | `boolean` | `false` | 单独禁用该 trigger |
|
|
768
808
|
|
|
769
809
|
**事件:** `change`
|
|
770
810
|
|
package/README.md
CHANGED
|
@@ -4,6 +4,11 @@
|
|
|
4
4
|
|
|
5
5
|
English | [简体中文](./README.CN.md)
|
|
6
6
|
|
|
7
|
+
## Demo
|
|
8
|
+
|
|
9
|
+
[View used by vue demo](https://pan-z2l0ahvi.github.io/mono/vue-web-ui-demo/)
|
|
10
|
+
[View used by react demo](https://pan-z2l0ahvi.github.io/mono/react-web-ui-demo/)
|
|
11
|
+
|
|
7
12
|
## Install
|
|
8
13
|
|
|
9
14
|
```bash
|
|
@@ -56,6 +61,40 @@ function App() {
|
|
|
56
61
|
}
|
|
57
62
|
```
|
|
58
63
|
|
|
64
|
+
#### React custom-element events and boolean properties
|
|
65
|
+
|
|
66
|
+
React 19 registers Custom Element events using the suffix of the JSX `on` key unchanged. Event names are
|
|
67
|
+
case-sensitive: bind `open-change` as `onopen-change`, not `onOpenChange`. Standard `input` and `change`
|
|
68
|
+
events continue to use React's conventional `onInput` and `onChange`. For a default-`true` property, pass the
|
|
69
|
+
camel-cased JavaScript property so `false` reaches the element.
|
|
70
|
+
|
|
71
|
+
```tsx
|
|
72
|
+
<web-ui-dialog
|
|
73
|
+
open={open}
|
|
74
|
+
lockScroll={false}
|
|
75
|
+
onopen-change={event => setOpen(event.detail.open)}
|
|
76
|
+
/>
|
|
77
|
+
<web-ui-select value={value} onChange={event => setValue(event.currentTarget.value)} />
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
When a component moves a child into its Portal Shadow DOM (such as a `web-ui-dropdown` menu item), React's
|
|
81
|
+
root-delegated synthetic `onClick` cannot receive that child's event. Bind a native listener directly through a
|
|
82
|
+
`ref` instead:
|
|
83
|
+
|
|
84
|
+
```tsx
|
|
85
|
+
const itemRef = useRef<HTMLElement>(null)
|
|
86
|
+
|
|
87
|
+
useEffect(() => {
|
|
88
|
+
const item = itemRef.current
|
|
89
|
+
if (!item) return
|
|
90
|
+
const close = () => setOpen(false)
|
|
91
|
+
item.addEventListener('click', close)
|
|
92
|
+
return () => item.removeEventListener('click', close)
|
|
93
|
+
}, [])
|
|
94
|
+
|
|
95
|
+
<web-ui-dropdown-item ref={itemRef}>Paste and close</web-ui-dropdown-item>
|
|
96
|
+
```
|
|
97
|
+
|
|
59
98
|
### Vue
|
|
60
99
|
|
|
61
100
|
Requires `vue >= 3` as optional peer dependency.
|
|
@@ -304,7 +343,7 @@ Segmented control — single-select button group.
|
|
|
304
343
|
| ---------- | --------- | ------- | ---------------------- |
|
|
305
344
|
| `value` | `string` | `''` | Selected trigger value |
|
|
306
345
|
| `name` | `string` | `''` | Form field name |
|
|
307
|
-
| `disabled` | `boolean` | `false` |
|
|
346
|
+
| `disabled` | `boolean` | `false` | Disables all triggers |
|
|
308
347
|
| `required` | `boolean` | `false` | Required validation |
|
|
309
348
|
|
|
310
349
|
**Events:** `input`, `change`
|
|
@@ -313,24 +352,24 @@ Segmented control — single-select button group.
|
|
|
313
352
|
|
|
314
353
|
Form-associated: integrates with native `<form>` via `ElementInternals`.
|
|
315
354
|
|
|
316
|
-
Manages child trigger `checked` state based on `value`. Setting `value` directly does not dispatch `input`/`change`.
|
|
355
|
+
Manages child trigger `checked` state based on `value`. `disabled` supplies inherited effective disabled state without changing a trigger's own `disabled` property. Setting `value` directly does not dispatch `input`/`change`.
|
|
317
356
|
|
|
318
357
|
#### `<web-ui-checkbox-group>`
|
|
319
358
|
|
|
320
359
|
Checkbox group managing multiple selection.
|
|
321
360
|
|
|
322
|
-
| Attribute | Type | Default | Description
|
|
323
|
-
| ---------- | ---------- | ------- |
|
|
324
|
-
| `value` | `string[]` | `[]` | Selected values
|
|
325
|
-
| `name` | `string` | `''` | Form field name
|
|
326
|
-
| `disabled` | `boolean` | `false` |
|
|
327
|
-
| `required` | `boolean` | `false` | Required validation
|
|
361
|
+
| Attribute | Type | Default | Description |
|
|
362
|
+
| ---------- | ---------- | ------- | --------------------------- |
|
|
363
|
+
| `value` | `string[]` | `[]` | Selected values |
|
|
364
|
+
| `name` | `string` | `''` | Form field name |
|
|
365
|
+
| `disabled` | `boolean` | `false` | Disables all child controls |
|
|
366
|
+
| `required` | `boolean` | `false` | Required validation |
|
|
328
367
|
|
|
329
368
|
**Events:** `input`, `change`
|
|
330
369
|
|
|
331
370
|
**Slots:** `default` (project `<web-ui-checkbox>` elements)
|
|
332
371
|
|
|
333
|
-
Syncs
|
|
372
|
+
Syncs child checkbox `checked` state. `disabled` supplies inherited effective disabled state without changing a child's own `disabled` property. Listens to child `change` events.
|
|
334
373
|
|
|
335
374
|
#### `<web-ui-radio-group>`
|
|
336
375
|
|
|
@@ -340,13 +379,15 @@ Radio group managing single selection.
|
|
|
340
379
|
| ---------- | --------- | ------- | ---------------------------------------- |
|
|
341
380
|
| `value` | `string` | `''` | Selected radio value |
|
|
342
381
|
| `name` | `string` | `''` | Form field name (propagates to children) |
|
|
343
|
-
| `disabled` | `boolean` | `false` |
|
|
382
|
+
| `disabled` | `boolean` | `false` | Disables all child controls |
|
|
344
383
|
| `required` | `boolean` | `false` | Required validation |
|
|
345
384
|
|
|
346
385
|
**Events:** `input`, `change`
|
|
347
386
|
|
|
348
387
|
**Slots:** `default` (project `<web-ui-radio>` elements)
|
|
349
388
|
|
|
389
|
+
`disabled` supplies inherited effective disabled state without changing a child's own `disabled` property.
|
|
390
|
+
|
|
350
391
|
---
|
|
351
392
|
|
|
352
393
|
### Buttons
|
|
@@ -764,11 +805,11 @@ Not form-associated (child of select, not independent submit).
|
|
|
764
805
|
|
|
765
806
|
Segment trigger for `<web-ui-segmented>`.
|
|
766
807
|
|
|
767
|
-
| Attribute | Type | Default | Description
|
|
768
|
-
| ---------- | --------- | ------- |
|
|
769
|
-
| `value` | `string` | `''` | Segment value
|
|
770
|
-
| `checked` | `boolean` | `false` | Currently selected
|
|
771
|
-
| `disabled` | `boolean` | `false` |
|
|
808
|
+
| Attribute | Type | Default | Description |
|
|
809
|
+
| ---------- | --------- | ------- | ---------------------------------- |
|
|
810
|
+
| `value` | `string` | `''` | Segment value |
|
|
811
|
+
| `checked` | `boolean` | `false` | Currently selected |
|
|
812
|
+
| `disabled` | `boolean` | `false` | Individually disables this trigger |
|
|
772
813
|
|
|
773
814
|
**Events:** `change`
|
|
774
815
|
|
|
@@ -78,7 +78,7 @@ var u = class extends r {
|
|
|
78
78
|
"is-checked": this._checked,
|
|
79
79
|
"is-disabled": this._isDisabled
|
|
80
80
|
})}
|
|
81
|
-
tabindex
|
|
81
|
+
tabindex=${this._isDisabled ? "-1" : "0"}
|
|
82
82
|
role="checkbox"
|
|
83
83
|
aria-checked=${String(this._checked)}
|
|
84
84
|
aria-disabled=${String(this._isDisabled)}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../src/components/checkbox/index.ts"],"sourcesContent":["import { html, LitElement, unsafeCSS } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\nimport { classMap } from 'lit/directives/class-map.js'\n\nimport '@/components/icon'\nimport { heroiconsCheck16Solid } from '@/icons'\n\nimport style from './style.css?inline'\n\n@customElement('web-ui-checkbox')\nexport class WebUiCheckbox extends LitElement {\n static override styles = unsafeCSS(style)\n static formAssociated = true\n\n /** 内部表单关联实例(connectedCallback 中初始化) */\n private _internals?: ElementInternals\n @state() private _formDisabled = false\n @state() private _groupDisabled = false\n\n /** 内部 checked 状态,通过 getter/setter 暴露为公共 API */\n @state() private _checked = false\n\n get checked(): boolean {\n return this._checked\n }\n\n set checked(v: boolean) {\n const old = this._checked\n this._checked = v\n this._syncFormValue()\n this.requestUpdate('checked', old)\n }\n\n @property({ type: String }) value = ''\n @property({ type: String, reflect: true }) name = ''\n @property({ type: Boolean, reflect: true }) disabled = false\n @property({ type: Boolean, reflect: true }) required = false\n\n private get _isDisabled(): boolean {\n return this.disabled || this._formDisabled || this._groupDisabled\n }\n\n private get _isManagedByGroup(): boolean {\n return this.closest('web-ui-checkbox-group') !== null\n }\n\n setGroupDisabled(disabled: boolean) {\n this._groupDisabled = disabled\n }\n\n override connectedCallback() {\n super.connectedCallback()\n if (this._internals) return\n this._internals = this.attachInternals()\n if (this.hasAttribute('checked')) {\n this._checked = true\n }\n this._syncFormValue()\n }\n\n formResetCallback() {\n this.checked = this.hasAttribute('checked')\n }\n\n formDisabledCallback(disabled: boolean) {\n this._formDisabled = disabled\n }\n\n override updated() {\n this._syncFormValue()\n this._syncValidity()\n }\n\n private _syncFormValue() {\n this._internals?.setFormValue?.(!this._isManagedByGroup && this._checked ? this.value || 'on' : null)\n }\n\n private _syncValidity() {\n if (!this._internals || typeof this._internals.setValidity !== 'function') return\n if (this._isDisabled || this._isManagedByGroup || !this.required || this._checked) {\n this._internals.setValidity({})\n return\n }\n this._internals.setValidity({ valueMissing: true }, '请选择此项')\n }\n\n /** 用户点击切换 */\n private handleClick() {\n if (this._isDisabled) return\n const old = this._checked\n this._checked = !old\n this._syncFormValue()\n this.requestUpdate('checked', old)\n this.dispatchEvent(new Event('input', { bubbles: true, composed: true }))\n this.dispatchEvent(new Event('change', { bubbles: true, composed: true }))\n }\n\n private handleKeyDown(e: KeyboardEvent) {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n this.handleClick()\n }\n }\n\n override render() {\n const cls = {\n 'wui-checkbox': true,\n 'is-checked': this._checked,\n 'is-disabled': this._isDisabled\n }\n\n return html`\n <label\n class=${classMap(cls)}\n tabindex
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../src/components/checkbox/index.ts"],"sourcesContent":["import { html, LitElement, unsafeCSS } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\nimport { classMap } from 'lit/directives/class-map.js'\n\nimport '@/components/icon'\nimport { heroiconsCheck16Solid } from '@/icons'\n\nimport style from './style.css?inline'\n\n@customElement('web-ui-checkbox')\nexport class WebUiCheckbox extends LitElement {\n static override styles = unsafeCSS(style)\n static formAssociated = true\n\n /** 内部表单关联实例(connectedCallback 中初始化) */\n private _internals?: ElementInternals\n @state() private _formDisabled = false\n @state() private _groupDisabled = false\n\n /** 内部 checked 状态,通过 getter/setter 暴露为公共 API */\n @state() private _checked = false\n\n get checked(): boolean {\n return this._checked\n }\n\n set checked(v: boolean) {\n const old = this._checked\n this._checked = v\n this._syncFormValue()\n this.requestUpdate('checked', old)\n }\n\n @property({ type: String }) value = ''\n @property({ type: String, reflect: true }) name = ''\n @property({ type: Boolean, reflect: true }) disabled = false\n @property({ type: Boolean, reflect: true }) required = false\n\n private get _isDisabled(): boolean {\n return this.disabled || this._formDisabled || this._groupDisabled\n }\n\n private get _isManagedByGroup(): boolean {\n return this.closest('web-ui-checkbox-group') !== null\n }\n\n setGroupDisabled(disabled: boolean) {\n this._groupDisabled = disabled\n }\n\n override connectedCallback() {\n super.connectedCallback()\n if (this._internals) return\n this._internals = this.attachInternals()\n if (this.hasAttribute('checked')) {\n this._checked = true\n }\n this._syncFormValue()\n }\n\n formResetCallback() {\n this.checked = this.hasAttribute('checked')\n }\n\n formDisabledCallback(disabled: boolean) {\n this._formDisabled = disabled\n }\n\n override updated() {\n this._syncFormValue()\n this._syncValidity()\n }\n\n private _syncFormValue() {\n this._internals?.setFormValue?.(!this._isManagedByGroup && this._checked ? this.value || 'on' : null)\n }\n\n private _syncValidity() {\n if (!this._internals || typeof this._internals.setValidity !== 'function') return\n if (this._isDisabled || this._isManagedByGroup || !this.required || this._checked) {\n this._internals.setValidity({})\n return\n }\n this._internals.setValidity({ valueMissing: true }, '请选择此项')\n }\n\n /** 用户点击切换 */\n private handleClick() {\n if (this._isDisabled) return\n const old = this._checked\n this._checked = !old\n this._syncFormValue()\n this.requestUpdate('checked', old)\n this.dispatchEvent(new Event('input', { bubbles: true, composed: true }))\n this.dispatchEvent(new Event('change', { bubbles: true, composed: true }))\n }\n\n private handleKeyDown(e: KeyboardEvent) {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n this.handleClick()\n }\n }\n\n override render() {\n const cls = {\n 'wui-checkbox': true,\n 'is-checked': this._checked,\n 'is-disabled': this._isDisabled\n }\n\n return html`\n <label\n class=${classMap(cls)}\n tabindex=${this._isDisabled ? '-1' : '0'}\n role=\"checkbox\"\n aria-checked=${String(this._checked)}\n aria-disabled=${String(this._isDisabled)}\n @click=${this.handleClick}\n @keydown=${this.handleKeyDown}\n >\n <span class=\"wui-checkbox-box\">\n <span class=\"wui-checkbox-icon\"\n ><web-ui-icon .icon=${heroiconsCheck16Solid} size=\"18\" color=\"#fff\"></web-ui-icon\n ></span>\n </span>\n <span class=\"wui-checkbox-label\"><slot></slot></span>\n </label>\n `\n }\n\n declare readonly $events: {\n input: Event\n change: Event\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'web-ui-checkbox': WebUiCheckbox\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
//#region src/components/checkbox/style.css?inline
|
|
2
|
-
var e = "*,:before,:after{box-sizing:border-box}:host{cursor:pointer;display:inline-block}:host([disabled]){cursor:not-allowed
|
|
2
|
+
var e = "*,:before,:after{box-sizing:border-box}:host{cursor:pointer;display:inline-block}:host([disabled]){cursor:not-allowed}.wui-checkbox{cursor:pointer;-webkit-user-select:none;user-select:none;font-size:var(--wui-font-size,14px);color:var(--wui-color-text,#1b1b1b);align-items:center;gap:10px;line-height:1;display:inline-flex}.wui-checkbox:focus-visible{outline:3px solid var(--wui-focus-ring,#08f6);outline-offset:2px;border-radius:2147483647px}.wui-checkbox.is-disabled{cursor:not-allowed;color:var(--wui-color-text-muted,#6a6a6a);opacity:.4}.wui-checkbox-box{background-color:var(--wui-color-surface-raised,#f2f2f7);border-radius:6px;flex-shrink:0;justify-content:center;align-items:center;width:18px;height:18px;transition:background-color .2s,border-color .2s;display:flex}.is-checked .wui-checkbox-box{border-color:var(--wui-color-accent,#08f);background-color:var(--wui-color-accent,#08f)}.wui-checkbox-icon{opacity:0;transition:opacity var(--wui-duration-fast,.16s) ease, transform var(--wui-duration-fast,.16s) var(--wui-ease-out,cubic-bezier(.23, 1, .32, 1));font-size:0;line-height:0;display:block;overflow:hidden;transform:scale(.85)}.is-checked .wui-checkbox-icon{opacity:1;transform:scale(1)}.wui-checkbox-label{pointer-events:none}@media (prefers-reduced-motion:reduce){.wui-checkbox-icon,.is-checked .wui-checkbox-icon{transform:none}}";
|
|
3
3
|
//#endregion
|
|
4
4
|
export { e as default };
|
|
5
5
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"style.js","names":[],"sources":["../../../src/components/checkbox/style.css?inline"],"sourcesContent":["*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\n:host {\n cursor: pointer;\n display: inline-block;\n}\n\n:host([disabled]) {\n cursor: not-allowed;\n
|
|
1
|
+
{"version":3,"file":"style.js","names":[],"sources":["../../../src/components/checkbox/style.css?inline"],"sourcesContent":["*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\n:host {\n cursor: pointer;\n display: inline-block;\n}\n\n:host([disabled]) {\n cursor: not-allowed;\n}\n\n.wui-checkbox {\n cursor: pointer;\n user-select: none;\n\n display: inline-flex;\n gap: 10px;\n align-items: center;\n\n font-size: var(--wui-font-size, 14px);\n line-height: 1;\n color: var(--wui-color-text, #1b1b1b);\n\n &:focus-visible {\n border-radius: calc(infinity * 1px);\n outline: 3px solid var(--wui-focus-ring, rgb(0 136 255 / 0.4));\n outline-offset: 2px;\n }\n}\n\n.wui-checkbox.is-disabled {\n cursor: not-allowed;\n color: var(--wui-color-text-muted, #6a6a6a);\n opacity: 0.4;\n}\n\n.wui-checkbox-box {\n display: flex;\n flex-shrink: 0;\n align-items: center;\n justify-content: center;\n\n width: 18px;\n height: 18px;\n border-radius: 6px;\n\n background-color: var(--wui-color-surface-raised, #f2f2f7);\n\n transition:\n background-color 0.2s ease,\n border-color 0.2s ease;\n}\n\n.is-checked .wui-checkbox-box {\n border-color: var(--wui-color-accent, #08f);\n background-color: var(--wui-color-accent, #08f);\n}\n\n.wui-checkbox-icon {\n transform: scale(0.85);\n\n overflow: hidden;\n display: block;\n\n font-size: 0;\n line-height: 0;\n\n opacity: 0;\n\n transition:\n opacity var(--wui-duration-fast, 160ms) ease,\n transform var(--wui-duration-fast, 160ms) var(--wui-ease-out, cubic-bezier(0.23, 1, 0.32, 1));\n}\n\n.is-checked .wui-checkbox-icon {\n transform: scale(1);\n opacity: 1;\n}\n\n.wui-checkbox-label {\n pointer-events: none;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .wui-checkbox-icon,\n .is-checked .wui-checkbox-icon {\n transform: none;\n }\n}\n"],"mappings":""}
|
|
@@ -74,7 +74,7 @@ var l = class extends n {
|
|
|
74
74
|
"is-checked": this._checked,
|
|
75
75
|
"is-disabled": this._isDisabled
|
|
76
76
|
})}
|
|
77
|
-
tabindex
|
|
77
|
+
tabindex=${this._isDisabled ? "-1" : "0"}
|
|
78
78
|
role="radio"
|
|
79
79
|
aria-checked=${String(this._checked)}
|
|
80
80
|
aria-disabled=${String(this._isDisabled)}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../src/components/radio/index.ts"],"sourcesContent":["import { html, LitElement, unsafeCSS } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\nimport { classMap } from 'lit/directives/class-map.js'\n\nimport style from './style.css?inline'\n\n@customElement('web-ui-radio')\nexport class WebUiRadio extends LitElement {\n static override styles = unsafeCSS(style)\n static formAssociated = true\n\n /** 内部表单关联实例(connectedCallback 中初始化) */\n private _internals?: ElementInternals\n @state() private _formDisabled = false\n @state() private _groupDisabled = false\n\n /** 内部 checked 状态,通过 getter/setter 暴露为公共 API */\n @state() private _checked = false\n\n get checked(): boolean {\n return this._checked\n }\n\n set checked(v: boolean) {\n const old = this._checked\n this._checked = v\n this._syncFormValue()\n this.requestUpdate('checked', old)\n }\n\n @property({ type: String }) value = ''\n @property({ type: String, reflect: true }) name = ''\n @property({ type: Boolean, reflect: true }) disabled = false\n @property({ type: Boolean, reflect: true }) required = false\n\n private get _isDisabled(): boolean {\n return this.disabled || this._formDisabled || this._groupDisabled\n }\n\n private get _isManagedByGroup(): boolean {\n return this.closest('web-ui-radio-group') !== null\n }\n\n setGroupDisabled(disabled: boolean) {\n this._groupDisabled = disabled\n }\n\n override connectedCallback() {\n super.connectedCallback()\n if (this._internals) return\n this._internals = this.attachInternals()\n if (this.hasAttribute('checked')) {\n this._checked = true\n }\n this._syncFormValue()\n }\n\n formResetCallback() {\n this.checked = this.hasAttribute('checked')\n }\n\n formDisabledCallback(disabled: boolean) {\n this._formDisabled = disabled\n }\n\n override updated() {\n this._syncFormValue()\n this._syncValidity()\n }\n\n private _syncFormValue() {\n this._internals?.setFormValue?.(!this._isManagedByGroup && this._checked ? this.value || 'on' : null)\n }\n\n private _syncValidity() {\n if (!this._internals || typeof this._internals.setValidity !== 'function') return\n if (this._isDisabled || this._isManagedByGroup || !this.required || this._checked) {\n this._internals.setValidity({})\n return\n }\n this._internals.setValidity({ valueMissing: true }, '请选择一项')\n }\n\n /** 用户点击选中(已选中时不重复触发) */\n private handleClick() {\n if (this._isDisabled || this._checked) return\n this._checked = true\n this._syncFormValue()\n this.requestUpdate('checked', false)\n this.dispatchEvent(new Event('input', { bubbles: true, composed: true }))\n this.dispatchEvent(new Event('change', { bubbles: true, composed: true }))\n }\n\n private handleKeyDown(e: KeyboardEvent) {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n this.handleClick()\n }\n }\n\n override render() {\n const cls = {\n 'wui-radio': true,\n 'is-checked': this._checked,\n 'is-disabled': this._isDisabled\n }\n\n return html`\n <label\n class=${classMap(cls)}\n tabindex
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../src/components/radio/index.ts"],"sourcesContent":["import { html, LitElement, unsafeCSS } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\nimport { classMap } from 'lit/directives/class-map.js'\n\nimport style from './style.css?inline'\n\n@customElement('web-ui-radio')\nexport class WebUiRadio extends LitElement {\n static override styles = unsafeCSS(style)\n static formAssociated = true\n\n /** 内部表单关联实例(connectedCallback 中初始化) */\n private _internals?: ElementInternals\n @state() private _formDisabled = false\n @state() private _groupDisabled = false\n\n /** 内部 checked 状态,通过 getter/setter 暴露为公共 API */\n @state() private _checked = false\n\n get checked(): boolean {\n return this._checked\n }\n\n set checked(v: boolean) {\n const old = this._checked\n this._checked = v\n this._syncFormValue()\n this.requestUpdate('checked', old)\n }\n\n @property({ type: String }) value = ''\n @property({ type: String, reflect: true }) name = ''\n @property({ type: Boolean, reflect: true }) disabled = false\n @property({ type: Boolean, reflect: true }) required = false\n\n private get _isDisabled(): boolean {\n return this.disabled || this._formDisabled || this._groupDisabled\n }\n\n private get _isManagedByGroup(): boolean {\n return this.closest('web-ui-radio-group') !== null\n }\n\n setGroupDisabled(disabled: boolean) {\n this._groupDisabled = disabled\n }\n\n override connectedCallback() {\n super.connectedCallback()\n if (this._internals) return\n this._internals = this.attachInternals()\n if (this.hasAttribute('checked')) {\n this._checked = true\n }\n this._syncFormValue()\n }\n\n formResetCallback() {\n this.checked = this.hasAttribute('checked')\n }\n\n formDisabledCallback(disabled: boolean) {\n this._formDisabled = disabled\n }\n\n override updated() {\n this._syncFormValue()\n this._syncValidity()\n }\n\n private _syncFormValue() {\n this._internals?.setFormValue?.(!this._isManagedByGroup && this._checked ? this.value || 'on' : null)\n }\n\n private _syncValidity() {\n if (!this._internals || typeof this._internals.setValidity !== 'function') return\n if (this._isDisabled || this._isManagedByGroup || !this.required || this._checked) {\n this._internals.setValidity({})\n return\n }\n this._internals.setValidity({ valueMissing: true }, '请选择一项')\n }\n\n /** 用户点击选中(已选中时不重复触发) */\n private handleClick() {\n if (this._isDisabled || this._checked) return\n this._checked = true\n this._syncFormValue()\n this.requestUpdate('checked', false)\n this.dispatchEvent(new Event('input', { bubbles: true, composed: true }))\n this.dispatchEvent(new Event('change', { bubbles: true, composed: true }))\n }\n\n private handleKeyDown(e: KeyboardEvent) {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n this.handleClick()\n }\n }\n\n override render() {\n const cls = {\n 'wui-radio': true,\n 'is-checked': this._checked,\n 'is-disabled': this._isDisabled\n }\n\n return html`\n <label\n class=${classMap(cls)}\n tabindex=${this._isDisabled ? '-1' : '0'}\n role=\"radio\"\n aria-checked=${String(this._checked)}\n aria-disabled=${String(this._isDisabled)}\n @click=${this.handleClick}\n @keydown=${this.handleKeyDown}\n >\n <span class=\"wui-radio-circle\">\n <span class=\"wui-radio-dot\"></span>\n </span>\n <span class=\"wui-radio-label\"><slot></slot></span>\n </label>\n `\n }\n\n declare readonly $events: {\n input: Event\n change: Event\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'web-ui-radio': WebUiRadio\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
//#region src/components/radio/style.css?inline
|
|
2
|
-
var e = "*,:before,:after{box-sizing:border-box}:host{cursor:pointer;display:inline-block}:host([disabled]){cursor:not-allowed
|
|
2
|
+
var e = "*,:before,:after{box-sizing:border-box}:host{cursor:pointer;display:inline-block}:host([disabled]){cursor:not-allowed}.wui-radio{cursor:pointer;-webkit-user-select:none;user-select:none;font-size:var(--wui-font-size,14px);color:var(--wui-color-text,#1b1b1b);align-items:center;gap:10px;line-height:1;display:inline-flex}.wui-radio:focus-visible{outline:3px solid var(--wui-focus-ring,#08f6);outline-offset:2px;border-radius:2147483647px}.wui-radio.is-disabled{cursor:not-allowed;color:var(--wui-color-text-muted,#6a6a6a);opacity:.4}.wui-radio-circle{background-color:var(--wui-color-surface-raised,#f2f2f7);border-radius:2147483647px;flex-shrink:0;justify-content:center;align-items:center;width:18px;height:18px;transition:background-color .2s,border-color .2s;display:flex}.is-checked .wui-radio-circle{background-color:var(--wui-color-accent,#08f)}.wui-radio-dot{opacity:0;background-color:var(--wui-color-surface,#fff);width:8px;height:8px;transition:opacity var(--wui-duration-fast,.16s) ease, transform var(--wui-duration-fast,.16s) var(--wui-ease-out,cubic-bezier(.23, 1, .32, 1));border-radius:2147483647px;transform:scale(.85);box-shadow:inset 0 -1px 2px #0000001f,inset 0 1px 2px #ffffff80,0 0 4px #0088ff4d}.is-checked .wui-radio-dot{opacity:1;transform:scale(1)}.wui-radio-label{pointer-events:none}@media (prefers-reduced-motion:reduce){.wui-radio-dot,.is-checked .wui-radio-dot{transform:none}}";
|
|
3
3
|
//#endregion
|
|
4
4
|
export { e as default };
|
|
5
5
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"style.js","names":[],"sources":["../../../src/components/radio/style.css?inline"],"sourcesContent":["*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\n:host {\n cursor: pointer;\n display: inline-block;\n}\n\n:host([disabled]) {\n cursor: not-allowed;\n
|
|
1
|
+
{"version":3,"file":"style.js","names":[],"sources":["../../../src/components/radio/style.css?inline"],"sourcesContent":["*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\n:host {\n cursor: pointer;\n display: inline-block;\n}\n\n:host([disabled]) {\n cursor: not-allowed;\n}\n\n.wui-radio {\n cursor: pointer;\n user-select: none;\n\n display: inline-flex;\n gap: 10px;\n align-items: center;\n\n font-size: var(--wui-font-size, 14px);\n line-height: 1;\n color: var(--wui-color-text, #1b1b1b);\n\n &:focus-visible {\n border-radius: calc(infinity * 1px);\n outline: 3px solid var(--wui-focus-ring, rgb(0 136 255 / 0.4));\n outline-offset: 2px;\n }\n}\n\n.wui-radio.is-disabled {\n cursor: not-allowed;\n color: var(--wui-color-text-muted, #6a6a6a);\n opacity: 0.4;\n}\n\n.wui-radio-circle {\n display: flex;\n flex-shrink: 0;\n align-items: center;\n justify-content: center;\n\n width: 18px;\n height: 18px;\n border-radius: calc(infinity * 1px);\n\n background-color: var(--wui-color-surface-raised, #f2f2f7);\n\n transition:\n background-color 0.2s ease,\n border-color 0.2s ease;\n}\n\n.is-checked .wui-radio-circle {\n background-color: var(--wui-color-accent, #08f);\n}\n\n.wui-radio-dot {\n transform: scale(0.85);\n\n width: 8px;\n height: 8px;\n border-radius: calc(infinity * 1px);\n\n opacity: 0;\n background-color: var(--wui-color-surface, #fff);\n box-shadow:\n inset 0 -1px 2px rgb(0 0 0 / 0.12),\n inset 0 1px 2px rgb(255 255 255 / 0.5),\n 0 0 4px rgb(0 136 255 / 0.3);\n\n transition:\n opacity var(--wui-duration-fast, 160ms) ease,\n transform var(--wui-duration-fast, 160ms) var(--wui-ease-out, cubic-bezier(0.23, 1, 0.32, 1));\n}\n\n.is-checked .wui-radio-dot {\n transform: scale(1);\n opacity: 1;\n}\n\n.wui-radio-label {\n pointer-events: none;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .wui-radio-dot,\n .is-checked .wui-radio-dot {\n transform: none;\n }\n}\n"],"mappings":""}
|
|
@@ -7,11 +7,13 @@ export declare class WebUiSegmented extends LitElement {
|
|
|
7
7
|
required: boolean;
|
|
8
8
|
private _internals?;
|
|
9
9
|
private _value;
|
|
10
|
+
private _formDisabled;
|
|
10
11
|
private _initialValue;
|
|
11
12
|
get value(): string;
|
|
12
13
|
set value(v: string);
|
|
13
14
|
private readonly childObserver;
|
|
14
15
|
private _syncPropsToChildren;
|
|
16
|
+
private get _isDisabled();
|
|
15
17
|
private _updateIndicator;
|
|
16
18
|
updated(props: PropertyValues): void;
|
|
17
19
|
connectedCallback(): void;
|
|
@@ -3,10 +3,11 @@ import t from "../../assets/glass.js";
|
|
|
3
3
|
import n from "./style.js";
|
|
4
4
|
import { LitElement as r, html as i, unsafeCSS as a } from "lit";
|
|
5
5
|
import { customElement as o, property as s, state as c } from "lit/decorators.js";
|
|
6
|
+
import { classMap as l } from "lit/directives/class-map.js";
|
|
6
7
|
//#region src/components/segmented/index.ts
|
|
7
|
-
var
|
|
8
|
+
var u = class extends r {
|
|
8
9
|
constructor(...e) {
|
|
9
|
-
super(...e), this.name = "", this.disabled = !1, this.required = !1, this._value = "", this._initialValue = "", this.childObserver = new MutationObserver(() => {
|
|
10
|
+
super(...e), this.name = "", this.disabled = !1, this.required = !1, this._value = "", this._formDisabled = !1, this._initialValue = "", this.childObserver = new MutationObserver(() => {
|
|
10
11
|
this._syncPropsToChildren(), requestAnimationFrame(() => this._updateIndicator());
|
|
11
12
|
});
|
|
12
13
|
}
|
|
@@ -25,9 +26,12 @@ var l = class extends r {
|
|
|
25
26
|
}
|
|
26
27
|
_syncPropsToChildren() {
|
|
27
28
|
this.querySelectorAll("web-ui-segmented-trigger").forEach((e) => {
|
|
28
|
-
e.checked = e.value === this._value, e.
|
|
29
|
+
e.checked = e.value === this._value, e.setGroupDisabled(this._isDisabled);
|
|
29
30
|
});
|
|
30
31
|
}
|
|
32
|
+
get _isDisabled() {
|
|
33
|
+
return this.disabled || this._formDisabled;
|
|
34
|
+
}
|
|
31
35
|
_updateIndicator() {
|
|
32
36
|
let e = this.querySelectorAll("web-ui-segmented-trigger"), t = 0, n = 0;
|
|
33
37
|
e.forEach((e) => {
|
|
@@ -38,7 +42,7 @@ var l = class extends r {
|
|
|
38
42
|
}), this.style.setProperty("--indicator-left", `${t}px`), this.style.setProperty("--indicator-width", `${n}px`);
|
|
39
43
|
}
|
|
40
44
|
updated(e) {
|
|
41
|
-
(e.has("value") || e.has("disabled")) && (this._syncPropsToChildren(), requestAnimationFrame(() => this._updateIndicator()));
|
|
45
|
+
(e.has("value") || e.has("disabled") || e.has("_formDisabled")) && (this._syncPropsToChildren(), requestAnimationFrame(() => this._updateIndicator()));
|
|
42
46
|
}
|
|
43
47
|
connectedCallback() {
|
|
44
48
|
super.connectedCallback(), this._internals = this.attachInternals();
|
|
@@ -52,7 +56,7 @@ var l = class extends r {
|
|
|
52
56
|
super.disconnectedCallback(), this.childObserver.disconnect(), this.removeEventListener("change", this._handleChildChange);
|
|
53
57
|
}
|
|
54
58
|
_handleChildChange(e) {
|
|
55
|
-
if (this.
|
|
59
|
+
if (this._isDisabled) return;
|
|
56
60
|
let t = e.target;
|
|
57
61
|
if (!t.matches?.("web-ui-segmented-trigger")) return;
|
|
58
62
|
let n = t;
|
|
@@ -68,11 +72,14 @@ var l = class extends r {
|
|
|
68
72
|
this.value = this._initialValue;
|
|
69
73
|
}
|
|
70
74
|
formDisabledCallback(e) {
|
|
71
|
-
this.
|
|
75
|
+
this._formDisabled = e;
|
|
72
76
|
}
|
|
73
77
|
render() {
|
|
74
78
|
return i`
|
|
75
|
-
<div class
|
|
79
|
+
<div class=${l({
|
|
80
|
+
"wui-segmented": !0,
|
|
81
|
+
"is-disabled": this._isDisabled
|
|
82
|
+
})}>
|
|
76
83
|
<span class="wui-segmented-indicator wui-glass"></span>
|
|
77
84
|
<slot></slot>
|
|
78
85
|
</div>
|
|
@@ -82,14 +89,14 @@ var l = class extends r {
|
|
|
82
89
|
e([s({
|
|
83
90
|
type: String,
|
|
84
91
|
reflect: !0
|
|
85
|
-
})],
|
|
92
|
+
})], u.prototype, "name", void 0), e([s({
|
|
86
93
|
type: Boolean,
|
|
87
94
|
reflect: !0
|
|
88
|
-
})],
|
|
95
|
+
})], u.prototype, "disabled", void 0), e([s({
|
|
89
96
|
type: Boolean,
|
|
90
97
|
reflect: !0
|
|
91
|
-
})],
|
|
98
|
+
})], u.prototype, "required", void 0), e([c()], u.prototype, "_value", void 0), e([c()], u.prototype, "_formDisabled", void 0), u = e([o("web-ui-segmented")], u);
|
|
92
99
|
//#endregion
|
|
93
|
-
export {
|
|
100
|
+
export { u as WebUiSegmented };
|
|
94
101
|
|
|
95
102
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../src/components/segmented/index.ts"],"sourcesContent":["import { html, LitElement, type PropertyValues, unsafeCSS } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\n\nimport glass from '@/assets/glass.css?inline'\n\nimport type { WebUiSegmentedTrigger } from '../segmented-trigger'\n\nimport style from './style.css?inline'\n\n@customElement('web-ui-segmented')\nexport class WebUiSegmented extends LitElement {\n static override styles = [unsafeCSS(glass), unsafeCSS(style)]\n static formAssociated = true\n\n @property({ type: String, reflect: true }) name = ''\n @property({ type: Boolean, reflect: true }) disabled = false\n @property({ type: Boolean, reflect: true }) required = false\n\n private _internals?: ElementInternals\n @state() private _value = ''\n private _initialValue = ''\n\n get value(): string {\n return this._value\n }\n\n set value(v: string) {\n const old = this._value\n this._value = v\n this._internals?.setFormValue?.(v)\n this.requestUpdate('value', old)\n }\n\n private readonly childObserver = new MutationObserver(() => {\n this._syncPropsToChildren()\n requestAnimationFrame(() => this._updateIndicator())\n })\n\n private _syncPropsToChildren() {\n this.querySelectorAll<WebUiSegmentedTrigger>('web-ui-segmented-trigger').forEach(trigger => {\n trigger.checked = trigger.value === this._value\n trigger.
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../src/components/segmented/index.ts"],"sourcesContent":["import { html, LitElement, type PropertyValues, unsafeCSS } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\nimport { classMap } from 'lit/directives/class-map.js'\n\nimport glass from '@/assets/glass.css?inline'\n\nimport type { WebUiSegmentedTrigger } from '../segmented-trigger'\n\nimport style from './style.css?inline'\n\n@customElement('web-ui-segmented')\nexport class WebUiSegmented extends LitElement {\n static override styles = [unsafeCSS(glass), unsafeCSS(style)]\n static formAssociated = true\n\n @property({ type: String, reflect: true }) name = ''\n @property({ type: Boolean, reflect: true }) disabled = false\n @property({ type: Boolean, reflect: true }) required = false\n\n private _internals?: ElementInternals\n @state() private _value = ''\n @state() private _formDisabled = false\n private _initialValue = ''\n\n get value(): string {\n return this._value\n }\n\n set value(v: string) {\n const old = this._value\n this._value = v\n this._internals?.setFormValue?.(v)\n this.requestUpdate('value', old)\n }\n\n private readonly childObserver = new MutationObserver(() => {\n this._syncPropsToChildren()\n requestAnimationFrame(() => this._updateIndicator())\n })\n\n private _syncPropsToChildren() {\n this.querySelectorAll<WebUiSegmentedTrigger>('web-ui-segmented-trigger').forEach(trigger => {\n trigger.checked = trigger.value === this._value\n trigger.setGroupDisabled(this._isDisabled)\n })\n }\n\n private get _isDisabled(): boolean {\n return this.disabled || this._formDisabled\n }\n\n private _updateIndicator() {\n const triggers = this.querySelectorAll<WebUiSegmentedTrigger>('web-ui-segmented-trigger')\n let left = 0\n let width = 0\n\n triggers.forEach(trigger => {\n if (trigger.value === this._value) {\n const triggerRect = trigger.getBoundingClientRect()\n const groupRect = this.getBoundingClientRect()\n left = triggerRect.left - groupRect.left\n width = triggerRect.width\n }\n })\n\n this.style.setProperty('--indicator-left', `${left}px`)\n this.style.setProperty('--indicator-width', `${width}px`)\n }\n\n override updated(props: PropertyValues) {\n if (props.has('value') || props.has('disabled') || props.has('_formDisabled')) {\n this._syncPropsToChildren()\n requestAnimationFrame(() => this._updateIndicator())\n }\n }\n\n override connectedCallback() {\n super.connectedCallback()\n this._internals = this.attachInternals()\n\n // 仅当属性在连接前未被 property setter 设值时,才从 attribute 读取初始值\n const attrValue = this.getAttribute('value')\n if (attrValue !== null && this._value === '') {\n this._value = attrValue\n }\n this._initialValue = attrValue ?? ''\n this._internals?.setFormValue?.(this._value)\n\n this.childObserver.observe(this, { childList: true })\n this.addEventListener('change', this._handleChildChange)\n }\n\n override firstUpdated() {\n this._syncPropsToChildren()\n requestAnimationFrame(() => this._updateIndicator())\n }\n\n override disconnectedCallback() {\n super.disconnectedCallback()\n this.childObserver.disconnect()\n this.removeEventListener('change', this._handleChildChange)\n }\n\n private _handleChildChange(e: Event) {\n if (this._isDisabled) return\n const target = e.target as HTMLElement\n if (!target.matches?.('web-ui-segmented-trigger')) return\n const trigger = target as WebUiSegmentedTrigger\n if (trigger.value === this._value) return\n\n this.value = trigger.value\n this.dispatchEvent(new Event('input', { bubbles: true, composed: true }))\n this.dispatchEvent(new Event('change', { bubbles: true, composed: true }))\n }\n\n formResetCallback() {\n this.value = this._initialValue\n }\n\n formDisabledCallback(disabled: boolean) {\n this._formDisabled = disabled\n }\n\n override render() {\n return html`\n <div class=${classMap({ 'wui-segmented': true, 'is-disabled': this._isDisabled })}>\n <span class=\"wui-segmented-indicator wui-glass\"></span>\n <slot></slot>\n </div>\n `\n }\n\n declare readonly $events: {\n input: Event\n change: Event\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'web-ui-segmented': WebUiSegmented\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
//#region src/components/segmented/style.css?inline
|
|
2
|
-
var e = "*,:before,:after{box-sizing:border-box}:host{-webkit-user-select:none;user-select:none;display:inline-block}.wui-segmented{background-color:var(--wui-color-surface-raised-mid,#dfdfdf);border-radius:2147483647px;align-items:stretch;padding:4px;display:inline-flex;position:relative}
|
|
2
|
+
var e = "*,:before,:after{box-sizing:border-box}:host{-webkit-user-select:none;user-select:none;display:inline-block}.wui-segmented{background-color:var(--wui-color-surface-raised-mid,#dfdfdf);border-radius:2147483647px;align-items:stretch;padding:4px;display:inline-flex;position:relative}.wui-segmented.is-disabled{cursor:not-allowed;opacity:.4}.wui-segmented.is-disabled .wui-segmented-trigger.is-disabled{opacity:1}.wui-segmented-indicator{z-index:0;top:3px;bottom:3px;left:var(--indicator-left,0);width:var(--indicator-width,0);background-color:var(--wui-color-surface-glass,#fafafa8c);transition:left var(--wui-duration-fast,.16s) var(--wui-ease-standard,cubic-bezier(.77, 0, .175, 1)), width var(--wui-duration-fast,.16s) var(--wui-ease-standard,cubic-bezier(.77, 0, .175, 1));border-radius:2147483647px;position:absolute}";
|
|
3
3
|
//#endregion
|
|
4
4
|
export { e as default };
|
|
5
5
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"style.js","names":[],"sources":["../../../src/components/segmented/style.css?inline"],"sourcesContent":["*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\n:host {\n user-select: none;\n display: inline-block;\n}\n\n.wui-segmented {\n position: relative;\n\n display: inline-flex;\n align-items: stretch;\n\n padding: 4px;\n border-radius: calc(infinity * 1px);\n\n background-color: var(--wui-color-surface-raised-mid, #dfdfdf);\n}\n\n
|
|
1
|
+
{"version":3,"file":"style.js","names":[],"sources":["../../../src/components/segmented/style.css?inline"],"sourcesContent":["*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\n:host {\n user-select: none;\n display: inline-block;\n}\n\n.wui-segmented {\n position: relative;\n\n display: inline-flex;\n align-items: stretch;\n\n padding: 4px;\n border-radius: calc(infinity * 1px);\n\n background-color: var(--wui-color-surface-raised-mid, #dfdfdf);\n}\n\n.wui-segmented.is-disabled {\n cursor: not-allowed;\n opacity: 0.4;\n}\n\n.wui-segmented.is-disabled .wui-segmented-trigger.is-disabled {\n opacity: 1;\n}\n\n.wui-segmented-indicator {\n position: absolute;\n z-index: 0;\n top: 3px;\n bottom: 3px;\n left: var(--indicator-left, 0);\n\n width: var(--indicator-width, 0);\n border-radius: calc(infinity * 1px);\n\n background-color: var(--wui-color-surface-glass, rgb(250 250 250 / 0.55));\n\n transition:\n left var(--wui-duration-fast, 160ms) var(--wui-ease-standard, cubic-bezier(0.77, 0, 0.175, 1)),\n width var(--wui-duration-fast, 160ms) var(--wui-ease-standard, cubic-bezier(0.77, 0, 0.175, 1));\n}\n"],"mappings":""}
|
|
@@ -4,6 +4,9 @@ export declare class WebUiSegmentedTrigger extends LitElement {
|
|
|
4
4
|
value: string;
|
|
5
5
|
checked: boolean;
|
|
6
6
|
disabled: boolean;
|
|
7
|
+
private _groupDisabled;
|
|
8
|
+
private get _isDisabled();
|
|
9
|
+
setGroupDisabled(disabled: boolean): void;
|
|
7
10
|
private handleClick;
|
|
8
11
|
private handleKeyDown;
|
|
9
12
|
render(): import('lit').TemplateResult<1>;
|
|
@@ -1,18 +1,24 @@
|
|
|
1
1
|
import e from "../../_virtual/_@oxc-project_runtime@0.140.0/helpers/esm/decorate.js";
|
|
2
2
|
import t from "./style.js";
|
|
3
3
|
import { LitElement as n, html as r, unsafeCSS as i } from "lit";
|
|
4
|
-
import { customElement as a, property as o } from "lit/decorators.js";
|
|
5
|
-
import { classMap as
|
|
4
|
+
import { customElement as a, property as o, state as s } from "lit/decorators.js";
|
|
5
|
+
import { classMap as c } from "lit/directives/class-map.js";
|
|
6
6
|
//#region src/components/segmented-trigger/index.ts
|
|
7
|
-
var
|
|
7
|
+
var l = class extends n {
|
|
8
8
|
constructor(...e) {
|
|
9
|
-
super(...e), this.value = "", this.checked = !1, this.disabled = !1;
|
|
9
|
+
super(...e), this.value = "", this.checked = !1, this.disabled = !1, this._groupDisabled = !1;
|
|
10
10
|
}
|
|
11
11
|
static {
|
|
12
12
|
this.styles = i(t);
|
|
13
13
|
}
|
|
14
|
+
get _isDisabled() {
|
|
15
|
+
return this.disabled || this._groupDisabled;
|
|
16
|
+
}
|
|
17
|
+
setGroupDisabled(e) {
|
|
18
|
+
this._groupDisabled = e;
|
|
19
|
+
}
|
|
14
20
|
handleClick() {
|
|
15
|
-
this.
|
|
21
|
+
this._isDisabled || this.checked || (this.checked = !0, this.dispatchEvent(new Event("change", {
|
|
16
22
|
bubbles: !0,
|
|
17
23
|
composed: !0
|
|
18
24
|
})));
|
|
@@ -23,14 +29,15 @@ var c = class extends n {
|
|
|
23
29
|
render() {
|
|
24
30
|
return r`
|
|
25
31
|
<div
|
|
26
|
-
class=${
|
|
32
|
+
class=${c({
|
|
27
33
|
"wui-segmented-trigger": !0,
|
|
28
34
|
"is-checked": this.checked,
|
|
29
|
-
"is-disabled": this.
|
|
35
|
+
"is-disabled": this._isDisabled
|
|
30
36
|
})}
|
|
31
|
-
tabindex
|
|
37
|
+
tabindex=${this._isDisabled ? "-1" : "0"}
|
|
32
38
|
role="option"
|
|
33
39
|
.ariaSelected=${String(this.checked)}
|
|
40
|
+
aria-disabled=${String(this._isDisabled)}
|
|
34
41
|
@click=${this.handleClick}
|
|
35
42
|
@keydown=${this.handleKeyDown}
|
|
36
43
|
>
|
|
@@ -39,14 +46,14 @@ var c = class extends n {
|
|
|
39
46
|
`;
|
|
40
47
|
}
|
|
41
48
|
};
|
|
42
|
-
e([o({ type: String })],
|
|
49
|
+
e([o({ type: String })], l.prototype, "value", void 0), e([o({
|
|
43
50
|
type: Boolean,
|
|
44
51
|
reflect: !0
|
|
45
|
-
})],
|
|
52
|
+
})], l.prototype, "checked", void 0), e([o({
|
|
46
53
|
type: Boolean,
|
|
47
54
|
reflect: !0
|
|
48
|
-
})],
|
|
55
|
+
})], l.prototype, "disabled", void 0), e([s()], l.prototype, "_groupDisabled", void 0), l = e([a("web-ui-segmented-trigger")], l);
|
|
49
56
|
//#endregion
|
|
50
|
-
export {
|
|
57
|
+
export { l as WebUiSegmentedTrigger };
|
|
51
58
|
|
|
52
59
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../src/components/segmented-trigger/index.ts"],"sourcesContent":["import { html, LitElement, unsafeCSS } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\nimport { classMap } from 'lit/directives/class-map.js'\n\nimport style from './style.css?inline'\n\n@customElement('web-ui-segmented-trigger')\nexport class WebUiSegmentedTrigger extends LitElement {\n static override styles = unsafeCSS(style)\n\n @property({ type: String }) value = ''\n @property({ type: Boolean, reflect: true }) checked = false\n @property({ type: Boolean, reflect: true }) disabled = false\n\n private handleClick() {\n if (this.
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../src/components/segmented-trigger/index.ts"],"sourcesContent":["import { html, LitElement, unsafeCSS } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\nimport { classMap } from 'lit/directives/class-map.js'\n\nimport style from './style.css?inline'\n\n@customElement('web-ui-segmented-trigger')\nexport class WebUiSegmentedTrigger extends LitElement {\n static override styles = unsafeCSS(style)\n\n @property({ type: String }) value = ''\n @property({ type: Boolean, reflect: true }) checked = false\n @property({ type: Boolean, reflect: true }) disabled = false\n @state() private _groupDisabled = false\n\n private get _isDisabled(): boolean {\n return this.disabled || this._groupDisabled\n }\n\n setGroupDisabled(disabled: boolean) {\n this._groupDisabled = disabled\n }\n\n private handleClick() {\n if (this._isDisabled || this.checked) return\n this.checked = true\n this.dispatchEvent(new Event('change', { bubbles: true, composed: true }))\n }\n\n private handleKeyDown(e: KeyboardEvent) {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n this.handleClick()\n }\n }\n\n override render() {\n const cls = {\n 'wui-segmented-trigger': true,\n 'is-checked': this.checked,\n 'is-disabled': this._isDisabled\n }\n\n return html`\n <div\n class=${classMap(cls)}\n tabindex=${this._isDisabled ? '-1' : '0'}\n role=\"option\"\n .ariaSelected=${String(this.checked)}\n aria-disabled=${String(this._isDisabled)}\n @click=${this.handleClick}\n @keydown=${this.handleKeyDown}\n >\n <slot></slot>\n </div>\n `\n }\n\n declare readonly $events: {\n change: Event\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'web-ui-segmented-trigger': WebUiSegmentedTrigger\n }\n}\n"],"mappings":";;;;;;AAOO,IAAM,IAAN,cAAoC,EAAW;;EAMlB,aAHE,KAAA,QAAA,IACkB,KAAA,UAAA,IACC,KAAA,WAAA,IACrB,KAAA,iBAAA;;;EALT,KAAA,SAAA,EAAU,CAAK;;CAOxC,IAAY,cAAuB;EACjC,OAAO,KAAK,YAAY,KAAK;CAC/B;CAEA,iBAAiB,GAAmB;EAClC,KAAK,iBAAiB;CACxB;CAEA,cAAsB;EAChB,KAAK,eAAe,KAAK,YAC7B,KAAK,UAAU,IACf,KAAK,cAAc,IAAI,MAAM,UAAU;GAAE,SAAS;GAAM,UAAU;EAAK,CAAC,CAAC;CAC3E;CAEA,cAAsB,GAAkB;EACtC,CAAI,EAAE,QAAQ,WAAW,EAAE,QAAQ,SACjC,EAAE,eAAe,GACjB,KAAK,YAAY;CAErB;CAEA,SAAkB;EAOhB,OAAO,CAAI;;gBAEC,EAAS;GAPnB,yBAAyB;GACzB,cAAc,KAAK;GACnB,eAAe,KAAK;EAKD,CAAG,EAAE;mBACX,KAAK,cAAc,OAAO,IAAI;;wBAEzB,OAAO,KAAK,OAAO,EAAE;wBACrB,OAAO,KAAK,WAAW,EAAE;iBAChC,KAAK,YAAY;mBACf,KAAK,cAAc;;;;;CAKpC;AAKF;AAnDG,EAAA,CAAA,EAAS,EAAE,MAAM,OAAO,CAAC,CAAA,GAAA,EAAA,WAAA,SAAA,KAAA,CAAA,GACzB,EAAA,CAAA,EAAS;CAAE,MAAM;CAAS,SAAS;AAAK,CAAC,CAAA,GAAA,EAAA,WAAA,WAAA,KAAA,CAAA,GACzC,EAAA,CAAA,EAAS;CAAE,MAAM;CAAS,SAAS;AAAK,CAAC,CAAA,GAAA,EAAA,WAAA,YAAA,KAAA,CAAA,GACzC,EAAA,CAAA,EAAM,CAAA,GAAA,EAAA,WAAA,kBAAA,KAAA,CAAA,GAPR,IAAA,EAAA,CAAA,EAAc,0BAA0B,CAAA,GAAA,CAAA"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
//#region src/components/segmented-trigger/style.css?inline
|
|
2
|
-
var e = "*,:before,:after{box-sizing:border-box}:host{display:inline-block}:host([disabled]){cursor:not-allowed}.wui-segmented-trigger{cursor:pointer;-webkit-user-select:none;user-select:none;z-index:1;height:34px;font-size:var(--wui-font-size,14px);color:var(--wui-color-text-muted,#6a6a6a);white-space:nowrap;border-radius:2147483647px;justify-content:center;align-items:center;padding:0 16px;line-height:1;transition:color .2s;display:inline-flex;position:relative}.wui-segmented-trigger:focus-visible{outline:3px solid var(--wui-focus-ring,#08f6);outline-offset:2px}.wui-segmented-trigger.is-checked{color:var(--wui-color-text,#1a1a1a)}
|
|
2
|
+
var e = "*,:before,:after{box-sizing:border-box}:host{display:inline-block}:host([disabled]){cursor:not-allowed}.wui-segmented-trigger{cursor:pointer;-webkit-user-select:none;user-select:none;z-index:1;height:34px;font-size:var(--wui-font-size,14px);color:var(--wui-color-text-muted,#6a6a6a);white-space:nowrap;border-radius:2147483647px;justify-content:center;align-items:center;padding:0 16px;line-height:1;transition:color .2s;display:inline-flex;position:relative}.wui-segmented-trigger:focus-visible{outline:3px solid var(--wui-focus-ring,#08f6);outline-offset:2px}.wui-segmented-trigger.is-checked{color:var(--wui-color-text,#1a1a1a)}.wui-segmented-trigger.is-disabled{cursor:not-allowed;opacity:.4}";
|
|
3
3
|
//#endregion
|
|
4
4
|
export { e as default };
|
|
5
5
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"style.js","names":[],"sources":["../../../src/components/segmented-trigger/style.css?inline"],"sourcesContent":["*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\n:host {\n display: inline-block;\n}\n\n:host([disabled]) {\n cursor: not-allowed;\n}\n\n.wui-segmented-trigger {\n cursor: pointer;\n user-select: none;\n\n position: relative;\n z-index: 1;\n\n display: inline-flex;\n align-items: center;\n justify-content: center;\n\n height: 34px;\n padding: 0 16px;\n border-radius: calc(infinity * 1px);\n\n font-size: var(--wui-font-size, 14px);\n line-height: 1;\n color: var(--wui-color-text-muted, #6a6a6a);\n white-space: nowrap;\n\n transition: color 0.2s ease;\n\n &:focus-visible {\n outline: 3px solid var(--wui-focus-ring, rgb(0 136 255 / 0.4));\n outline-offset: 2px;\n }\n\n &.is-checked {\n color: var(--wui-color-text, #1a1a1a);\n }\n}\n\n
|
|
1
|
+
{"version":3,"file":"style.js","names":[],"sources":["../../../src/components/segmented-trigger/style.css?inline"],"sourcesContent":["*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\n:host {\n display: inline-block;\n}\n\n:host([disabled]) {\n cursor: not-allowed;\n}\n\n.wui-segmented-trigger {\n cursor: pointer;\n user-select: none;\n\n position: relative;\n z-index: 1;\n\n display: inline-flex;\n align-items: center;\n justify-content: center;\n\n height: 34px;\n padding: 0 16px;\n border-radius: calc(infinity * 1px);\n\n font-size: var(--wui-font-size, 14px);\n line-height: 1;\n color: var(--wui-color-text-muted, #6a6a6a);\n white-space: nowrap;\n\n transition: color 0.2s ease;\n\n &:focus-visible {\n outline: 3px solid var(--wui-focus-ring, rgb(0 136 255 / 0.4));\n outline-offset: 2px;\n }\n\n &.is-checked {\n color: var(--wui-color-text, #1a1a1a);\n }\n}\n\n.wui-segmented-trigger.is-disabled {\n cursor: not-allowed;\n opacity: 0.4;\n}\n"],"mappings":""}
|
package/dist/types/react.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { DetailedHTMLProps, HTMLAttributes } from 'react';
|
|
2
|
-
import { WebUiAvatar, WebUiBackTop, WebUiBadge, WebUiButton, WebUiButtonGroup, WebUiCheckbox, WebUiCheckboxGroup, WebUiContextMenu, WebUiDialog, WebUiDrawer, WebUiEmpty, WebUiDropdownDivider, WebUiDropdownHeader, WebUiDropdownItem, WebUiDropdown, WebUiIcon, WebUiInput, WebUiInputNumber, WebUiLayout, WebUiOption, WebUiPopover, WebUiRadio, WebUiRadioGroup, WebUiSegmented, WebUiSegmentedTrigger, WebUiSelect, WebUiSlider, WebUiSpinner, WebUiTextarea, WebUiTheme, WebUiToast, WebUiSwitch, WebUiTooltip } from '../components';
|
|
3
|
-
import {
|
|
4
|
-
export type LitReactWrapper<T> = T extends {
|
|
2
|
+
import { WebUiAvatar, WebUiBackTop, WebUiBadge, WebUiButton, WebUiButtonGroup, WebUiCheckbox, WebUiCheckboxGroup, WebUiContextMenu, WebUiDialog, WebUiDrawer, WebUiEmpty, WebUiDropdownDivider, WebUiDropdownHeader, WebUiDropdownItem, WebUiDropdown, WebUiIcon, WebUiInput, WebUiInputNumber, WebUiLayout, WebUiOption, WebUiPopover, WebUiRadio, WebUiRadioGroup, WebUiSegmented, WebUiSegmentedTrigger, WebUiSelect, WebUiSlider, WebUiSpinner, WebUiTextarea, WebUiTheme, WebUiToast, WebUiSwitch, WebUiSvgDrawLines, WebUiTooltip } from '../components';
|
|
3
|
+
import { ExactEventListeners, ExtractProps, OmitLitBase } from './utils';
|
|
4
|
+
export type LitReactWrapper<T extends HTMLElement> = T extends {
|
|
5
5
|
readonly $events: infer E;
|
|
6
|
-
} ? DetailedHTMLProps<ExtractProps<OmitLitBase<T>> &
|
|
6
|
+
} ? DetailedHTMLProps<ExtractProps<OmitLitBase<T>> & ExactEventListeners<E> & HTMLAttributes<T>, T> : DetailedHTMLProps<ExtractProps<OmitLitBase<T>> & HTMLAttributes<T>, T>;
|
|
7
7
|
export interface WebUiComponents {
|
|
8
8
|
'web-ui-avatar': LitReactWrapper<WebUiAvatar>;
|
|
9
9
|
'web-ui-back-top': LitReactWrapper<WebUiBackTop>;
|
|
@@ -26,6 +26,7 @@ export interface WebUiComponents {
|
|
|
26
26
|
'web-ui-select': LitReactWrapper<WebUiSelect>;
|
|
27
27
|
'web-ui-slider': LitReactWrapper<WebUiSlider>;
|
|
28
28
|
'web-ui-spinner': LitReactWrapper<WebUiSpinner>;
|
|
29
|
+
'web-ui-svg-draw-lines': LitReactWrapper<WebUiSvgDrawLines>;
|
|
29
30
|
'web-ui-option': LitReactWrapper<WebUiOption>;
|
|
30
31
|
'web-ui-popover': LitReactWrapper<WebUiPopover>;
|
|
31
32
|
'web-ui-radio': LitReactWrapper<WebUiRadio>;
|
package/dist/types/utils.d.ts
CHANGED
|
@@ -10,17 +10,10 @@ export type ExtractProps<T> = {
|
|
|
10
10
|
};
|
|
11
11
|
export type OmitLitBase<T> = Omit<T, keyof HTMLElement | keyof LitElement>;
|
|
12
12
|
/**
|
|
13
|
-
*
|
|
14
|
-
* '
|
|
15
|
-
* 'input' → 'Input'
|
|
13
|
+
* 将 EventMap 转换为 React 19 Custom Element 的精确事件键。
|
|
14
|
+
* 例如 { 'open-change': CustomEvent<...> } → { 'onopen-change'?: (e: CustomEvent<...>) => void }
|
|
16
15
|
*/
|
|
17
|
-
type
|
|
18
|
-
|
|
19
|
-
* 将 EventMap 转换为 on* 事件监听器类型
|
|
20
|
-
* 例如 { input: Event } → { onInput?: (e: Event) => void }
|
|
21
|
-
* { 'visible-change': CustomEvent<...> } → { onVisibleChange?: (e: CustomEvent<...>) => void }
|
|
22
|
-
*/
|
|
23
|
-
export type EventListeners<T> = {
|
|
24
|
-
[K in keyof T & string as `on${KebabToPascal<K>}`]?: (e: T[K]) => void;
|
|
16
|
+
export type ExactEventListeners<T> = {
|
|
17
|
+
[K in keyof T & string as `on${K}`]?: (e: T[K]) => void;
|
|
25
18
|
};
|
|
26
19
|
export {};
|