Skip to content

packages/core/src/lib/components/horizontal-line.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   PixelGridAlignment,
9   RenderingContext2D,
10   SystemStyle,
11 } from '../types.js';
12 import type { PibblPhysics2DPropExtension } from '../types.js';
13 import { adjustForPixelGrid } from '../util/pixel-grid-adjustments.js';
14 import {
15   resolveLocalOffset,
16   resolveRequiredLength,
17   stripLayoutParticipation,
18 } from '../style/resolve-built-in.js';
19 import { registerOpaqueStyleProperties } from '../style/resolve-dispatch.js';
20 import type {
21   BoxStyle,
22   LayoutItemStyle,
23   Length,
24   ResolvedDrawingStyle,
25 } from '../style/types.js';
26 import { renderLine, type LineStyle } from './line.js';
27 
28 /**
29  * Authored inputs for HorizontalLine, including the declared data and presentation options.
30  *
31  * @see {@link PibblEventHandlers}
32  * @see {@link PibblEventParticipationOptions}
33  * @see {@link PibblPhysics2DPropExtension}
34  * @see {@link HorizontalLine}
35  */
36 export interface HorizontalLineProps
37   extends PibblEventHandlers, PibblEventFocusOptions, PibblEventParticipationOptions, PibblPhysics2DPropExtension {}
38 
39 /**
40  * Supported geometry and presentation properties for HorizontalLine.
41  *
42  * @see {@link SystemStyle}
43  * @see {@link BoxStyle}
44  * @see {@link LayoutItemStyle}
45  * @see {@link LineStyle}
46  * @see {@link Length}
47  * @see {@link PixelGridAlignment}
48  * @see {@link HorizontalLine}
49  */
50 export interface HorizontalLineStyle
51   extends SystemStyle, BoxStyle, LayoutItemStyle, Omit<LineStyle, 'coords'> {
52   /**
53    * Vertical coordinate or displacement in the containing coordinate system. See {@link Length}.
54    */
55   y: Exclude<Length, 'auto'>;
56   /** Horizontal coordinate of the first endpoint. See {@link Length}. */
57   x1?: Exclude<Length, 'auto'>;
58   /** Horizontal coordinate of the second endpoint. See {@link Length}. */
59   x2?: Exclude<Length, 'auto'>;
60   /**
61    * Pixel-grid alignment policy applied to the resolved geometry. See {@link PixelGridAlignment}.
62    */
63   alignToPixelGrid?: PixelGridAlignment;
64   /**
65    * Width used for line hit testing independently of the visible stroke width. See
66    * {@link HorizontalLineStyle}.
67    */
68   lineInteractionWidth?: number;
69 }
70 
71 type ResolvedHorizontalLineStyle = ResolvedDrawingStyle<HorizontalLineStyle> & {
72   y: number;
73   x1: number;
74   x2: number;
75 };
76 
77 function renderHorizontalLine(
78   props: HorizontalLineProps,
79   style: Readonly<ResolvedHorizontalLineStyle>,
80   ctx: RenderingContext2D,
81 ) {
82   const {
83     y: initialY,
84     x1 = 0,
85     x2 = ctx.canvas.width,
86     alignToPixelGrid = 'none',
87     stroke,
88     strokeWidth,
89     opacity,
90     cursor,
91     lineInteractionWidth,
92   } = style;
93   const y = adjustForPixelGrid(
94     initialY,
95     strokeWidth,
96     alignToPixelGrid,
97   );
98   const coords: [number, number][] = [
99     [x1, y],
100     [x2, y],
101   ];
102   return renderLine(
103     props,
104     {
105       coords,
106       stroke,
107       strokeWidth,
108       opacity,
109       cursor,
110       lineInteractionWidth,
111     },
112     ctx,
113   );
114 }
115 
116 /**
117  * Describes a horizontal-line primitive for JSX or createElement authoring.
118  *
119  * @param props - Authored component inputs, supplied through JSX or createElement. See the linked
120  * props and style types.
121  * @throws When called directly; Pibbl mounts this component through JSX or createElement.
122  *
123  * @see {@link HorizontalLineProps}
124  * @see {@link HorizontalLineStyle}
125  */
126 export const HorizontalLine = definePrimitive<
127   HorizontalLineProps,
128   HorizontalLineStyle,
129   HorizontalLineStyle,
130   ResolvedHorizontalLineStyle
131 >(renderHorizontalLine, {
132   resolveStyle: (style, context) => ({
133     ...stripLayoutParticipation(style),
134     y: resolveRequiredLength(
135       style.y,
136       context.percentageBasis.height,
137       'y',
138       context,
139     ),
140     x1: resolveLocalOffset(
141       style.x1,
142       context.percentageBasis.width,
143       'x1',
144       context,
145     ),
146     x2: resolveRequiredLength(
147       style.x2 ?? context.allocation.width,
148       context.percentageBasis.width,
149       'x2',
150       context,
151     ),
152   }) as ResolvedHorizontalLineStyle,
153 });
154 registerOpaqueStyleProperties(HorizontalLine, ['stroke', 'cursor']);
155 

Documentation built with @pibbl/core 0.0.2, revision 272a94a. ALPHA — NOT FOR PRODUCTION USE.