@haiyue/ui 0.1.2 → 0.2.2
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/CHANGELOG.md +43 -0
- package/LICENSE +27 -0
- package/README.md +643 -2
- package/dist/adapters/web/controls.d.ts +19 -0
- package/dist/adapters/web/controls.js +307 -0
- package/dist/adapters/web/dom.d.ts +10 -0
- package/dist/adapters/web/dom.js +98 -0
- package/dist/adapters/web/index.d.ts +3 -0
- package/dist/adapters/web/index.js +3 -0
- package/dist/adapters/web/renderer.d.ts +18 -0
- package/dist/adapters/web/renderer.js +553 -0
- package/dist/adapters/web/styles.d.ts +3 -0
- package/dist/adapters/web/styles.js +83 -0
- package/dist/adapters/web/types.d.ts +46 -0
- package/dist/adapters/web/types.js +2 -0
- package/dist/affix.d.ts +35 -0
- package/dist/affix.js +137 -0
- package/dist/badge.d.ts +45 -0
- package/dist/badge.js +168 -0
- package/dist/breadcrumb.d.ts +37 -0
- package/dist/breadcrumb.js +210 -0
- package/dist/button-group.d.ts +12 -0
- package/dist/button-group.js +72 -0
- package/dist/button.d.ts +15 -1
- package/dist/button.js +101 -12
- package/dist/carousel.d.ts +92 -0
- package/dist/carousel.js +509 -0
- package/dist/cascader.d.ts +65 -0
- package/dist/cascader.js +479 -0
- package/dist/collapse.d.ts +68 -0
- package/dist/collapse.js +348 -0
- package/dist/core/actions.d.ts +32 -0
- package/dist/core/actions.js +145 -0
- package/dist/core/data.d.ts +4 -0
- package/dist/core/data.js +27 -0
- package/dist/core/index.d.ts +7 -0
- package/dist/core/index.js +6 -0
- package/dist/core/platform-view.d.ts +17 -0
- package/dist/core/platform-view.js +84 -0
- package/dist/core/selection.d.ts +14 -0
- package/dist/core/selection.js +93 -0
- package/dist/core/text.d.ts +31 -0
- package/dist/core/text.js +154 -0
- package/dist/core/types.d.ts +269 -0
- package/dist/core/types.js +2 -0
- package/dist/core/validation.d.ts +24 -0
- package/dist/core/validation.js +243 -0
- package/dist/date-picker.d.ts +60 -0
- package/dist/date-picker.js +355 -0
- package/dist/dialog.d.ts +4 -0
- package/dist/dialog.js +23 -5
- package/dist/divider.d.ts +33 -0
- package/dist/divider.js +113 -0
- package/dist/draggable.d.ts +78 -0
- package/dist/draggable.js +255 -0
- package/dist/index.d.ts +53 -1
- package/dist/index.js +78 -0
- package/dist/input.d.ts +30 -1
- package/dist/input.js +166 -54
- package/dist/internal/qrcodegen.d.ts +94 -0
- package/dist/internal/qrcodegen.js +856 -0
- package/dist/masonry.d.ts +36 -0
- package/dist/masonry.js +171 -0
- package/dist/modal.d.ts +73 -0
- package/dist/modal.js +361 -0
- package/dist/portable/icons.d.ts +5 -0
- package/dist/portable/icons.js +24 -0
- package/dist/portable/index.d.ts +7 -0
- package/dist/portable/index.js +5 -0
- package/dist/portable/page.d.ts +38 -0
- package/dist/portable/page.js +361 -0
- package/dist/portable/responsive.d.ts +20 -0
- package/dist/portable/responsive.js +15 -0
- package/dist/portable/theme.d.ts +24 -0
- package/dist/portable/theme.js +60 -0
- package/dist/portable/tree.d.ts +10 -0
- package/dist/portable/tree.js +96 -0
- package/dist/qr-code.d.ts +62 -0
- package/dist/qr-code.js +224 -0
- package/dist/range.d.ts +3 -0
- package/dist/range.js +16 -5
- package/dist/rate.d.ts +46 -0
- package/dist/rate.js +193 -0
- package/dist/resizable.d.ts +97 -0
- package/dist/resizable.js +426 -0
- package/dist/skeleton.d.ts +41 -0
- package/dist/skeleton.js +141 -0
- package/dist/steps.d.ts +45 -0
- package/dist/steps.js +203 -0
- package/dist/table.d.ts +106 -0
- package/dist/table.js +689 -0
- package/dist/tabs.d.ts +3 -0
- package/dist/tabs.js +11 -1
- package/dist/tag.d.ts +55 -0
- package/dist/tag.js +225 -0
- package/dist/time-picker.d.ts +62 -0
- package/dist/time-picker.js +298 -0
- package/dist/timeline.d.ts +48 -0
- package/dist/timeline.js +201 -0
- package/dist/toast.d.ts +55 -0
- package/dist/toast.js +224 -0
- package/dist/tour.d.ts +89 -0
- package/dist/tour.js +306 -0
- package/dist/virtual-keyboard.d.ts +95 -0
- package/dist/virtual-keyboard.js +432 -0
- package/dist/virtual-mouse.d.ts +82 -0
- package/dist/virtual-mouse.js +358 -0
- package/dist/watermark.d.ts +44 -0
- package/dist/watermark.js +148 -0
- package/package.json +132 -4
package/README.md
CHANGED
|
@@ -23,10 +23,12 @@ helpers, and registration stays explicit:
|
|
|
23
23
|
|
|
24
24
|
```ts
|
|
25
25
|
import { defineButtonComponents } from '@haiyue/ui/button';
|
|
26
|
+
import { defineButtonGroupComponents } from '@haiyue/ui/button-group';
|
|
26
27
|
import { defineTreeComponents } from '@haiyue/ui/tree';
|
|
27
28
|
import { defineVirtualListComponents } from '@haiyue/ui/virtual-list';
|
|
28
29
|
|
|
29
30
|
defineButtonComponents();
|
|
31
|
+
defineButtonGroupComponents();
|
|
30
32
|
defineTreeComponents();
|
|
31
33
|
defineVirtualListComponents();
|
|
32
34
|
```
|
|
@@ -46,6 +48,275 @@ defineHaiyueUI();
|
|
|
46
48
|
Because `defineHaiyueUI()` references the complete component set, prefer focused subpaths in bundle-sensitive
|
|
47
49
|
product entry points.
|
|
48
50
|
|
|
51
|
+
## Modal
|
|
52
|
+
|
|
53
|
+
Import `defineModalComponents` from `@haiyue/ui/modal` and register once. `HYModal` is also exported by the root
|
|
54
|
+
and included in `defineHaiyueUI()`. It provides default confirmation/cancel actions around a native modal
|
|
55
|
+
`<dialog>`, with top-layer rendering, background inertness, focus containment and return focus through shadow roots.
|
|
56
|
+
The existing Dialog entry remains available for surfaces with application-supplied footer actions.
|
|
57
|
+
|
|
58
|
+
```html
|
|
59
|
+
<hy-modal id="publish" heading="Publish project" width="560" ok-text="Publish">
|
|
60
|
+
<p>Review the project before publishing.</p>
|
|
61
|
+
</hy-modal>
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Call `showModal()` / `close(reason?)`, or set the reflected boolean `open` property/attribute.
|
|
65
|
+
`heading` defaults to “Modal”; the `heading` slot overrides its content and the default slot supplies the body.
|
|
66
|
+
`width` defaults to 520 CSS pixels (240–2000), constrained to the viewport. `centered`, `closable`,
|
|
67
|
+
`mask-closable` / `maskClosable`, `keyboard` (Escape), and `show-footer` / `showFooter` all default to true;
|
|
68
|
+
set their attributes to `"false"` or properties to false to disable them independently.
|
|
69
|
+
`ok-text` / `okText` and `cancel-text` / `cancelText` default to “OK” and “Cancel”.
|
|
70
|
+
Use the `footer` slot for application-owned custom actions, replacing both default buttons.
|
|
71
|
+
|
|
72
|
+
Bubbling/composed events are `modal-open`, `modal-ok`, `modal-cancel` and `modal-close`.
|
|
73
|
+
The cancelable `modal-ok` and `modal-cancel` events carry `{ reason }`. Preventing either event keeps the modal open.
|
|
74
|
+
Close reasons are `ok`, `cancel`, `close-button`, `mask`, `escape` and `programmatic`; `close(reason)` also accepts
|
|
75
|
+
an application-specific string. `modal-close` fires once after an actual close, with `{ reason }`.
|
|
76
|
+
With `controlled`, default user actions only emit requests; the application updates `open` or calls `close()`.
|
|
77
|
+
|
|
78
|
+
```js
|
|
79
|
+
publish.addEventListener('modal-ok', async event => {
|
|
80
|
+
event.preventDefault();
|
|
81
|
+
publish.confirmLoading = true;
|
|
82
|
+
try {
|
|
83
|
+
await saveProject();
|
|
84
|
+
publish.close('ok');
|
|
85
|
+
} finally {
|
|
86
|
+
publish.confirmLoading = false;
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
publish.showModal();
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
`confirm-loading` / `confirmLoading` disables the default actions and user dismissal, shows a spinner and marks the
|
|
93
|
+
surface busy; application `close()` remains available. `confirm-disabled` / `confirmDisabled` only disables confirmation.
|
|
94
|
+
`destroy-on-hidden` / `destroyOnHidden` unmounts light DOM content while closed, retaining the same nodes, values and
|
|
95
|
+
listeners for reopening. It defaults to false. Disconnecting removes modality and scroll locks without emitting a
|
|
96
|
+
close event; a retained `open` attribute reopens on reconnection. Nested modals retain scroll locking until the last closes.
|
|
97
|
+
|
|
98
|
+
Style parts `panel`, `header`, `heading`, `body`, `footer`, `actions`, `ok-button`, `cancel-button`,
|
|
99
|
+
`close-button`, `spinner`. Tokens include `--hy-modal-width`, `--hy-modal-radius`, `--hy-modal-body-padding`,
|
|
100
|
+
`--hy-modal-duration`, `--hy-modal-bg-color`, `--hy-modal-mask-color`, `--hy-modal-mask-blur`, `--hy-modal-shadow-color`,
|
|
101
|
+
`--hy-modal-footer-bg-color` and `--hy-modal-button-radius`; colors inherit semantic theme tokens. Reduced-motion
|
|
102
|
+
preferences suppress the entrance and spinner animations. No sibling component import or automatic registration is needed.
|
|
103
|
+
|
|
104
|
+
## QR Code
|
|
105
|
+
|
|
106
|
+
Import `defineQRCodeComponents` from `@haiyue/ui/qr-code` and call it once. The root registration path also includes
|
|
107
|
+
`<hy-qr-code>`. Values are encoded locally into SVG; no runtime dependency or remote QR generation service is used.
|
|
108
|
+
|
|
109
|
+
```html
|
|
110
|
+
<hy-qr-code value="https://haiyuestudio.github.io/UI/" size="220"
|
|
111
|
+
icon="/brand.svg" icon-size="32" icon-margin="2" aria-label="Open Haiyue UI"></hy-qr-code>
|
|
112
|
+
|
|
113
|
+
<hy-qr-code value="https://haiyuestudio.github.io/UI/">
|
|
114
|
+
<img slot="icon" src="/brand.svg" alt="" />
|
|
115
|
+
</hy-qr-code>
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Set `value` to a URL or text (including UTF-8/Chinese/emoji). `size` defaults to 200 CSS pixels (64–2048).
|
|
119
|
+
`margin` is the quiet zone in modules (default/minimum 4, maximum 16).
|
|
120
|
+
`error-correction-level` / `errorCorrectionLevel` accepts `L`, `M`, `Q`, or `H`. Without an explicit level,
|
|
121
|
+
it defaults to `H` with an icon and `M` otherwise. An explicit level applies with or without an icon.
|
|
122
|
+
An `icon` image URL or content in the `icon` slot adds a center icon; the slot takes precedence over the URL.
|
|
123
|
+
`icon-size` / `iconSize` requests the content size in pixels (default 32), while `icon-margin` / `iconMargin`
|
|
124
|
+
sets its backing padding (default 2). The complete overlay is capped at 20% of the QR matrix width, including padding,
|
|
125
|
+
and scales with responsive sizing. Icon content is decorative and inert. A failed image leaves the plain QR visible.
|
|
126
|
+
|
|
127
|
+
`color` and `background-color` / `backgroundColor` customize the QR colors. The inherited tokens
|
|
128
|
+
`--hy-qr-code-color` and `--hy-qr-code-background-color` default to dark modules on white for both themes.
|
|
129
|
+
Other styling hooks are `--hy-qr-code-icon-radius`, `--hy-qr-code-radius` and parts `frame`, `code`,
|
|
130
|
+
`background`, `modules`, `icon`, `icon-image`, `message`. Keep sufficient contrast and verify your final payload,
|
|
131
|
+
size, colors and icon with the intended scanner; arbitrary custom styling can affect readability.
|
|
132
|
+
|
|
133
|
+
The read-only `status` is `empty`, `ready`, or `error`. Empty values and over-capacity payloads clear the previous code.
|
|
134
|
+
Bubbling, composed events are `qr-render` with `{ value, version, moduleCount, errorCorrectionLevel }` after encoding,
|
|
135
|
+
`qr-error` with `{ message }` on encoding failure, and `qr-icon-error` with `{ src }` on image failure.
|
|
136
|
+
SVG is decorative beneath a labelled image role; set `aria-label` to describe the QR's purpose.
|
|
137
|
+
|
|
138
|
+
The internal encoder is vendored from [Project Nayuki](https://www.nayuki.io/page/qr-code-generator-library),
|
|
139
|
+
upstream Git blob `c4191ac0b5f8a24d87fd9340ceaa2d3b07d0231a`, with its MIT notice retained in source and `LICENSE`.
|
|
140
|
+
Local edits only add an ES module export, strict indexed-access assertions and formatting. Independent decoding tests
|
|
141
|
+
use `jsqr` as a development-only dependency. Internal encoder symbols are excluded from the public component API.
|
|
142
|
+
|
|
143
|
+
## Carousel
|
|
144
|
+
|
|
145
|
+
`@haiyue/ui/carousel` exports `HYCarousel`, `defineCarouselComponents()` and the associated `HYCarousel*` types.
|
|
146
|
+
Registration is explicit; panels are HTML elements in the default slot and stay mounted between changes.
|
|
147
|
+
|
|
148
|
+
```html
|
|
149
|
+
<hy-carousel direction="horizontal" indicator-style="line" indicator-position="bottom"
|
|
150
|
+
autoplay interval="4000" draggable="true" loop="true" aria-label="Featured projects">
|
|
151
|
+
<article>First panel</article>
|
|
152
|
+
<article>Second panel</article>
|
|
153
|
+
<article>Third panel</article>
|
|
154
|
+
</hy-carousel>
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
| Attribute / property | Default | Behavior |
|
|
158
|
+
| --- | --- | --- |
|
|
159
|
+
| `index` | `0` | Active panel, zero based |
|
|
160
|
+
| `direction` | `horizontal` | `horizontal` or `vertical`; horizontal supports RTL |
|
|
161
|
+
| `indicator-style` / `indicatorStyle` | `dot` | `dot`, `line`, `number` |
|
|
162
|
+
| `indicator-position` / `indicatorPosition` | `bottom` | `top`, `right`, `bottom`, `left` |
|
|
163
|
+
| `show-indicators` / `showIndicators` | `true` | Set `false` to hide indicators |
|
|
164
|
+
| `show-arrows` / `showArrows` | `true` | Set `false` to hide previous/next buttons |
|
|
165
|
+
| `autoplay` | `false` | Opt-in automatic rotation with a pause/start button |
|
|
166
|
+
| `interval` | `3000` | Milliseconds, normalized to 100–86,400,000 |
|
|
167
|
+
| `draggable` | `true` | Mouse/touch swipe; set `false` to disable |
|
|
168
|
+
| `loop` | `true` | Wrap at the ends; `false` clamps and stops autoplay at the last panel |
|
|
169
|
+
|
|
170
|
+
Use `next()`, `previous()`, `goTo(index)`, `play()` and `pause()` for imperative control.
|
|
171
|
+
The bubbling, composed `change` event includes `{ index, previousIndex, source }`, with sources
|
|
172
|
+
`api`, `indicator`, `arrow`, `keyboard`, `drag`, `autoplay` and `content`.
|
|
173
|
+
Inactive panels are inert and hidden from assistive technology. Arrow keys (matching direction), Home and End
|
|
174
|
+
navigate the focused viewport or indicators; input fields keep their editing keys. Hover temporarily pauses rotation;
|
|
175
|
+
keyboard focus pauses until explicitly resumed. Reduced-motion preferences suppress transitions and initial automatic
|
|
176
|
+
rotation; `play()` permits explicit rotation. Disconnecting releases timers, pointer listeners and animations and restores panel attributes/styles.
|
|
177
|
+
|
|
178
|
+
Customize `::part(indicators)`, `::part(indicator)`, `::part(indicator-active)`, `::part(indicator-content)`,
|
|
179
|
+
`::part(previous)`, `::part(next)`, `::part(playback)` and `::part(viewport)`.
|
|
180
|
+
Tokens include `--hy-carousel-height` (240px), `--hy-carousel-duration` (320ms), `--hy-carousel-indicator-size`,
|
|
181
|
+
`--hy-carousel-indicator-gap`, `--hy-carousel-indicator-offset`, `--hy-carousel-indicator-radius`,
|
|
182
|
+
`--hy-carousel-indicator-color` and `--hy-carousel-indicator-active-color`; other colors inherit semantic theme tokens.
|
|
183
|
+
For arbitrary content, set `indicatorRenderer = (index, active) => Node | string | null` (strings are plain text).
|
|
184
|
+
The component retains the native accessible indicator buttons and click/keyboard behavior around your content.
|
|
185
|
+
Panels should not override the component's positioning, dimensions, visibility or transform.
|
|
186
|
+
|
|
187
|
+
## Masonry layout
|
|
188
|
+
|
|
189
|
+
Import `defineMasonryComponents` from `@haiyue/ui/masonry` and call it once to register `<hy-masonry>`.
|
|
190
|
+
Place HTML elements of varying heights in the default slot:
|
|
191
|
+
|
|
192
|
+
```html
|
|
193
|
+
<hy-masonry min-column-width="240" gap="16" aria-label="Project gallery">
|
|
194
|
+
<article>First card…</article>
|
|
195
|
+
<article>Another card with more content…</article>
|
|
196
|
+
<article><img src="preview.jpg" alt="Project preview" style="width: 100%" /></article>
|
|
197
|
+
</hy-masonry>
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
`columns` defaults to `0` (automatic); positive values request a fixed number of columns.
|
|
201
|
+
`min-column-width` (default `240`) controls automatic sizing; `gap` (default `16`) sets both gaps in CSS pixels.
|
|
202
|
+
Columns shrink to fit narrow containers. Each item goes into the shortest column, starting at the inline start,
|
|
203
|
+
including RTL layouts. DOM, screen-reader and keyboard order remain the original slot order.
|
|
204
|
+
Items keep their own content, theme and semantics; the component supplies positioning, border-box width and zero outer margins.
|
|
205
|
+
Use padding inside cards and avoid overriding item positioning/width. Text nodes and named slots are not layout items.
|
|
206
|
+
|
|
207
|
+
Container resizing, item resizing (including image loads), adding/removing items and toggling `hidden` automatically
|
|
208
|
+
schedule a layout. Call `refresh()` after changes outside those observations (for example, a stylesheet rule that
|
|
209
|
+
reveals a previously hidden item). `layout-change` bubbles across shadow roots with `{ columns, itemCount, height }`
|
|
210
|
+
after geometry changes; `itemCount` excludes hidden items. Style the transparent container with `::part(layout)`.
|
|
211
|
+
Observers and queued frames are released on disconnect, and internal item CSS properties are restored.
|
|
212
|
+
|
|
213
|
+
## Tag and toast
|
|
214
|
+
|
|
215
|
+
Tags provide compact semantic labels with optional checked and close interactions. Toasts are an imperative,
|
|
216
|
+
lightweight feedback surface for short-lived messages; use Notification when a message also needs a description
|
|
217
|
+
or richer stacked content.
|
|
218
|
+
|
|
219
|
+
```ts
|
|
220
|
+
import { defineTagComponents } from '@haiyue/ui/tag';
|
|
221
|
+
import { defineToastComponents } from '@haiyue/ui/toast';
|
|
222
|
+
|
|
223
|
+
defineTagComponents();
|
|
224
|
+
defineToastComponents();
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
```html
|
|
228
|
+
<hy-tag variant="success" icon="✓" closable>Synced</hy-tag>
|
|
229
|
+
<hy-tag variant="primary" checkable value="featured">Featured</hy-tag>
|
|
230
|
+
<hy-toast id="feedback" placement="top" duration="3" closable></hy-toast>
|
|
231
|
+
<script type="module">
|
|
232
|
+
feedback.success('Saved successfully');
|
|
233
|
+
const key = feedback.loading('Exporting…');
|
|
234
|
+
// Reusing a key replaces the persistent loading toast.
|
|
235
|
+
feedback.success({ key, message: 'Export complete' });
|
|
236
|
+
</script>
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
## Button icons, loading, and groups
|
|
240
|
+
|
|
241
|
+
Buttons accept a text `icon` or a richer `icon` slot. Set `icon-position="end"` to place it after the label.
|
|
242
|
+
The boolean `loading` attribute replaces the configured icon with a spinner, marks the native button busy, and
|
|
243
|
+
temporarily disables activation so an asynchronous request cannot be submitted twice.
|
|
244
|
+
|
|
245
|
+
```html
|
|
246
|
+
<hy-button label="Publish" icon="↥"></hy-button>
|
|
247
|
+
<hy-button label="Continue" icon="→" icon-position="end"></hy-button>
|
|
248
|
+
<hy-button loading label="Syncing"></hy-button>
|
|
249
|
+
<hy-button label="Upload"><svg slot="icon" aria-hidden="true">…</svg></hy-button>
|
|
250
|
+
|
|
251
|
+
<hy-button-group aria-label="History actions">
|
|
252
|
+
<hy-button label="Undo" icon="↶"></hy-button>
|
|
253
|
+
<hy-button label="Redo" icon="↷"></hy-button>
|
|
254
|
+
</hy-button-group>
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
Use `orientation="vertical"` for a stacked group. Button styling is exposed through the `button`, `content`,
|
|
258
|
+
`icon`, and `spinner` parts; the group exposes its container as the `group` part.
|
|
259
|
+
|
|
260
|
+
## Input and search
|
|
261
|
+
|
|
262
|
+
`HYInput` supports plain-text `prefix` and `suffix` attributes as well as named slots for icons or richer
|
|
263
|
+
content. Use `type="search"` to add an accessible search action button:
|
|
264
|
+
|
|
265
|
+
```html
|
|
266
|
+
<hy-input type="search" prefix="⌕" suffix="assets"
|
|
267
|
+
placeholder="Search…" search-label="Search assets"></hy-input>
|
|
268
|
+
|
|
269
|
+
<hy-input placeholder="Amount">
|
|
270
|
+
<span slot="prefix">¥</span>
|
|
271
|
+
<span slot="suffix">CNY</span>
|
|
272
|
+
</hy-input>
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
Search inputs emit a composed, cancelable `search` event when the user presses Enter, activates the search
|
|
276
|
+
button, or the application calls `search()`. Its detail contains `{ value, valid, source }`, where `source` is
|
|
277
|
+
`enter`, `button`, or `api`. Existing `value-change`, validation, number, and color input behavior remains
|
|
278
|
+
available. Style the `control`, `input`, `prefix`, `suffix`, and `search-button` parts or the
|
|
279
|
+
`--hy-input-affix-*` and `--hy-input-search-*` tokens.
|
|
280
|
+
|
|
281
|
+
## Portable component semantics (M24 G03/G05)
|
|
282
|
+
|
|
283
|
+
`@haiyue/ui/core` provides platform-independent component types, validation, selection/input/action
|
|
284
|
+
controllers and the `PlatformView` lifetime contract. `@haiyue/ui/portable` provides `HYPage`, selector
|
|
285
|
+
bindings, keyed updates, transactions, focus/modal policy and semantic theme conversion. Both entries
|
|
286
|
+
can be imported without DOM, NativeScript or Engine. They do not register existing Web Components.
|
|
287
|
+
|
|
288
|
+
```ts
|
|
289
|
+
import { hyNode, hyKey, type HYRenderer } from '@haiyue/ui/core';
|
|
290
|
+
import { HYPage } from '@haiyue/ui/portable';
|
|
291
|
+
|
|
292
|
+
export function mountPage(renderer: HYRenderer) {
|
|
293
|
+
const page = new HYPage(renderer);
|
|
294
|
+
page.mount(hyNode('Column', 'settings', { layout: { gap: 8 } }, {
|
|
295
|
+
children: [hyNode('Text', 'title', { text: 'Settings' })],
|
|
296
|
+
}));
|
|
297
|
+
page.setProps(hyKey('settings', 'title'), 'Text', { text: 'Preview settings' });
|
|
298
|
+
return page; // The shell forwards suspend/resume and calls dispose on exit.
|
|
299
|
+
}
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
Author keys are stable and unique within each parent, including its named slots. `hyKey()` builds
|
|
303
|
+
scoped keys for bindings, events and focus. `setProps()` completely replaces a node's props; use
|
|
304
|
+
`transaction()` for one synchronous batch. Group all selectors for a given store in one `bind(store,
|
|
305
|
+
bindings)` call so an application transaction produces one renderer commit. Identical props produce
|
|
306
|
+
no writes; reordering preserves instances. Applications persist values on `commit`, not `valueChange`.
|
|
307
|
+
|
|
308
|
+
The Web backend is available from `@haiyue/ui/adapters/web`: explicitly call
|
|
309
|
+
`definePortableWebComponents()`, construct `new HYWebRenderer(connectedElement, options)`, then pass it
|
|
310
|
+
to `HYPage`. It reuses seven existing Web Components and maps the other semantic kinds to browser
|
|
311
|
+
elements. It introduces no runtime package dependencies or automatic registration. See the
|
|
312
|
+
[Web adapter guide](docs/web-adapter.md) and [interactive example](examples/portable-ui/index.html).
|
|
313
|
+
Run `npm run test:web-adapter` for Chromium/WebKit regression coverage.
|
|
314
|
+
|
|
315
|
+
These APIs are included in the package and remain under development. Mobile mapping is G06, desktop mapping
|
|
316
|
+
G08, and ShaderLab shared-page migration G07. Existing Web component APIs below remain independent. See the
|
|
317
|
+
[portable UI guide](docs/portable-ui.md) and [typed composition example](test/portable/fixtures/settings-page.ts).
|
|
318
|
+
Run `npm run verify:portable` for semantics, no-DOM types, and an isolated offline tarball consumer.
|
|
319
|
+
|
|
49
320
|
## Tabs
|
|
50
321
|
|
|
51
322
|
`@haiyue/ui/tabs` retains its existing `HYTabs`, `HYTabOption`, `HYTabChangeDetail`, and
|
|
@@ -82,6 +353,238 @@ Use the `height` property (or `height` attribute) for the internal viewport. `vi
|
|
|
82
353
|
exclusive `endIndex` / `visibleEndIndex` values, and `item-click` reports the source item and absolute index.
|
|
83
354
|
The scrollbar can be themed with inherited semantic tokens and `--hy-virtual-list-scrollbar-size`.
|
|
84
355
|
|
|
356
|
+
## Breadcrumb
|
|
357
|
+
|
|
358
|
+
Import and register breadcrumb navigation independently:
|
|
359
|
+
|
|
360
|
+
```ts
|
|
361
|
+
import { defineBreadcrumbComponents } from '@haiyue/ui/breadcrumb';
|
|
362
|
+
|
|
363
|
+
defineBreadcrumbComponents();
|
|
364
|
+
const breadcrumb = document.querySelector('hy-breadcrumb');
|
|
365
|
+
breadcrumb.items = [
|
|
366
|
+
{ key: 'projects', title: 'Projects', href: '/projects' },
|
|
367
|
+
{ key: 'scene', title: 'Ocean World' },
|
|
368
|
+
{ key: 'lighting', title: 'Lighting' },
|
|
369
|
+
];
|
|
370
|
+
breadcrumb.separator = '›';
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
Item text may use the Ant Design-compatible `title` field or its `label` alias. The final item is exposed as
|
|
374
|
+
the current page with `aria-current="page"`. Earlier items render as links when
|
|
375
|
+
they provide `href`, or as action buttons otherwise; disabled items remain readable but cannot be activated.
|
|
376
|
+
Listen for the composed, cancelable `breadcrumb-click` event to handle actions or prevent link navigation.
|
|
377
|
+
Use `renderItem` for custom item content, and `ariaLabel` when rendered content needs an explicit accessible
|
|
378
|
+
name. Styling hooks include the `nav`, `list`, `item`, `link`, `button`, `current`, `disabled`, and `separator`
|
|
379
|
+
shadow parts plus the `--hy-breadcrumb-*` CSS variables.
|
|
380
|
+
|
|
381
|
+
## Cascader
|
|
382
|
+
|
|
383
|
+
Use the focused `@haiyue/ui/cascader` entry for hierarchical selection:
|
|
384
|
+
|
|
385
|
+
```ts
|
|
386
|
+
import { defineCascaderComponents } from '@haiyue/ui/cascader';
|
|
387
|
+
|
|
388
|
+
defineCascaderComponents();
|
|
389
|
+
const cascader = document.querySelector('hy-cascader');
|
|
390
|
+
cascader.options = [
|
|
391
|
+
{ label: 'Project', value: 'project', children: [
|
|
392
|
+
{ label: 'Scenes', value: 'scenes', children: [
|
|
393
|
+
{ label: 'Moon Temple', value: 'temple' },
|
|
394
|
+
] },
|
|
395
|
+
] },
|
|
396
|
+
];
|
|
397
|
+
cascader.value = ['project', 'scenes', 'temple'];
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
Selecting a leaf commits the complete value path and emits `value-change` with both values and resolved option
|
|
401
|
+
objects. Enable `changeOnSelect` (or `change-on-select`) when parent paths should also be committed. The component
|
|
402
|
+
supports string and number values, disabled options, clearing, a custom `displaySeparator`, controlled `open`
|
|
403
|
+
state, outside-pointer and Escape closing, and arrow/Home/End keyboard navigation. `open-change` reports panel
|
|
404
|
+
visibility. Shadow parts expose `control`, `trigger`, `label`, `arrow`, `clear`, `panel`, `column`, `option`,
|
|
405
|
+
`option-item`, and `empty` for product-specific styling.
|
|
406
|
+
|
|
407
|
+
## Date and time pickers
|
|
408
|
+
|
|
409
|
+
Date and time selection remain independently importable, so an application only ships the picker it uses:
|
|
410
|
+
|
|
411
|
+
```ts
|
|
412
|
+
import { defineDatePickerComponents } from '@haiyue/ui/date-picker';
|
|
413
|
+
import { defineTimePickerComponents } from '@haiyue/ui/time-picker';
|
|
414
|
+
|
|
415
|
+
defineDatePickerComponents();
|
|
416
|
+
defineTimePickerComponents();
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
`<hy-date-picker>` emits ISO `YYYY-MM-DD` values and provides a locale-aware month calendar, `min` / `max`
|
|
420
|
+
constraints, Monday or Sunday `weekStart`, Today, clearing, outside-pointer and Escape closing, and arrow,
|
|
421
|
+
Home/End, and PageUp/PageDown keyboard navigation.
|
|
422
|
+
|
|
423
|
+
`<hy-time-picker>` emits 24-hour `HH:mm` or `HH:mm:ss` values. Enable `showSeconds`, configure
|
|
424
|
+
`minuteStep` / `secondStep`, and constrain selection with `min` / `max`. Its scrollable hour, minute, and second
|
|
425
|
+
columns support keyboard traversal, Now, explicit confirmation, clearing, and controlled `open` state. Both
|
|
426
|
+
components emit composed `value-change` and `open-change` events and expose their controls through shadow parts.
|
|
427
|
+
|
|
428
|
+
## Skeleton
|
|
429
|
+
|
|
430
|
+
Import the loading placeholder independently and place the real content in its default slot:
|
|
431
|
+
|
|
432
|
+
```ts
|
|
433
|
+
import { defineSkeletonComponents } from '@haiyue/ui/skeleton';
|
|
434
|
+
|
|
435
|
+
defineSkeletonComponents();
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+
`<hy-skeleton>` defaults to a title and three paragraph rows. Enable `active` for the shimmer animation, add
|
|
439
|
+
`avatar`, choose `avatarShape`, `avatarSize`, `size`, and `round`, or tune `rows`, `titleWidth`, and the
|
|
440
|
+
`paragraphWidths` property. Set `loading = false` to remove placeholder DOM and reveal the slotted content.
|
|
441
|
+
The host exposes `aria-busy`, honors reduced-motion preferences, inherits both Haiyue themes, and provides
|
|
442
|
+
`placeholder`, `content`, `avatar`, `body`, `title`, `paragraph`, and `row` shadow parts.
|
|
443
|
+
|
|
444
|
+
## Steps
|
|
445
|
+
|
|
446
|
+
Use `@haiyue/ui/steps` to show task, form, or publishing progress. Assign `items` with a required `title` and
|
|
447
|
+
optional `description`, `subtitle`, `icon`, `status`, and `disabled` state. `current` is zero-based and derives
|
|
448
|
+
`finish`, `process`, and `wait` states automatically unless an item provides an explicit status. Set
|
|
449
|
+
`direction` to `horizontal` or `vertical`, use `size="small"` for compact layouts, and enable `clickable` when
|
|
450
|
+
users may navigate between steps. Click navigation updates `current` and emits the composed `step-change` event.
|
|
451
|
+
The ordered list exposes `aria-current="step"` and shadow parts for every structural and status element.
|
|
452
|
+
|
|
453
|
+
## Badge
|
|
454
|
+
|
|
455
|
+
Import `@haiyue/ui/badge` to decorate slotted content with a count or notification dot, or to render a standalone
|
|
456
|
+
semantic status. Numeric counts are capped by `overflowCount` (99 by default); use `showZero`, `dot`, `size`,
|
|
457
|
+
`color`, `title`, and the `[x, y]` `offset` property for display control. The `default`, `success`, `processing`,
|
|
458
|
+
`warning`, and `error` statuses accept accompanying `text`, expose status semantics, and honor reduced-motion
|
|
459
|
+
preferences. Structural styling hooks include `wrapper`, `badge`, `badge-content`, `status`, `status-dot`, and
|
|
460
|
+
`status-text` shadow parts.
|
|
461
|
+
|
|
462
|
+
## Collapse
|
|
463
|
+
|
|
464
|
+
Import `@haiyue/ui/collapse` and assign typed `items` containing `key`, `title`, optional `content`, `extra`,
|
|
465
|
+
`disabled`, and `showArrow` values. `activeKeys` supports multiple open panels, while `accordion` limits the
|
|
466
|
+
group to one. Configure `iconPosition`, `collapsible`, `bordered`, `ghost`, and `destroyOnHidden`; call
|
|
467
|
+
`toggle(key, expanded?)` for imperative control. Each header is a native keyboard-accessible button connected
|
|
468
|
+
to a labelled region, and user changes emit the composed `collapse-change` event with the active keys and
|
|
469
|
+
changed panel. The component exposes structural shadow parts from `collapse` and `panel` through `body`.
|
|
470
|
+
|
|
471
|
+
Enable `animated` / `animated = true` for smooth opening and closing. Animation is off by default;
|
|
472
|
+
initial rendering stays immediate. Set `animation-duration` / `animationDuration` in milliseconds
|
|
473
|
+
(default 200, range 0–10,000); zero disables animation. Without the attribute, the inherited
|
|
474
|
+
`--hy-collapse-animation-duration` token (for example `250ms`) supplies the duration.
|
|
475
|
+
`--hy-collapse-animation-easing` customizes the easing (default `ease`).
|
|
476
|
+
|
|
477
|
+
```html
|
|
478
|
+
<hy-collapse animated animation-duration="250" destroy-on-hidden></hy-collapse>
|
|
479
|
+
```
|
|
480
|
+
|
|
481
|
+
Rapid toggles reverse from the current height, and content resizing during expansion updates the target height.
|
|
482
|
+
Closed panels become inert and hidden from assistive technology immediately; focus returns to their header
|
|
483
|
+
when needed. With `destroyOnHidden`, content is removed after the closing animation finishes.
|
|
484
|
+
Disabling animation, setting duration to zero, or enabling reduced-motion preferences settles immediately.
|
|
485
|
+
Animations and content observers are released on disconnect. The existing `collapse-change` event still fires
|
|
486
|
+
when the expanded state changes, rather than waiting for animation completion. These options extend `HYCollapse`;
|
|
487
|
+
no new package exports or registration functions are required.
|
|
488
|
+
|
|
489
|
+
## Affix
|
|
490
|
+
|
|
491
|
+
Import `@haiyue/ui/affix` to pin actions, navigation, or status content after it crosses a viewport threshold.
|
|
492
|
+
Use the `offset-top` or `offset-bottom` attributes, or the `topOffset` / `bottomOffset` properties, and assign an
|
|
493
|
+
element to `target` when the scroll container is not the browser window. The component preserves the original
|
|
494
|
+
layout with an internal placeholder, exposes the read-only `affixed` state, and emits the composed
|
|
495
|
+
`affix-change` event. Call `refresh()` after layout changes that do not trigger resize observation.
|
|
496
|
+
|
|
497
|
+
## Tour
|
|
498
|
+
|
|
499
|
+
Import `@haiyue/ui/tour` for step-by-step product guidance. Assign `steps` with a title, optional description,
|
|
500
|
+
target selector, element, or resolver function, and an optional `top`, `right`, `bottom`, `left`, or `center`
|
|
501
|
+
placement. The component can render a spotlight mask, scroll targets into view, close from Escape or mask
|
|
502
|
+
interaction, and is controlled through `open` and zero-based `current`. Use `start()`, `next()`, `previous()`,
|
|
503
|
+
and `close()` from application code; observe `tour-change`, `tour-close`, `tour-finish`, and `tour-open-change`
|
|
504
|
+
for lifecycle state. Focus returns to the launch control when the tour ends.
|
|
505
|
+
|
|
506
|
+
## Divider
|
|
507
|
+
|
|
508
|
+
Import `@haiyue/ui/divider` for semantic horizontal or vertical separators. Text can be supplied through the
|
|
509
|
+
default slot or the `label` property. Choose `solid`, `dashed`, `dotted`, or `double` with `lineStyle`, and place
|
|
510
|
+
text at `start`, `center`, or `end` with `textPlacement`. `thickness`, `color`, and `spacing` provide direct
|
|
511
|
+
appearance controls, while the `divider`, `line`, `line-before`, `line-after`, `text`, and `fallback` shadow
|
|
512
|
+
parts support product-specific styling. The internal separator exposes the correct `aria-orientation`.
|
|
513
|
+
|
|
514
|
+
## Timeline
|
|
515
|
+
|
|
516
|
+
Use `@haiyue/ui/timeline` for ordered activity, history, and process displays. Assign typed `items` containing
|
|
517
|
+
`title`, optional `label` and `description`, semantic `status`, custom `color` or `dot`, and an optional per-item
|
|
518
|
+
`position`. The `left`, `right`, and `alternate` modes control placement; `reverse` flips the order and moves an
|
|
519
|
+
optional `pending` node to the leading edge. `renderItem` and `renderDot` provide DOM customization without
|
|
520
|
+
changing the data contract. The ordered list automatically collapses to a readable single-column layout on
|
|
521
|
+
narrow screens and its pending animation honors reduced-motion preferences.
|
|
522
|
+
|
|
523
|
+
## Rate
|
|
524
|
+
|
|
525
|
+
Import and register the star rating independently:
|
|
526
|
+
|
|
527
|
+
```ts
|
|
528
|
+
import { defineRateComponents } from '@haiyue/ui/rate';
|
|
529
|
+
|
|
530
|
+
defineRateComponents();
|
|
531
|
+
```
|
|
532
|
+
|
|
533
|
+
`<hy-rate>` exposes a controlled numeric `value` and defaults to five stars. Add `allow-half` (or set
|
|
534
|
+
`allowHalf = true`) for 0.5 increments. Configure `count`, `allowClear`, `character`, and `tooltips`, or set
|
|
535
|
+
`disabled` / `readOnly` for non-editable states. The component exposes slider semantics, arrow/Home/End keyboard
|
|
536
|
+
control, `value-change` and `hover-change` composed events, plus `group`, `star`, and `fill` shadow parts.
|
|
537
|
+
|
|
538
|
+
## Watermark
|
|
539
|
+
|
|
540
|
+
Wrap any content and render a non-interactive repeated text or image mark above it:
|
|
541
|
+
|
|
542
|
+
```ts
|
|
543
|
+
import { defineWatermarkComponents } from '@haiyue/ui/watermark';
|
|
544
|
+
|
|
545
|
+
defineWatermarkComponents();
|
|
546
|
+
const watermark = document.querySelector('hy-watermark');
|
|
547
|
+
watermark.content = ['HAIYUE', 'INTERNAL'];
|
|
548
|
+
```
|
|
549
|
+
|
|
550
|
+
Use `content` for one or more text lines, or set `image` to prefer an image mark. Geometry is controlled by
|
|
551
|
+
`rotate`, `gapX`, `gapY`, `offsetX`, `offsetY`, `markWidth`, and `markHeight`; typography and appearance use
|
|
552
|
+
`fontSize`, `fontFamily`, `fontWeight`, `color`, `opacity`, and `zIndex`. The SVG pattern lives inside the
|
|
553
|
+
component shadow root, is hidden from assistive technology, and uses `pointer-events: none`, so links, buttons,
|
|
554
|
+
and other slotted content remain interactive. Shadow parts expose `content`, `overlay`, `mark`, `text`, and
|
|
555
|
+
`image` for targeted styling.
|
|
556
|
+
|
|
557
|
+
## Table
|
|
558
|
+
|
|
559
|
+
Import the data table from its focused entry. It applies local filters first, then stable sorting, and finally
|
|
560
|
+
pagination, so only the current page is rendered as rows:
|
|
561
|
+
|
|
562
|
+
```ts
|
|
563
|
+
import { defineTableComponents } from '@haiyue/ui/table';
|
|
564
|
+
|
|
565
|
+
defineTableComponents();
|
|
566
|
+
const table = document.querySelector('hy-table');
|
|
567
|
+
table.columns = [
|
|
568
|
+
{ key: 'name', title: 'Name', sortable: true, filterable: true },
|
|
569
|
+
{ key: 'role', title: 'Role', filterOptions: roles },
|
|
570
|
+
{ key: 'score', title: 'Score', sortable: true, align: 'right' },
|
|
571
|
+
];
|
|
572
|
+
table.dataSource = records;
|
|
573
|
+
table.pageSize = 20;
|
|
574
|
+
```
|
|
575
|
+
|
|
576
|
+
Use `page`, `pageSize`, `pageSizeOptions`, and `pagination` for paging; `filters`, `setFilter()`, and
|
|
577
|
+
`clearFilters()` for filtering; and `sort`, `sortBy()`, and `clearSort()` for ordering. Columns may provide a
|
|
578
|
+
custom `filter`, `sorter`, or `render` function. `table-change` reports the complete processed state after a
|
|
579
|
+
user or API change, while `row-click` returns the source record and its original absolute index. The `empty`
|
|
580
|
+
slot, semantic theme tokens, and exported shadow parts support content and visual customization.
|
|
581
|
+
|
|
582
|
+
Filterable columns show a funnel control beside the title. Set `table.showFilters = false` or
|
|
583
|
+
`show-filters="false"` to hide all filter controls while keeping programmatic filtering active. Set
|
|
584
|
+
`showFilter: false` on an individual column to hide only that column's funnel. The filter menu, trigger, panel,
|
|
585
|
+
input, and clear action are exposed through the `filter-menu`, `filter-trigger`, `filter-panel`, `filter`, and
|
|
586
|
+
`filter-clear` shadow parts.
|
|
587
|
+
|
|
85
588
|
## Drawer
|
|
86
589
|
|
|
87
590
|
Import and register the drawer independently when a product needs an off-canvas panel:
|
|
@@ -156,6 +659,104 @@ Single-value mode uses `value`; interval mode exposes `lowerValue`, `upperValue`
|
|
|
156
659
|
`rail`, `track`, `handle`, `handle-lower`, and `handle-upper` shadow parts. `value-input` reports live movement and
|
|
157
660
|
`value-change` reports a committed pointer or keyboard change.
|
|
158
661
|
|
|
662
|
+
## Virtual keyboard
|
|
663
|
+
|
|
664
|
+
Import the on-screen keyboard independently and bind it to a text input or textarea:
|
|
665
|
+
|
|
666
|
+
```ts
|
|
667
|
+
import { defineVirtualKeyboardComponents } from '@haiyue/ui/virtual-keyboard';
|
|
668
|
+
|
|
669
|
+
defineVirtualKeyboardComponents();
|
|
670
|
+
const keyboard = document.querySelector('hy-virtual-keyboard');
|
|
671
|
+
keyboard.target = document.querySelector('textarea');
|
|
672
|
+
keyboard.physicalSync = true;
|
|
673
|
+
keyboard.mode = 'numeric'; // switch back with 'qwerty'
|
|
674
|
+
await keyboard.type('Haiyue UI', { interval: 45 });
|
|
675
|
+
```
|
|
676
|
+
|
|
677
|
+
The default exported `HY_VIRTUAL_KEYBOARD_QWERTY_LAYOUT` includes digits, letters, Shift, Caps Lock, editing,
|
|
678
|
+
all four arrow directions, caret, and navigation keys. Set `mode` to `qwerty` or `numeric`; the numeric mode uses
|
|
679
|
+
the exported `HY_VIRTUAL_KEYBOARD_NUMERIC_LAYOUT` with digits, decimal, minus, deletion, and Enter keys. Assign
|
|
680
|
+
`layout` with rows of typed key descriptors for shortcut or product-specific keyboards. Pointer and native keyboard activation edit the bound target and emit its normal
|
|
681
|
+
`input` event; `physicalSync` mirrors real key state without duplicating native input. `press()`, `release()`,
|
|
682
|
+
`tap()`, `type()`, and `clear()` support guided playback. Observe `virtual-keyboard-down`,
|
|
683
|
+
`virtual-keyboard-up`, and `virtual-keyboard-input`, or style `keyboard`, `row`, `key`, and per-code key parts
|
|
684
|
+
with the `--hy-virtual-keyboard-*` tokens.
|
|
685
|
+
|
|
686
|
+
## Draggable container
|
|
687
|
+
|
|
688
|
+
Import the transform-based container independently, then use any slotted element as its handle:
|
|
689
|
+
|
|
690
|
+
```ts
|
|
691
|
+
import { defineDraggableComponents } from '@haiyue/ui/draggable';
|
|
692
|
+
|
|
693
|
+
defineDraggableComponents();
|
|
694
|
+
const panel = document.querySelector('hy-draggable');
|
|
695
|
+
panel.bounds = 'parent';
|
|
696
|
+
panel.axis = 'both';
|
|
697
|
+
panel.grid = 8;
|
|
698
|
+
panel.moveTo(24, 24);
|
|
699
|
+
```
|
|
700
|
+
|
|
701
|
+
`bounds` accepts `none`, `parent`, `viewport`, or an `HTMLElement`; `axis` accepts `both`, `x`, or `y`.
|
|
702
|
+
Use `handle` to restrict pointer starts to a selector and `cancel` to exclude interactive content. The default
|
|
703
|
+
cancel selector protects inputs, buttons, links, editable content, and `[data-no-drag]`. Arrow keys move by one
|
|
704
|
+
grid step, Shift multiplies that step by ten, and Home resets the position. `moveTo()`, `moveBy()`, `reset()`,
|
|
705
|
+
and `refresh()` provide imperative control. Observe cancelable `drag-start`, followed by `drag-move` and
|
|
706
|
+
`drag-end`; style the exported `surface` part and `--hy-draggable-*` tokens.
|
|
707
|
+
|
|
708
|
+
## Resizable container
|
|
709
|
+
|
|
710
|
+
Import the eight-handle transform frame independently. Its four corner points and four edge-midpoint handles
|
|
711
|
+
resize the rectangle; dragging the content surface moves it:
|
|
712
|
+
|
|
713
|
+
```ts
|
|
714
|
+
import { defineResizableComponents } from '@haiyue/ui/resizable';
|
|
715
|
+
|
|
716
|
+
defineResizableComponents();
|
|
717
|
+
const frame = document.querySelector('hy-resizable');
|
|
718
|
+
frame.bounds = 'parent';
|
|
719
|
+
frame.grid = 8;
|
|
720
|
+
frame.aspectRatio = 16 / 9;
|
|
721
|
+
frame.setRect({ x: 48, y: 48, width: 240, height: 135 });
|
|
722
|
+
```
|
|
723
|
+
|
|
724
|
+
Configure `minWidth`, `minHeight`, `maxWidth`, and `maxHeight`, or use the matching kebab-case attributes.
|
|
725
|
+
`bounds` accepts `none`, `parent`, `viewport`, or an `HTMLElement`; `movable="false"` keeps content stationary
|
|
726
|
+
while preserving resize handles. The focused frame and handles support arrows, Shift acceleration, and Home
|
|
727
|
+
reset. Imperative APIs include `setRect()`, `moveTo()`, `moveBy()`, `resizeTo()`, `reset()`, and `refresh()`.
|
|
728
|
+
Observe cancelable `resize-start`, continuous `resize`, and `resize-end` events. Shadow parts expose `frame`,
|
|
729
|
+
`content`, `handle`, and every directional handle such as `handle-nw`; appearance uses `--hy-resizable-*` tokens.
|
|
730
|
+
|
|
731
|
+
## Virtual mouse
|
|
732
|
+
|
|
733
|
+
Import the fixed-position cursor visual independently. It never intercepts pointer input or synthesizes clicks on
|
|
734
|
+
page elements; host applications receive composed events and decide how actions map to product behavior:
|
|
735
|
+
|
|
736
|
+
```ts
|
|
737
|
+
import { defineVirtualMouseComponents } from '@haiyue/ui/virtual-mouse';
|
|
738
|
+
|
|
739
|
+
defineVirtualMouseComponents();
|
|
740
|
+
const mouse = document.querySelector('hy-virtual-mouse');
|
|
741
|
+
mouse.images = {
|
|
742
|
+
idle: '/cursor-idle.png',
|
|
743
|
+
'left-down': '/cursor-left.png',
|
|
744
|
+
'right-down': '/cursor-right.png',
|
|
745
|
+
};
|
|
746
|
+
mouse.show();
|
|
747
|
+
await mouse.moveTo(420, 280, { animate: true, duration: 600 });
|
|
748
|
+
await mouse.leftClick();
|
|
749
|
+
await mouse.rightClick();
|
|
750
|
+
```
|
|
751
|
+
|
|
752
|
+
Use `moveTo()` / `moveBy()` for coordinates, `press()` / `release()` for held-button states, and
|
|
753
|
+
`leftClick()` / `middleClick()` / `rightClick()` for timed click feedback. `animated`, `duration`, and `easing`
|
|
754
|
+
provide host defaults; every move may override them. State images may also be supplied through `idle-image`,
|
|
755
|
+
`left-down-image`, `middle-down-image`, and `right-down-image`. Style the exported `cursor`, `shape`, `image`,
|
|
756
|
+
and `indicator` parts or the `--hy-virtual-mouse-*` CSS variables. Events include `virtual-mouse-move-start`,
|
|
757
|
+
`virtual-mouse-move`, `virtual-mouse-move-end`, `virtual-mouse-down`, `virtual-mouse-up`, and
|
|
758
|
+
`virtual-mouse-click`.
|
|
759
|
+
|
|
159
760
|
## Themes
|
|
160
761
|
|
|
161
762
|
Two optional CSS theme entries are provided. Import only the skin a product needs, or import both when the
|
|
@@ -189,7 +790,11 @@ npm run examples
|
|
|
189
790
|
```
|
|
190
791
|
|
|
191
792
|
Then open <http://localhost:4173/>. The gallery provides a left-side component index and live examples for
|
|
192
|
-
every exported component, including editable parameters and event output.
|
|
793
|
+
every exported component, including editable parameters and event output. The gallery shell itself dogfoods
|
|
794
|
+
Haiyue UI: theme actions, component search, command results, status, and example action controls use the
|
|
795
|
+
published Web Components rather than parallel page-only widgets. The navigation/content shell and eligible
|
|
796
|
+
preview/control cards use `hy-split` for keyboard- and pointer-adjustable sizing. Usage blocks are rendered as
|
|
797
|
+
read-only CodeMirror editors with HTML, JavaScript, and CSS syntax highlighting.
|
|
193
798
|
|
|
194
799
|
## Expandable container
|
|
195
800
|
|
|
@@ -230,4 +835,40 @@ npm run release:check
|
|
|
230
835
|
```
|
|
231
836
|
|
|
232
837
|
Candidates: `.artifacts/packages/`. Review API changes before `npm run api:update`.
|
|
233
|
-
See [release review](review/release-0.
|
|
838
|
+
See [release review](review/release-0.2.2.md).
|
|
839
|
+
|
|
840
|
+
### 共享组件目录(开发中)
|
|
841
|
+
|
|
842
|
+
`@haiyue/ui/core` 的 `HYComponentProps` 增加五种节点,Web 适配复用对应组件子模块,Native 适配使用原生控件;不新增根导出,也不自动注册全部组件。现有 18 种节点保持兼容,支持范围由 renderer 的 `capabilities.components` 声明。
|
|
843
|
+
|
|
844
|
+
| 节点 | 对应 WebComponent | 当前共享属性 |
|
|
845
|
+
| --- | --- | --- |
|
|
846
|
+
| `Checkbox` | `hy-checkbox` | `text`, `checked`, `disabled`;区别于原生开关 `Toggle` |
|
|
847
|
+
| `RadioGroup` | 一组 `hy-radio` | `value`, `options`, `disabled`;值必须出现在选项中 |
|
|
848
|
+
| `Rate` | `hy-rate` | `value`(0 到 count 的整数), `count`(1–10), `disabled`, `readOnly` |
|
|
849
|
+
| `Badge` | `hy-badge` | 独立文本 `text`,计数截断由应用决定 |
|
|
850
|
+
| `Divider` | `hy-divider` | 水平分隔线,可选 `text` |
|
|
851
|
+
|
|
852
|
+
交互节点受应用状态控制,通过同一 transaction 的 `valueChange` / `commit` 提议变更;应用拒绝时保留已接受值。评分的半星、悬浮效果,徽标的圆点、动画、悬挂计数,分隔线的垂直/虚线模式尚未纳入共享协议。请勿把 WebComponent 的所有属性直接传入通用节点。
|
|
853
|
+
|
|
854
|
+
Native 仓库的 `examples/ui-validation/mobile` 提供独立「Haiyue UI」组件实验室;折叠内容、步骤导航与按钮组是基础节点组合示例,不是新增协议节点。
|
|
855
|
+
|
|
856
|
+
Web 的 `hy-badge` 新增可选 `literal` 属性(默认为 false):启用后 `count` 按原始文字显示,保留 0、前导零和大数字。普通计数的隐藏零值、截断,以及 status/text 模式保持原行为;共享 Badge 适配显式启用此模式。
|
|
857
|
+
|
|
858
|
+
The portable presentation contract adds optional semantic `Button.variant`
|
|
859
|
+
(`primary`, `secondary`, `quiet`, `danger`), `size` and vector `icon` names;
|
|
860
|
+
`Text.textStyle` (`title`, `body`, `caption`) and `tone`; `Tabs.variant`
|
|
861
|
+
(`underline`, `segmented`); and native `Select.presentation`. Existing nodes stay
|
|
862
|
+
valid. `HYTheme.typography` scales with fontScale, and optional selected, pressed,
|
|
863
|
+
disabled, elevated and onAccent colors map to inherited `--hy-` properties.
|
|
864
|
+
`HYIconName`, `HYButtonVariant`, `HYTextStyle` and `HYTypography` are explicitly
|
|
865
|
+
exported from `@haiyue/ui/core`; `HY_ICONS` / `hyIconSvg` are explicitly exported
|
|
866
|
+
from `@haiyue/ui/portable`, with no platform access or registration at import time.
|
|
867
|
+
|
|
868
|
+
Portable forms accept optional `FormGroup.description`, rendered as visible helper
|
|
869
|
+
text and included in associated controls' accessible descriptions. Updating help
|
|
870
|
+
or validation errors preserves the existing input, selection and composition.
|
|
871
|
+
`@haiyue/ui/portable` explicitly exports `hyResponsiveGrid`,
|
|
872
|
+
`hyResponsiveWorkspace`, `HYResponsiveGridOptions` and
|
|
873
|
+
`HYResponsiveWorkspaceOptions`. These return logical-pixel layout data without
|
|
874
|
+
reading window or platform globals, so hosts can use actual split-window sizes.
|