packages/core/src/lib/manipulation/manipulable.ts
This is the source snapshot used to build these API details. View this revision on GitHub.
1 import { createElement } from "../element/create-element.js";
2 import type { PibblNode } from "../element/types.js";
3 import type { WritableSignal } from "../signals/types.js";
4 import { useManipulation } from "./controller.js";
5 import type {
6 PibblManipulationOptions,
7 PibblManipulationMoveInput,
8 PibblManipulationResizeInput,
9 PibblManipulationRotateInput,
10 } from "./controller-types.js";
11 import { ManipulationFrame } from "./frame.js";
12 import { DragHandle, ResizeHandles, RotationHandle } from "./handles.js";
13 import type {
14 PibblResizeHandlesProps,
15 PibblDragHandleProps,
16 PibblDragHandleStyle,
17 PibblRotationHandleProps,
18 PibblRotationHandleStyle,
19 } from "./handles.js";
20 import type { PibblManipulationBox } from "./types.js";
21
22 /**
23 * Authored inputs for Manipulable, including the declared data and presentation options.
24 *
25 * @see {@link PibblManipulationOptions}
26 * @see {@link WritableSignal}
27 * @see {@link PibblManipulationBox}
28 * @see {@link PibblManipulationMoveInput}
29 * @see {@link PibblManipulationResizeInput}
30 * @see {@link PibblManipulationRotateInput}
31 * @see {@link PibblResizeHandlesProps}
32 * @see {@link PibblRotationHandleProps}
33 * @see {@link PibblRotationHandleStyle}
34 * @see {@link PibblDragHandleProps}
35 * @see {@link PibblDragHandleStyle}
36 * @see {@link PibblNode}
37 * @see {@link Manipulable}
38 */
39 export interface PibblManipulableProps extends Pick<
40 PibblManipulationOptions,
41 "rotation" | "onStart" | "onChange" | "onCommit" | "onCancel"
42 > {
43 /**
44 * Declared presentation and layout properties. See {@link WritableSignal},
45 * {@link PibblManipulationBox}.
46 */
47 readonly style: WritableSignal<PibblManipulationBox>;
48 /** Enables or configures translation of the target. See {@link PibblManipulationMoveInput}. */
49 readonly draggable?: boolean | PibblManipulationMoveInput;
50 /** Enables or configures resizing of the target. See {@link PibblManipulationResizeInput}. */
51 readonly resizable?: boolean | PibblManipulationResizeInput;
52 /** Enables or configures rotation of the target. See {@link PibblManipulationRotateInput}. */
53 readonly rotatable?: boolean | PibblManipulationRotateInput;
54 /** Configuration of the target's resize handles. See {@link PibblResizeHandlesProps}. */
55 readonly resizeHandles?:
56 PibblResizeHandlesProps["positions"] | Omit<PibblResizeHandlesProps, "controller">;
57 /**
58 * Configuration of the target's rotation handle. See {@link PibblRotationHandleProps},
59 * {@link PibblRotationHandleStyle}.
60 */
61 readonly rotationHandle?: Omit<PibblRotationHandleProps, "controller" | "children"> & {
62 /** Declared presentation and layout properties. See {@link PibblRotationHandleStyle}. */
63 readonly style?: PibblRotationHandleStyle;
64 };
65 /**
66 * Configuration of the target's drag handle. See {@link PibblDragHandleProps},
67 * {@link PibblDragHandleStyle}.
68 */
69 readonly dragHandle?: Omit<PibblDragHandleProps, "controller" | "children"> & {
70 /** Declared presentation and layout properties. See {@link PibblDragHandleStyle}. */
71 readonly style?: PibblDragHandleStyle;
72 };
73 /** Descendant content or the callback that supplies it. See {@link PibblNode}. */
74 readonly children?: PibblNode;
75 }
76 function operation<T>(value: boolean | T | undefined): T | undefined {
77 return value === undefined || value === false
78 ? undefined
79 : value === true
80 ? ({} as T)
81 : value;
82 }
83 /**
84 * Compose the same signal-owned frame and handles used by useManipulation.
85 *
86 * @param props - Manipulation controller and child content. See {@link PibblManipulableProps}.
87 * @returns Child content with manipulation interaction applied. See {@link PibblNode}.
88 *
89 * @see {@link PibblManipulableProps}
90 * @see {@link PibblNode}
91 */
92 export function Manipulable(props: PibblManipulableProps): PibblNode {
93 const controller = useManipulation({
94 box: props.style,
95 rotation: props.rotation,
96 move: operation(props.draggable),
97 resize: operation(props.resizable),
98 rotate: operation(props.rotatable),
99 onStart: props.onStart,
100 onChange: props.onChange,
101 onCommit: props.onCommit,
102 onCancel: props.onCancel,
103 });
104 const resizeHandles =
105 Array.isArray(props.resizeHandles) ||
106 props.resizeHandles === "corners" ||
107 props.resizeHandles === "edges-and-corners"
108 ? { positions: props.resizeHandles }
109 : props.resizeHandles;
110 return createElement(ManipulationFrame, {
111 ...controller.frameProps,
112 children: [
113 createElement(DragHandle, {
114 key: "content",
115 controller,
116 ...props.dragHandle,
117 style: { width: "100%", height: "100%", ...props.dragHandle?.style },
118 children: props.children,
119 }),
120 props.resizable &&
121 createElement(ResizeHandles, {
122 key: "resize",
123 controller,
124 ...resizeHandles,
125 }),
126 props.rotatable &&
127 createElement(RotationHandle, {
128 key: "rotate",
129 controller,
130 ...props.rotationHandle,
131 }),
132 ],
133 });
134 }
135
Documentation version
Section titled “Documentation version”Documentation built with @pibbl/core 0.0.2, revision 272a94a. ALPHA — NOT FOR PRODUCTION USE.