Skip to content

Commit e467185

Browse files
committed
feat(tre): enhanced typings and documentation
1 parent ae66015 commit e467185

3 files changed

Lines changed: 76 additions & 17 deletions

File tree

packages/transient-render-engine/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
export type { StylesConfig, MixedStyleRecord } from './styles/types';
22
export * from './model/model-types';
33
export { default as HTMLElementModel } from './model/HTMLElementModel';
4+
export type { HTMLElementModelShape } from './model/HTMLElementModel';
45
export { default as HTMLContentModel } from './model/HTMLContentModel';
56
export type { TStylesShape } from './styles/TStyles';
67
export type {

packages/transient-render-engine/src/model/HTMLElementModel.ts

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ const translatableBlockCategories: ElementCategory[] = [
2424
* @typeParam T - The name of the tag to which the model will apply.
2525
* @typeParam M - The {@link HTMLContentModel} associated with this tag.
2626
*/
27-
export interface HTMLElementModelProperties<
27+
export interface HTMLElementModelShape<
2828
T extends string,
2929
M extends HTMLContentModel
3030
> extends ElementModelBase<T> {
@@ -42,6 +42,11 @@ export interface HTMLElementModelProperties<
4242
* have children.
4343
*/
4444
readonly isVoid: boolean;
45+
/**
46+
* An opaque element translated {@link TNode} will have no translated {@link TNode}
47+
* children.
48+
*/
49+
readonly isOpaque: boolean;
4550
}
4651

4752
/**
@@ -54,7 +59,7 @@ export interface HTMLElementModelProperties<
5459
export default class HTMLElementModel<
5560
T extends string,
5661
M extends HTMLContentModel
57-
> implements HTMLElementModelProperties<T, M>
62+
> implements HTMLElementModelShape<T, M>
5863
{
5964
/**
6065
* The tag name associated with this model.
@@ -144,7 +149,7 @@ export default class HTMLElementModel<
144149
setMarkersForTNode,
145150
getReactNativeProps,
146151
reactNativeProps
147-
}: HTMLElementModelProperties<T, M>) {
152+
}: HTMLElementModelShape<T, M>) {
148153
this.tagName = tagName;
149154
this.contentModel = contentModel;
150155
this.isOpaque = isOpaque || false;
@@ -248,24 +253,24 @@ export default class HTMLElementModel<
248253
*/
249254
extend<CM extends HTMLContentModel>(
250255
merger: (
251-
properties: HTMLElementModelProperties<T, CM>
252-
) => Partial<HTMLElementModelProperties<T, CM>>
256+
shape: HTMLElementModelShape<T, CM>
257+
) => Partial<HTMLElementModelShape<T, CM>>
253258
): HTMLElementModel<T, CM>;
254259
/**
255260
* Create a new {@link HTMLElementModel} by shallow-merging properties into this model.
256261
*
257-
* @param properties - The {@link HTMLElementModelProperties} to shallow-merge into this model.
262+
* @param shape - The {@link HTMLElementModelShape} to shallow-merge into this model.
258263
* @typeParam CM - The {@link HTMLContentModel} attached to the new model.
259264
*/
260265
extend<CM extends HTMLContentModel>(
261-
properties: Partial<HTMLElementModelProperties<T, CM>>
266+
shape: Partial<HTMLElementModelShape<T, CM>>
262267
): HTMLElementModel<T, CM>;
263268
extend<CM extends HTMLContentModel>(
264269
arg:
265270
| ((
266-
fields: HTMLElementModel<T, M>
267-
) => Partial<HTMLElementModelProperties<T, CM>>)
268-
| Partial<HTMLElementModelProperties<T, CM>>
271+
shape: HTMLElementModelShape<T, M>
272+
) => Partial<HTMLElementModelShape<T, CM>>)
273+
| Partial<HTMLElementModelShape<T, CM>>
269274
): HTMLElementModel<T, CM> {
270275
const properties = typeof arg === 'function' ? arg(this) : arg;
271276
return new HTMLElementModel<T, CM>({

packages/transient-render-engine/src/model/model-types.ts

Lines changed: 60 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -202,13 +202,34 @@ export interface ElementModelBase<T extends string> {
202202
readonly mixedUAStyles?: MixedStyleDeclaration;
203203

204204
/**
205-
* Default react Native props to pass to renderers.
205+
* React Native props grouped by native components. Those props
206+
* will be passed to the underlying native component at render time.
206207
*
207208
* @remarks Some props might be overriden by props derived from the
208209
* {@link TNode} attributes. For example, if you pass `accessibilityLabel`
209210
* and there is an `aria-label` attribute attached to one node, the
210211
* `aria-label` will be used. If you want to be able to override the
211212
* `aria-label`, use {@link getReactNativeProps} instead.
213+
*
214+
* @example
215+
*
216+
* ```ts
217+
* import {HTMLElementModel, HTMLContentModel} from 'react-native-render-html';
218+
*
219+
* const customHTMLElementModels = {
220+
* 'nav-button': HTMLElementModel.fromCustomModel({
221+
* tagName: 'nav-button',
222+
* contentModel: HTMLContentModel.block,
223+
* reactNativeProps: {
224+
* native: {
225+
* onPress() {
226+
* console.info('nav-button pressed');
227+
* },
228+
* },
229+
* },
230+
* }),
231+
*};
232+
* ```
212233
*/
213234
readonly reactNativeProps?: ReactNativePropsDefinitions;
214235

@@ -253,16 +274,48 @@ export interface ElementModelBase<T extends string> {
253274
) => MixedStyleDeclaration | null | undefined | void;
254275

255276
/**
256-
* A function to create conditional React Native props for a specific TNode.
277+
* A function to create React Native props from a {@link TNode} grouped by
278+
* native components.
279+
*
257280
* Those props will be deep-merged over the pre-generated props. You can
258281
* preserve some of the pre-generated props since you receive them as second
259282
* argument.
260283
*
261-
* **Merge strategy** (rightmost overrides leftmost): _static props from model_,
262-
* _auto-generated props from attributes_, _props returned by this function_.
284+
* **Merge strategy** (latest overrides former):
285+
*
286+
* 1. props from `reactNativeProps`,
287+
* 2. auto-generated props from attributes
288+
* 3. props returned by this function
263289
*
264-
* @param tnode - The TNode for which to create React Native props.
265-
* @param preGeneratedProps - The props that were pre-generated for the TNode based on attributes (style, aria-* ...) and {@link HTMLELementModel.reactNativeProps}.
290+
* @param tnode - The {@link TNode} for which to create React Native props.
291+
* @param preGeneratedProps - The props that were pre-generated for the {@link TNode}
292+
* based on attributes (e.g. aria-label ...) and
293+
* {@link ElementModelBase.reactNativeProps}.
294+
* @returns React Native props grouped by native components (see
295+
* {@link ReactNativePropsDefinitions}). Those props will be passed to the
296+
* underlying native component at render time.
297+
*
298+
* @example
299+
*
300+
* ```ts
301+
* import { defaultHTMLElementModels } from "react-native-render-html";
302+
*
303+
* const customHTMLElementModels = {
304+
* a: defaultHTMLElementModels.a.extend({
305+
* getReactNativeProps(tnode) {
306+
* const attributes = tnode.attributes;
307+
* return {
308+
* native: {
309+
* accessibilityHint:
310+
* attributes['data-scope'] === 'internal'
311+
* ? 'Open in a new screen.'
312+
* : 'Open in system web browser.',
313+
* },
314+
* };
315+
* },
316+
* }),
317+
* };
318+
* ```
266319
*/
267320
getReactNativeProps?: (
268321
tnode: ExtractTNodeFromType<TNodeType>,
@@ -288,7 +341,7 @@ export interface CustomElementModel<
288341
/**
289342
* The tag name associated with this model.
290343
*/
291-
readonly tagName: Exclude<T, TagName>;
344+
readonly tagName: T;
292345
}
293346

294347
/**

0 commit comments

Comments
 (0)