haze-ui 1.32.0 → 1.33.0
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.md +87 -1210
- package/dist/coi-serviceworker.LICENSE +21 -0
- package/dist/coi-serviceworker.js +118 -0
- package/dist/components/Countdown/Countdown.js +49 -0
- package/dist/components/Countdown/index.js +3 -0
- package/dist/components/HoverCard/HoverCard.js +63 -43
- package/dist/components/ImageCrop/ImageCrop.js +188 -0
- package/dist/components/ImageCrop/image-crop-geometry.js +81 -0
- package/dist/components/ImageCrop/index.js +3 -0
- package/dist/components/LocaleProvider/ar-sa.js +6 -0
- package/dist/components/LocaleProvider/de-de.js +6 -0
- package/dist/components/LocaleProvider/es-es.js +6 -0
- package/dist/components/LocaleProvider/fr-fr.js +6 -0
- package/dist/components/LocaleProvider/it-it.js +6 -0
- package/dist/components/LocaleProvider/ja-jp.js +6 -0
- package/dist/components/LocaleProvider/ko-kr.js +6 -0
- package/dist/components/LocaleProvider/locale.js +6 -0
- package/dist/components/LocaleProvider/pt-br.js +6 -0
- package/dist/components/LocaleProvider/ru-ru.js +6 -0
- package/dist/components/LocaleProvider/zh-cn.js +6 -0
- package/dist/components/Resizable/index.js +1 -1
- package/dist/components/Splitter/Splitter.js +199 -0
- package/dist/components/Splitter/index.js +3 -0
- package/dist/css/countdown.css +4 -0
- package/dist/css/image-crop.css +4 -0
- package/dist/css/splitter.css +4 -0
- package/dist/css-manifest.json +4 -3
- package/dist/haze-ui.css +12 -0
- package/dist/hooks/useHotkeys.js +78 -24
- package/dist/index.js +277 -274
- package/dist/mcp-docs.json +210 -9
- package/dist/registry.json +71 -5
- package/dist/robots.txt +4 -0
- package/dist/sitemap.xml +160 -0
- package/dist/types/components/ConfigProvider/ConfigContext.d.ts +2 -1
- package/dist/types/components/Countdown/Countdown.d.ts +30 -0
- package/dist/types/components/Countdown/index.d.ts +2 -0
- package/dist/types/components/HoverCard/HoverCard.d.ts +18 -1
- package/dist/types/components/ImageCrop/ImageCrop.d.ts +67 -0
- package/dist/types/components/ImageCrop/image-crop-geometry.d.ts +65 -0
- package/dist/types/components/ImageCrop/index.d.ts +3 -0
- package/dist/types/components/LocaleProvider/locale.d.ts +6 -0
- package/dist/types/components/Resizable/index.d.ts +0 -2
- package/dist/types/components/Splitter/Splitter.d.ts +33 -0
- package/dist/types/components/Splitter/index.d.ts +2 -0
- package/dist/types/headless/index.d.ts +7 -6
- package/dist/types/hooks/useHotkeys.d.ts +16 -4
- package/dist/types/index.d.ts +7 -2
- package/package.json +23 -4
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { ComponentPropsWithoutRef, ReactNode } from 'react';
|
|
2
|
+
/** Decomposed remaining time handed to `format`/`render`. */
|
|
3
|
+
type CountdownParts = {
|
|
4
|
+
/** Whole seconds left — `ceil` of the exact milliseconds so every
|
|
5
|
+
* displayed second is a full second and the display lands on 0 exactly
|
|
6
|
+
* at the deadline. */
|
|
7
|
+
totalSeconds: number;
|
|
8
|
+
days: number;
|
|
9
|
+
hours: number;
|
|
10
|
+
minutes: number;
|
|
11
|
+
seconds: number;
|
|
12
|
+
/** Deadline reached — parts are all zero and the clock has stopped. */
|
|
13
|
+
finished: boolean;
|
|
14
|
+
};
|
|
15
|
+
type CountdownProps = {
|
|
16
|
+
/** Deadline: epoch milliseconds or a `Date`. Changing it re-aims the
|
|
17
|
+
* clock (and re-arms a spent `onFinish`). */
|
|
18
|
+
value: number | Date;
|
|
19
|
+
/** Fires exactly once when the deadline is reached. */
|
|
20
|
+
onFinish?: () => void;
|
|
21
|
+
/** Parts → display string. Default: adaptive — `1d 02:03:04` past a
|
|
22
|
+
* day, `02:03:04` under it. */
|
|
23
|
+
format?: (parts: CountdownParts) => string;
|
|
24
|
+
/** Parts → arbitrary node — the render escape hatch next to `format`
|
|
25
|
+
* for non-string output. */
|
|
26
|
+
render?: (parts: CountdownParts) => ReactNode;
|
|
27
|
+
className?: string;
|
|
28
|
+
} & Omit<ComponentPropsWithoutRef<'span'>, 'children'>;
|
|
29
|
+
export default function Countdown({ value, onFinish, format, render, className, ...rest }: CountdownProps): import("react").JSX.Element;
|
|
30
|
+
export type { CountdownProps, CountdownParts };
|
|
@@ -20,6 +20,10 @@ import type { FloatingPlacement } from '../../utils/floating';
|
|
|
20
20
|
* the panel cancels the pending close (the "resting zone"). Escape
|
|
21
21
|
* closes at once (native popover light dismiss / the fallback path's
|
|
22
22
|
* document keydown, both owned by useFloating).
|
|
23
|
+
*
|
|
24
|
+
* `interactive` upgrades the card to React Aria's PreviewTrigger
|
|
25
|
+
* semantics: focusable content, focus handoff trigger ↔ card, Escape
|
|
26
|
+
* returning focus to the trigger — see the prop for the contract.
|
|
23
27
|
*/
|
|
24
28
|
type HoverCardProps = {
|
|
25
29
|
/** Card content, rendered inside the floating panel. */
|
|
@@ -31,6 +35,19 @@ type HoverCardProps = {
|
|
|
31
35
|
* before the card closes — long enough to travel into the panel.
|
|
32
36
|
*/
|
|
33
37
|
closeDelay?: number;
|
|
38
|
+
/**
|
|
39
|
+
* Interactive card contents (React Aria PreviewTrigger semantics):
|
|
40
|
+
* focusable elements inside `content` join the Tab order and focus
|
|
41
|
+
* may travel between the trigger and the card without closing it.
|
|
42
|
+
* The pointer grace after leaving the trigger/panel defaults to
|
|
43
|
+
* 300 ms in this mode (vs 120 ms otherwise; an explicit `closeDelay`
|
|
44
|
+
* or a ConfigProvider default still overrides). While focus rests
|
|
45
|
+
* inside the card, pointer leaves alone no longer close it — Escape
|
|
46
|
+
* or tabbing out does, and Escape hands focus back to the trigger.
|
|
47
|
+
* Focus is deliberately NOT trapped: a hover card is a preview, not
|
|
48
|
+
* a modal, so Tab must keep reaching the rest of the page.
|
|
49
|
+
*/
|
|
50
|
+
interactive?: boolean;
|
|
34
51
|
/**
|
|
35
52
|
* Panel placement relative to the trigger, in the floating utils'
|
|
36
53
|
* physical convention ('bottom-span' aligns the panel's inline-start
|
|
@@ -45,5 +62,5 @@ type HoverCardProps = {
|
|
|
45
62
|
/** The trigger — render a focusable element for keyboard access. */
|
|
46
63
|
children: ReactNode;
|
|
47
64
|
};
|
|
48
|
-
export default function HoverCard({ content, openDelay: openDelayProp, closeDelay: closeDelayProp, placement, open: openControl, collisionPadding, className, children, }: HoverCardProps): import("react").JSX.Element;
|
|
65
|
+
export default function HoverCard({ content, openDelay: openDelayProp, closeDelay: closeDelayProp, interactive, placement, open: openControl, collisionPadding, className, children, }: HoverCardProps): import("react").JSX.Element;
|
|
49
66
|
export type { HoverCardProps };
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import type { ComponentPropsWithoutRef, Ref } from 'react';
|
|
2
|
+
import type { ControlOrValue } from 'react-use-control';
|
|
3
|
+
import type { CropRect } from './image-crop-geometry';
|
|
4
|
+
/**
|
|
5
|
+
* Interactive image cropper — the avatar/photo companion to Upload.
|
|
6
|
+
*
|
|
7
|
+
* The source image is painted onto a `<canvas>` sized to its natural
|
|
8
|
+
* pixels (max detail; CSS scales it down), and the crop box is a DOM
|
|
9
|
+
* overlay positioned in percentages of the same box, so `value` needs no
|
|
10
|
+
* pixel measurement to render. `value` is the crop rectangle normalized
|
|
11
|
+
* to the image (every field 0..1) and fully controllable; every commit
|
|
12
|
+
* path (drag, handle resize, keyboard) runs through the same clamp
|
|
13
|
+
* pipeline, so an illegal rect can never display.
|
|
14
|
+
*
|
|
15
|
+
* Keyboard (the part competitors skip): the crop box is focusable and
|
|
16
|
+
* labeled. Arrow keys move it (1% of the image per press), Shift + arrow
|
|
17
|
+
* keys resize it — the Resizable handle's pointer-free contract in
|
|
18
|
+
* normalized space. A `visually-hidden` description announces the live
|
|
19
|
+
* geometry so screen readers track drags too.
|
|
20
|
+
*
|
|
21
|
+
* `ref.getCroppedCanvas()` rasterizes the current crop into a fresh
|
|
22
|
+
* `HTMLCanvasElement` (`null` when the image has not loaded or the 2d
|
|
23
|
+
* context is unavailable — jsdom without a mock). When the 2d context is
|
|
24
|
+
* unavailable the whole cropper degrades to a notice (Signature
|
|
25
|
+
* precedent): without paint there is no image to crop.
|
|
26
|
+
*/
|
|
27
|
+
type ImageCropProps = {
|
|
28
|
+
/** Image source URL. */
|
|
29
|
+
src: string;
|
|
30
|
+
/** Accessible name of the rendered image (carried by the canvas). */
|
|
31
|
+
alt: string;
|
|
32
|
+
/** Crop rectangle normalized to the image (every field 0..1); a
|
|
33
|
+
* Control receives every commit live, a plain object seeds it. */
|
|
34
|
+
value?: ControlOrValue<CropRect>;
|
|
35
|
+
/** Fires with the new normalized rect on every pointer frame and
|
|
36
|
+
* keyboard step. */
|
|
37
|
+
onChange?: (rect: CropRect) => void;
|
|
38
|
+
/** Locks the crop's pixel-space aspect ratio (width / height, e.g. `1`
|
|
39
|
+
* for avatars). Height derives from width; a rect that cannot fit
|
|
40
|
+
* refits from its height budget. */
|
|
41
|
+
aspect?: number;
|
|
42
|
+
/** Overlay mask of the crop box: rectangular frame or a full-radius
|
|
43
|
+
* circle for avatars (pair with `aspect={1}` for a true circle). */
|
|
44
|
+
shape?: 'rect' | 'circle';
|
|
45
|
+
/** Accessible label of the focusable crop region. */
|
|
46
|
+
cropLabel?: string;
|
|
47
|
+
/** Notice rendered when the canvas 2d context is unavailable. */
|
|
48
|
+
unsupportedLabel?: string;
|
|
49
|
+
/** Notice rendered when `src` fails to load. */
|
|
50
|
+
errorLabel?: string;
|
|
51
|
+
/** Locks dragging, handle resizing and keyboard operation. */
|
|
52
|
+
disabled?: boolean;
|
|
53
|
+
/** Passed to the loader `<img>`; `anonymous` is required for
|
|
54
|
+
* CORS-clean hosts or `getCroppedCanvas` output stays tainted. */
|
|
55
|
+
crossOrigin?: 'anonymous' | 'use-credentials';
|
|
56
|
+
className?: string;
|
|
57
|
+
ref?: Ref<ImageCropHandle>;
|
|
58
|
+
} & Omit<ComponentPropsWithoutRef<'div'>, 'onChange'>;
|
|
59
|
+
/** Imperative surface exposed through the component `ref`. */
|
|
60
|
+
type ImageCropHandle = {
|
|
61
|
+
/** Fresh canvas holding the current crop at native pixel resolution,
|
|
62
|
+
* or `null` when the image has not loaded / 2d context is missing. */
|
|
63
|
+
getCroppedCanvas: () => HTMLCanvasElement | null;
|
|
64
|
+
};
|
|
65
|
+
export default function ImageCrop({ src, alt, value: valueControl, onChange, aspect, shape, cropLabel, unsupportedLabel, errorLabel, disabled, crossOrigin, className, ref, ...rest }: ImageCropProps): import("react").JSX.Element;
|
|
66
|
+
export type { ImageCropProps, ImageCropHandle };
|
|
67
|
+
export type { CropRect } from './image-crop-geometry';
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure geometry for ImageCrop — every exported helper works in normalized
|
|
3
|
+
* space (0..1 relative to the image's own pixel box) so pointer, keyboard
|
|
4
|
+
* and aspect math share one clamp story. Unit tests exercise these
|
|
5
|
+
* directly (the signature-points precedent).
|
|
6
|
+
*/
|
|
7
|
+
/** Normalized crop rectangle: top-left corner (x, y) and size, every
|
|
8
|
+
* field 0..1 relative to the image's own pixel box. */
|
|
9
|
+
export type CropRect = {
|
|
10
|
+
x: number;
|
|
11
|
+
y: number;
|
|
12
|
+
width: number;
|
|
13
|
+
height: number;
|
|
14
|
+
};
|
|
15
|
+
/** Natural pixel size of the loaded source image. */
|
|
16
|
+
export type NaturalSize = {
|
|
17
|
+
width: number;
|
|
18
|
+
height: number;
|
|
19
|
+
};
|
|
20
|
+
/** Corner handles of the crop box. */
|
|
21
|
+
export type CropCorner = 'nw' | 'ne' | 'sw' | 'se';
|
|
22
|
+
/** Size floor for the crop box on both axes — a box smaller than this is
|
|
23
|
+
* no longer grabbable and crops to a degenerate image. */
|
|
24
|
+
export declare const MIN_CROP = 0.05;
|
|
25
|
+
/** Keyboard step for arrow keys: 1% of the image per press (the Resizable
|
|
26
|
+
* handle's fully-pointer-free contract, scaled to normalized space). */
|
|
27
|
+
export declare const KEYBOARD_STEP = 0.01;
|
|
28
|
+
/** Fit a rect to a locked pixel-space aspect ratio. Width drives; when
|
|
29
|
+
* the derived height overflows the unit square the height clamps to 1
|
|
30
|
+
* and the width re-derives from it. Position keeps x/y, clamped so the
|
|
31
|
+
* box stays inside the image. */
|
|
32
|
+
export declare function fitAspect(rect: CropRect, aspect: number, natural: NaturalSize): CropRect;
|
|
33
|
+
/** Clamp any rect into a legal crop: sizes into [MIN_CROP, 1] — with an
|
|
34
|
+
* aspect refit when the ratio is locked — and the position so the box
|
|
35
|
+
* stays inside the unit square. Display and every commit path run
|
|
36
|
+
* through this, so a stale or consumer-supplied value can never paint an
|
|
37
|
+
* illegal box. */
|
|
38
|
+
export declare function normalizeRect(rect: CropRect, aspect: number | undefined, natural: NaturalSize): CropRect;
|
|
39
|
+
/** Centered default crop covering 80% of the image (aspect-refit first —
|
|
40
|
+
* a square crop of a wide image saturates height before width, then the
|
|
41
|
+
* smaller box recenters). */
|
|
42
|
+
export declare function defaultRect(aspect: number | undefined, natural: NaturalSize): CropRect;
|
|
43
|
+
/** Translate by (dx, dy) — position clamps inside the image, size is
|
|
44
|
+
* frozen (the keyboard move contract). */
|
|
45
|
+
export declare function moveRect(rect: CropRect, dx: number, dy: number): CropRect;
|
|
46
|
+
/** Keyboard resize anchored at the top-left corner: dw/dh grow the box
|
|
47
|
+
* towards the right/bottom. With a locked aspect both axes drive the
|
|
48
|
+
* shared width (dh is translated through the aspect factor), so all four
|
|
49
|
+
* Shift+arrow keys stay functional. */
|
|
50
|
+
export declare function resizeRect(rect: CropRect, dw: number, dh: number, aspect: number | undefined, natural: NaturalSize): CropRect;
|
|
51
|
+
/** Corner-handle resize: the opposite corner stays anchored and the
|
|
52
|
+
* dragged corner follows the normalized pointer. Dragging across the
|
|
53
|
+
* anchor floors at MIN_CROP instead of inverting; a locked aspect fits
|
|
54
|
+
* width-first, clamped to the space the anchor leaves. */
|
|
55
|
+
export declare function resizeFromAnchor(start: CropRect, corner: CropCorner, pointer: {
|
|
56
|
+
x: number;
|
|
57
|
+
y: number;
|
|
58
|
+
}, aspect: number | undefined, natural: NaturalSize): CropRect;
|
|
59
|
+
/** Frame-relative normalized pointer position from client coordinates.
|
|
60
|
+
* The width/height guards keep a zero-sized rect (jsdom, not-yet-laid-out
|
|
61
|
+
* frames) from producing NaN instead of merely useless numbers. */
|
|
62
|
+
export declare function pointerToNormalized(clientX: number, clientY: number, frame: DOMRect): {
|
|
63
|
+
x: number;
|
|
64
|
+
y: number;
|
|
65
|
+
};
|
|
@@ -228,6 +228,12 @@ declare const defaultStrings: {
|
|
|
228
228
|
spinner: {
|
|
229
229
|
loading: string;
|
|
230
230
|
};
|
|
231
|
+
splitter: {
|
|
232
|
+
collapseLead: string;
|
|
233
|
+
expandLead: string;
|
|
234
|
+
collapseTrail: string;
|
|
235
|
+
expandTrail: string;
|
|
236
|
+
};
|
|
231
237
|
sources: {
|
|
232
238
|
label: string;
|
|
233
239
|
expand: string;
|
|
@@ -1,4 +1,2 @@
|
|
|
1
1
|
export { ResizableGroup, ResizablePanel, ResizableHandle } from './Resizable';
|
|
2
2
|
export type { ResizableGroupProps, ResizablePanelProps, ResizableHandleProps, } from './Resizable';
|
|
3
|
-
export { ResizableGroup as SplitterGroup, ResizablePanel as SplitterPanel, ResizableHandle as SplitterHandle, } from './Resizable';
|
|
4
|
-
export type { ResizableGroupProps as SplitterGroupProps, ResizablePanelProps as SplitterPanelProps, ResizableHandleProps as SplitterHandleProps, } from './Resizable';
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { ComponentPropsWithoutRef, ReactNode } from 'react';
|
|
2
|
+
import type { ControlOrValue } from 'react-use-control';
|
|
3
|
+
type SplitterProps = {
|
|
4
|
+
/** Layout axis: horizontal stacks panes left-to-right, vertical
|
|
5
|
+
* top-to-bottom. */
|
|
6
|
+
orientation?: 'horizontal' | 'vertical';
|
|
7
|
+
/** Pane sizes in percent of the pane area (the container minus the
|
|
8
|
+
* dividers), one entry per pane, summing to 100. Accepts a Control for
|
|
9
|
+
* controlled usage or a plain array as the uncontrolled initial
|
|
10
|
+
* value (equal split when omitted). */
|
|
11
|
+
sizes?: ControlOrValue<number[]>;
|
|
12
|
+
/** Fired on every applied change — pointer moves and keyboard steps
|
|
13
|
+
* alike — with the full next sizes array. */
|
|
14
|
+
onSizesChange?: (sizes: number[]) => void;
|
|
15
|
+
children?: ReactNode;
|
|
16
|
+
className?: string;
|
|
17
|
+
} & Omit<ComponentPropsWithoutRef<'div'>, 'children'>;
|
|
18
|
+
export declare function Splitter({ orientation, sizes: sizesControl, onSizesChange, children, className, ...rest }: SplitterProps): import("react").JSX.Element;
|
|
19
|
+
type SplitterPaneProps = {
|
|
20
|
+
/** Minimum size in percent of the pane area. */
|
|
21
|
+
min?: number;
|
|
22
|
+
/** Maximum size in percent of the pane area. */
|
|
23
|
+
max?: number;
|
|
24
|
+
/** Opt the pane into divider collapse triggers: every divider
|
|
25
|
+
* touching it grows a button that zeroes the pane (the partner
|
|
26
|
+
* absorbs its share) and, once collapsed, expands it back to its
|
|
27
|
+
* pre-collapse size. */
|
|
28
|
+
collapsible?: boolean;
|
|
29
|
+
children?: ReactNode;
|
|
30
|
+
className?: string;
|
|
31
|
+
} & Omit<ComponentPropsWithoutRef<'div'>, 'min' | 'max'>;
|
|
32
|
+
export declare function SplitterPane({ min, max, collapsible, children, className, ...rest }: SplitterPaneProps): import("react").JSX.Element;
|
|
33
|
+
export type { SplitterProps, SplitterPaneProps };
|
|
@@ -337,11 +337,12 @@ export { useClickOutside };
|
|
|
337
337
|
export type { UseClickOutsideOptions } from '../hooks/useClickOutside';
|
|
338
338
|
/**
|
|
339
339
|
* Declarative keyboard shortcuts: a map of spec strings (`'mod+k'`,
|
|
340
|
-
* `'ctrl+shift+p'`, `'?'`, named keys
|
|
341
|
-
* window (or a ref target). `mod`
|
|
342
|
-
* Ctrl elsewhere), editable focus
|
|
343
|
-
* `allowInInput`,
|
|
344
|
-
*
|
|
340
|
+
* `'ctrl+shift+p'`, `'?'`, named keys, whitespace-joined sequences like
|
|
341
|
+
* `'g h'`) to handlers, listened on the window (or a ref target). `mod`
|
|
342
|
+
* normalizes per platform (⌘ on macOS, Ctrl elsewhere), editable focus
|
|
343
|
+
* suppresses fires unless `allowInInput`, sequences reset on a wrong key
|
|
344
|
+
* or after `sequenceTimeout` (default 1000ms), and the map may be an
|
|
345
|
+
* inline literal — a latest-ref keeps the listener mounted once.
|
|
345
346
|
*/
|
|
346
347
|
export { useHotkeys };
|
|
347
348
|
/**
|
|
@@ -357,7 +358,7 @@ export { hotkey };
|
|
|
357
358
|
export type { HotkeyHandler } from '../hooks/useHotkeys';
|
|
358
359
|
/**
|
|
359
360
|
* Options accepted by {@link useHotkeys}: `enabled`, `target` (element
|
|
360
|
-
* ref or `window`), `eventName` and `
|
|
361
|
+
* ref or `window`), `eventName`, `allowInInput` and `sequenceTimeout`.
|
|
361
362
|
*/
|
|
362
363
|
export type { UseHotkeysOptions } from '../hooks/useHotkeys';
|
|
363
364
|
/**
|
|
@@ -10,16 +10,19 @@ type UseHotkeysOptions = {
|
|
|
10
10
|
eventName?: 'keydown' | 'keyup';
|
|
11
11
|
/** 焦点在 input/textarea/select/contenteditable 内时是否仍触发(默认 `false`)。 */
|
|
12
12
|
allowInInput?: boolean;
|
|
13
|
+
/** 序列快捷键相邻两步的最大间隔毫秒,超时清空进度(默认 `1000`)。 */
|
|
14
|
+
sequenceTimeout?: number;
|
|
13
15
|
};
|
|
14
16
|
/**
|
|
15
17
|
* 组合多个快捷键规格为一条别名绑定(逗号连接),任一命中即触发同一
|
|
16
18
|
* handler——对象字面量的键只能是字符串,数组规格经由本函数进入。
|
|
19
|
+
* 规格可以是单键组合或序列(含空白,如 `'g h'`)。
|
|
17
20
|
*
|
|
18
21
|
* ```tsx
|
|
19
22
|
* useHotkeys({ [hotkey('mod+k', 'mod+j')]: cyclePalette });
|
|
20
23
|
* ```
|
|
21
24
|
*
|
|
22
|
-
* @param specs 至少一个规格,如 `'mod+k'`、`'ctrl+shift+p'`。
|
|
25
|
+
* @param specs 至少一个规格,如 `'mod+k'`、`'ctrl+shift+p'`、`'g h'`。
|
|
23
26
|
*/
|
|
24
27
|
export declare function hotkey(...specs: [string, ...string[]]): string;
|
|
25
28
|
/**
|
|
@@ -32,6 +35,8 @@ export declare function hotkey(...specs: [string, ...string[]]): string;
|
|
|
32
35
|
* 'ctrl+shift+p': openCommandPalette,
|
|
33
36
|
* '?': showHelp, // 符号键天然携带 shift,无需声明
|
|
34
37
|
* ArrowUp: selectPrev, // 命名键精确匹配
|
|
38
|
+
* 'g h': goHome, // 序列:先 g 再 h(步间默认 1s)
|
|
39
|
+
* 'ctrl+k g': goHome, // 修饰键组合可作序列元素
|
|
35
40
|
* [hotkey('mod+k', 'mod+j')]: cycle, // 多规格别名:任一命中
|
|
36
41
|
* }, { allowInInput: false });
|
|
37
42
|
* ```
|
|
@@ -39,11 +44,18 @@ export declare function hotkey(...specs: [string, ...string[]]): string;
|
|
|
39
44
|
* - 规格语法:`[修饰键+]*键`;修饰键别名 mod/ctrl/control/meta/cmd/⌘/
|
|
40
45
|
* shift/alt/option/⌥;`mod` 按平台归一(macOS ⌘,否则 ctrl,
|
|
41
46
|
* `navigator.platform` 判定,SSR 安全)。
|
|
47
|
+
* - 序列语法:空白分隔多个步骤(`'g h'`、`'ctrl+k g g'`),每步是独立的
|
|
48
|
+
* 规格并沿用严格修饰键校验(未声明的 ctrl/alt/meta 必须抬起)。相邻
|
|
49
|
+
* 两步间隔超过 `sequenceTimeout`(默认 1000ms)重置;中途按错键重置
|
|
50
|
+
* ——但错键若本身是某序列的首步(如 `g g h` 的第二个 g)则从该键重新
|
|
51
|
+
* 起步,若命中任何单键绑定则照常触发该绑定并清空进度。推进中的步骤
|
|
52
|
+
* 不 `preventDefault`,序列完整命中才拦截事件;命中后进度清零,
|
|
53
|
+
* 同一序列可立即重新输入。
|
|
42
54
|
* - 默认焦点在 input/textarea/select/contenteditable 时忽略全部快捷键,
|
|
43
55
|
* `allowInInput: true` 打开。
|
|
44
|
-
* -
|
|
45
|
-
*
|
|
46
|
-
*
|
|
56
|
+
* - 一个事件只触发第一个命中的绑定(含序列完成);`hotkeys` 映射每次
|
|
57
|
+
* 渲染变化不重挂监听(latest-ref),`enabled/target/eventName/
|
|
58
|
+
* allowInInput/sequenceTimeout` 变化才重新绑定(重绑会清空序列进度)。
|
|
47
59
|
* - `enabled: false` 等价于不挂载监听。
|
|
48
60
|
*
|
|
49
61
|
* @param hotkeys 规格(或逗号连接的规格列表)到处理器的映射。
|
package/dist/types/index.d.ts
CHANGED
|
@@ -106,8 +106,8 @@ export { Command, CommandInput, CommandList, CommandItem, CommandGroup, CommandD
|
|
|
106
106
|
export type { CommandProps, CommandInputProps, CommandListProps, CommandItemProps, CommandGroupProps, CommandDialogProps } from './components/Command';
|
|
107
107
|
export { ResizableGroup, ResizablePanel, ResizableHandle } from './components/Resizable';
|
|
108
108
|
export type { ResizableGroupProps, ResizablePanelProps, ResizableHandleProps } from './components/Resizable';
|
|
109
|
-
export {
|
|
110
|
-
export type {
|
|
109
|
+
export { Splitter, SplitterPane } from './components/Splitter';
|
|
110
|
+
export type { SplitterProps, SplitterPaneProps } from './components/Splitter';
|
|
111
111
|
export { Collapsible, CollapsibleTrigger, CollapsibleContent } from './components/Collapsible';
|
|
112
112
|
export type { CollapsibleProps, CollapsibleTriggerProps, CollapsibleContentProps, CollapsibleClassNames } from './components/Collapsible';
|
|
113
113
|
export { Transfer, TransferCore } from './components/Transfer';
|
|
@@ -127,6 +127,8 @@ export { Ellipsis } from './components/Ellipsis';
|
|
|
127
127
|
export type { EllipsisProps } from './components/Ellipsis';
|
|
128
128
|
export { CountUp } from './components/CountUp';
|
|
129
129
|
export type { CountUpProps } from './components/CountUp';
|
|
130
|
+
export { Countdown } from './components/Countdown';
|
|
131
|
+
export type { CountdownProps, CountdownParts } from './components/Countdown';
|
|
130
132
|
export { Sparkline, sparklineToneStrokes, sparklineToneFills } from './components/Sparkline';
|
|
131
133
|
export type { SparklineProps } from './components/Sparkline';
|
|
132
134
|
export type { StatProps, StatGroupProps } from './components/Stat';
|
|
@@ -290,6 +292,9 @@ export { Masonry } from './components/Masonry';
|
|
|
290
292
|
export type { MasonryProps } from './components/Masonry';
|
|
291
293
|
export { Signature } from './components/Signature';
|
|
292
294
|
export type { SignatureProps } from './components/Signature';
|
|
295
|
+
export { ImageCrop } from './components/ImageCrop';
|
|
296
|
+
export type { ImageCropHandle, ImageCropProps } from './components/ImageCrop';
|
|
297
|
+
export type { CropRect } from './components/ImageCrop';
|
|
293
298
|
export { useTitle, useMediaQuery, usePrefersReducedMotion, useDebouncedValue, useDebouncedCallback, useDarkMode, useClipboard, useFullscreen, } from './hooks';
|
|
294
299
|
export type { UseClipboardResult } from './hooks';
|
|
295
300
|
export type { FullscreenTarget, UseFullscreenHandle } from './hooks';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "haze-ui",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.33.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "A React UI component library powered by react-use-control and Linaria",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -101,6 +101,7 @@
|
|
|
101
101
|
],
|
|
102
102
|
"author": "wmzy",
|
|
103
103
|
"license": "MIT",
|
|
104
|
+
"homepage": "https://wmzy.github.io/haze-ui/",
|
|
104
105
|
"peerDependencies": {
|
|
105
106
|
"react": "^19.0.0",
|
|
106
107
|
"react-dom": "^19.0.0"
|
|
@@ -175,7 +176,7 @@
|
|
|
175
176
|
"name": "Button only (bundled from barrel)",
|
|
176
177
|
"path": "dist/index.js",
|
|
177
178
|
"import": "{Button}",
|
|
178
|
-
"limit": "5.
|
|
179
|
+
"limit": "5.85 KB"
|
|
179
180
|
},
|
|
180
181
|
{
|
|
181
182
|
"name": "TagGroup+TagGroupItem only — dnd-free (bundled from barrel)",
|
|
@@ -204,11 +205,11 @@
|
|
|
204
205
|
{
|
|
205
206
|
"name": "CSS aggregate (dist/haze-ui.css, brotli)",
|
|
206
207
|
"path": "dist/haze-ui.css",
|
|
207
|
-
"limit": "
|
|
208
|
+
"limit": "27 KB"
|
|
208
209
|
},
|
|
209
210
|
{
|
|
210
211
|
"path": "dist/haze-ui.css",
|
|
211
|
-
"limit": "
|
|
212
|
+
"limit": "36 KB",
|
|
212
213
|
"gzip": true
|
|
213
214
|
},
|
|
214
215
|
{
|
|
@@ -229,6 +230,24 @@
|
|
|
229
230
|
"limit": "0.3 KB",
|
|
230
231
|
"gzip": true
|
|
231
232
|
},
|
|
233
|
+
{
|
|
234
|
+
"name": "CSS family ratchet: countdown",
|
|
235
|
+
"path": "dist/css/countdown.css",
|
|
236
|
+
"limit": "0.2 KB",
|
|
237
|
+
"gzip": true
|
|
238
|
+
},
|
|
239
|
+
{
|
|
240
|
+
"name": "CSS family ratchet: splitter",
|
|
241
|
+
"path": "dist/css/splitter.css",
|
|
242
|
+
"limit": "1 KB",
|
|
243
|
+
"gzip": true
|
|
244
|
+
},
|
|
245
|
+
{
|
|
246
|
+
"name": "CSS family ratchet: image-crop",
|
|
247
|
+
"path": "dist/css/image-crop.css",
|
|
248
|
+
"limit": "0.85 KB",
|
|
249
|
+
"gzip": true
|
|
250
|
+
},
|
|
232
251
|
{
|
|
233
252
|
"name": "CSS family ratchet: sparkline",
|
|
234
253
|
"path": "dist/css/sparkline.css",
|