packages/core/src/lib/components/star.ts
This is the source snapshot used to build these API details. View this revision on GitHub.
1 import { definePrimitive } from '../define-primitive.js';
2 import type {
3 PibblEventFocusOptions,
4 PibblEventHandlers,
5 PibblEventParticipationOptions,
6 } from '../events/types.js';
7 import {
8 resolveStarGeometry,
9 type StarPathOptions,
10 } from '../geometry/star.js';
11 import {
12 integerAtLeast,
13 type GeometryErrorFactory,
14 } from '../geometry/validation.js';
15 import {
16 resolveLocalOffset,
17 stripLayoutParticipation,
18 } from '../style/resolve-built-in.js';
19 import { registerOpaqueStyleProperties } from '../style/resolve-dispatch.js';
20 import type {
21 BoxStyle,
22 CursorStyle,
23 LayoutItemStyle,
24 Length,
25 PaintStyle,
26 RoundedCornerStyle,
27 } from '../style/types.js';
28 import type { RenderingContext2D, SystemStyle } from '../types.js';
29 import type { PibblPhysics2DPropExtension } from '../types.js';
30 import { renderPath } from './path.js';
31 import { resolveRoundedCornerStyle } from './rounded-corner-style.js';
32 import {
33 circularPercentageBasis,
34 resolveFiniteShapeNumber,
35 resolveNonnegativeShapeLength,
36 shapeGeometryErrorFactory,
37 } from './shape-style.js';
38
39 /**
40 * Authored inputs for Star, including the declared data and presentation options.
41 *
42 * @see {@link PibblEventHandlers}
43 * @see {@link PibblEventParticipationOptions}
44 * @see {@link PibblPhysics2DPropExtension}
45 * @see {@link Star}
46 */
47 export interface StarProps extends PibblEventHandlers, PibblEventFocusOptions, PibblEventParticipationOptions, PibblPhysics2DPropExtension {}
48
49 /**
50 * Supported geometry and presentation properties for Star.
51 *
52 * @see {@link RoundedCornerStyle}
53 * @see {@link SystemStyle}
54 * @see {@link PaintStyle}
55 * @see {@link CursorStyle}
56 * @see {@link BoxStyle}
57 * @see {@link LayoutItemStyle}
58 * @see {@link Length}
59 * @see {@link Star}
60 */
61 export interface StarStyle
62 extends
63 RoundedCornerStyle,
64 SystemStyle,
65 PaintStyle,
66 CursorStyle,
67 BoxStyle,
68 LayoutItemStyle {
69 /** Points defining the geometry or reported by the contact query. See {@link StarStyle}. */
70 points: number;
71 /** Horizontal coordinate of the center. See {@link Length}. */
72 cx?: Exclude<Length, 'auto'>;
73 /** Vertical coordinate of the center. See {@link Length}. */
74 cy?: Exclude<Length, 'auto'>;
75 /** Radius of the outer boundary. See {@link Length}. */
76 outerRadius: Exclude<Length, 'auto'>;
77 /** Radius of the inner boundary. See {@link Length}. */
78 innerRadius: Exclude<Length, 'auto'>;
79 /** Rotation applied to the containing geometry. See {@link StarStyle}. */
80 rotation?: number;
81 /**
82 * Width used for line hit testing independently of the visible stroke width. See
83 * {@link StarStyle}.
84 */
85 lineInteractionWidth?: number;
86 }
87
88 interface ResolvedStarStyle extends SystemStyle, PaintStyle, CursorStyle {
89 points: number;
90 cx: number;
91 cy: number;
92 outerRadius: number;
93 innerRadius: number;
94 rotation: number;
95 cornerRadius?: number;
96 cornerRadii?: readonly (number | null | undefined)[];
97 lineInteractionWidth?: number;
98 geometryErrorFactory: GeometryErrorFactory;
99 }
100
101 function renderStar(
102 props: StarProps,
103 style: Readonly<ResolvedStarStyle>,
104 ctx: RenderingContext2D,
105 ) {
106 const {
107 points,
108 cx,
109 cy,
110 outerRadius,
111 innerRadius,
112 rotation,
113 cornerRadius,
114 cornerRadii,
115 geometryErrorFactory,
116 ...pathStyle
117 } = style;
118 const geometry = resolveStarGeometry({
119 points,
120 cx,
121 cy,
122 outerRadius,
123 innerRadius,
124 rotation,
125 cornerRadius,
126 cornerRadii,
127 } satisfies StarPathOptions, geometryErrorFactory);
128
129 return renderPath({
130 ...props,
131 keyboardNavigationBounds: props.keyboardNavigationBounds ?? geometry.bounds,
132 }, {
133 ...pathStyle,
134 d: geometry.path,
135 }, ctx);
136 }
137
138 /**
139 * Describes a star primitive for JSX or createElement authoring.
140 *
141 * @param props - Authored component inputs, supplied through JSX or createElement. See the linked
142 * props and style types.
143 * @throws When called directly; Pibbl mounts this component through JSX or createElement.
144 *
145 * @see {@link StarProps}
146 * @see {@link StarStyle}
147 */
148 export const Star = definePrimitive<
149 StarProps,
150 StarStyle,
151 StarStyle,
152 ResolvedStarStyle
153 >(renderStar, {
154 resolveStyle: (style, context) => {
155 const errorFactory = shapeGeometryErrorFactory(context);
156 const points = integerAtLeast(style.points, 3, 'points', errorFactory);
157 const basis = circularPercentageBasis(context);
158 return {
159 ...stripLayoutParticipation(style),
160 points,
161 cx: resolveLocalOffset(
162 style.cx,
163 context.percentageBasis.width,
164 'cx',
165 context,
166 ),
167 cy: resolveLocalOffset(
168 style.cy,
169 context.percentageBasis.height,
170 'cy',
171 context,
172 ),
173 outerRadius: resolveNonnegativeShapeLength(
174 style.outerRadius,
175 basis,
176 'outerRadius',
177 context,
178 ),
179 innerRadius: resolveNonnegativeShapeLength(
180 style.innerRadius,
181 basis,
182 'innerRadius',
183 context,
184 ),
185 rotation: resolveFiniteShapeNumber(
186 style.rotation ?? -Math.PI / 2,
187 'rotation',
188 context,
189 ),
190 ...resolveRoundedCornerStyle(points * 2, style, context),
191 geometryErrorFactory: errorFactory,
192 };
193 },
194 });
195 registerOpaqueStyleProperties(Star, ['fill', 'stroke', 'cursor']);
196
Documentation version
Section titled “Documentation version”Documentation built with @pibbl/core 0.0.2, revision 2dccb19. ALPHA — NOT FOR PRODUCTION USE.