Skip to content

packages/core/src/lib/components/star.ts

Read as Markdown

This is the source snapshot used to build these API details. View this revision on GitHub.

Back to reference

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 built with @pibbl/core 0.0.2, revision 272a94a. ALPHA — NOT FOR PRODUCTION USE.