@nikpnevmatikos/html-renderer 0.1.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +19 -0
  3. package/dist/index.d.ts +7 -0
  4. package/dist/index.d.ts.map +1 -0
  5. package/dist/index.js +5 -0
  6. package/dist/index.js.map +1 -0
  7. package/dist/parser/parse.d.ts +3 -0
  8. package/dist/parser/parse.d.ts.map +1 -0
  9. package/dist/parser/parse.js +26 -0
  10. package/dist/parser/parse.js.map +1 -0
  11. package/dist/render-tree/build.d.ts +14 -0
  12. package/dist/render-tree/build.d.ts.map +1 -0
  13. package/dist/render-tree/build.js +299 -0
  14. package/dist/render-tree/build.js.map +1 -0
  15. package/dist/render-tree/hoist-blocks.d.ts +3 -0
  16. package/dist/render-tree/hoist-blocks.d.ts.map +1 -0
  17. package/dist/render-tree/hoist-blocks.js +48 -0
  18. package/dist/render-tree/hoist-blocks.js.map +1 -0
  19. package/dist/render-tree/whitespace.d.ts +3 -0
  20. package/dist/render-tree/whitespace.d.ts.map +1 -0
  21. package/dist/render-tree/whitespace.js +81 -0
  22. package/dist/render-tree/whitespace.js.map +1 -0
  23. package/dist/renderer/RenderedImage.d.ts +12 -0
  24. package/dist/renderer/RenderedImage.d.ts.map +1 -0
  25. package/dist/renderer/RenderedImage.js +60 -0
  26. package/dist/renderer/RenderedImage.js.map +1 -0
  27. package/dist/renderer/Renderer.d.ts +31 -0
  28. package/dist/renderer/Renderer.d.ts.map +1 -0
  29. package/dist/renderer/Renderer.js +309 -0
  30. package/dist/renderer/Renderer.js.map +1 -0
  31. package/dist/styles/css-parser.d.ts +18 -0
  32. package/dist/styles/css-parser.d.ts.map +1 -0
  33. package/dist/styles/css-parser.js +98 -0
  34. package/dist/styles/css-parser.js.map +1 -0
  35. package/dist/styles/normalize.d.ts +4 -0
  36. package/dist/styles/normalize.d.ts.map +1 -0
  37. package/dist/styles/normalize.js +14 -0
  38. package/dist/styles/normalize.js.map +1 -0
  39. package/dist/styles/parse-inline.d.ts +3 -0
  40. package/dist/styles/parse-inline.d.ts.map +1 -0
  41. package/dist/styles/parse-inline.js +169 -0
  42. package/dist/styles/parse-inline.js.map +1 -0
  43. package/dist/styles/selector-match.d.ts +8 -0
  44. package/dist/styles/selector-match.d.ts.map +1 -0
  45. package/dist/styles/selector-match.js +49 -0
  46. package/dist/styles/selector-match.js.map +1 -0
  47. package/dist/styles/split.d.ts +8 -0
  48. package/dist/styles/split.d.ts.map +1 -0
  49. package/dist/styles/split.js +52 -0
  50. package/dist/styles/split.js.map +1 -0
  51. package/dist/types.d.ts +69 -0
  52. package/dist/types.d.ts.map +1 -0
  53. package/dist/types.js +2 -0
  54. package/dist/types.js.map +1 -0
  55. package/package.json +74 -0
@@ -0,0 +1,169 @@
1
+ export function parseInlineStyle(styleAttr) {
2
+ if (!styleAttr)
3
+ return {};
4
+ const result = {};
5
+ for (const decl of styleAttr.split(';')) {
6
+ const colonIdx = decl.indexOf(':');
7
+ if (colonIdx === -1)
8
+ continue;
9
+ const prop = decl.slice(0, colonIdx).trim().toLowerCase();
10
+ const value = decl.slice(colonIdx + 1).trim();
11
+ if (!prop || !value)
12
+ continue;
13
+ applyCssProperty(result, prop, value);
14
+ }
15
+ return result;
16
+ }
17
+ function applyCssProperty(out, prop, value) {
18
+ switch (prop) {
19
+ case 'color':
20
+ out.color = value;
21
+ return;
22
+ case 'background-color':
23
+ case 'background':
24
+ out.backgroundColor = value;
25
+ return;
26
+ case 'font-size': {
27
+ const px = parsePx(value);
28
+ if (px !== null)
29
+ out.fontSize = px;
30
+ return;
31
+ }
32
+ case 'line-height': {
33
+ const px = parsePx(value);
34
+ if (px !== null)
35
+ out.lineHeight = px;
36
+ return;
37
+ }
38
+ case 'font-family':
39
+ out.fontFamily = stripFontFamilyQuotes(value);
40
+ return;
41
+ case 'font-weight': {
42
+ if (value === 'bold' || value === 'normal') {
43
+ out.fontWeight = value;
44
+ return;
45
+ }
46
+ const num = parseInt(value, 10);
47
+ if (!isNaN(num))
48
+ out.fontWeight = num >= 600 ? 'bold' : 'normal';
49
+ return;
50
+ }
51
+ case 'font-style':
52
+ if (value === 'italic' || value === 'normal')
53
+ out.fontStyle = value;
54
+ return;
55
+ case 'text-align':
56
+ if (value === 'left' ||
57
+ value === 'right' ||
58
+ value === 'center' ||
59
+ value === 'justify') {
60
+ out.textAlign = value;
61
+ }
62
+ return;
63
+ case 'text-decoration':
64
+ case 'text-decoration-line': {
65
+ const hasUnderline = value.includes('underline');
66
+ const hasLineThrough = value.includes('line-through');
67
+ if (hasUnderline && hasLineThrough) {
68
+ out.textDecorationLine = 'underline line-through';
69
+ }
70
+ else if (hasUnderline) {
71
+ out.textDecorationLine = 'underline';
72
+ }
73
+ else if (hasLineThrough) {
74
+ out.textDecorationLine = 'line-through';
75
+ }
76
+ else {
77
+ out.textDecorationLine = 'none';
78
+ }
79
+ return;
80
+ }
81
+ case 'margin':
82
+ applyBoxShorthand(out, 'margin', value);
83
+ return;
84
+ case 'margin-top':
85
+ setPx(out, 'marginTop', value);
86
+ return;
87
+ case 'margin-bottom':
88
+ setPx(out, 'marginBottom', value);
89
+ return;
90
+ case 'margin-left':
91
+ setPx(out, 'marginLeft', value);
92
+ return;
93
+ case 'margin-right':
94
+ setPx(out, 'marginRight', value);
95
+ return;
96
+ case 'padding':
97
+ applyBoxShorthand(out, 'padding', value);
98
+ return;
99
+ case 'padding-top':
100
+ setPx(out, 'paddingTop', value);
101
+ return;
102
+ case 'padding-bottom':
103
+ setPx(out, 'paddingBottom', value);
104
+ return;
105
+ case 'padding-left':
106
+ setPx(out, 'paddingLeft', value);
107
+ return;
108
+ case 'padding-right':
109
+ setPx(out, 'paddingRight', value);
110
+ return;
111
+ }
112
+ }
113
+ function applyBoxShorthand(out, prop, value) {
114
+ const parts = value.split(/\s+/).map(parsePx);
115
+ if (parts.some((p) => p === null))
116
+ return;
117
+ const [a, b, c, d] = parts;
118
+ let top, right, bottom, left;
119
+ switch (parts.length) {
120
+ case 1:
121
+ top = right = bottom = left = a;
122
+ break;
123
+ case 2:
124
+ top = bottom = a;
125
+ right = left = b;
126
+ break;
127
+ case 3:
128
+ top = a;
129
+ right = left = b;
130
+ bottom = c;
131
+ break;
132
+ case 4:
133
+ top = a;
134
+ right = b;
135
+ bottom = c;
136
+ left = d;
137
+ break;
138
+ default:
139
+ return;
140
+ }
141
+ if (prop === 'margin') {
142
+ out.marginTop = top;
143
+ out.marginRight = right;
144
+ out.marginBottom = bottom;
145
+ out.marginLeft = left;
146
+ }
147
+ else {
148
+ out.paddingTop = top;
149
+ out.paddingRight = right;
150
+ out.paddingBottom = bottom;
151
+ out.paddingLeft = left;
152
+ }
153
+ }
154
+ function setPx(out, key, value) {
155
+ const px = parsePx(value);
156
+ if (px !== null)
157
+ out[key] = px;
158
+ }
159
+ function stripFontFamilyQuotes(value) {
160
+ const first = value.split(',')[0].trim();
161
+ return first.replace(/^["']|["']$/g, '');
162
+ }
163
+ function parsePx(value) {
164
+ const match = /^(-?\d+(?:\.\d+)?)\s*(px)?$/.exec(value);
165
+ if (!match)
166
+ return null;
167
+ return parseFloat(match[1]);
168
+ }
169
+ //# sourceMappingURL=parse-inline.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse-inline.js","sourceRoot":"","sources":["../../src/styles/parse-inline.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import type { Selector } from './css-parser';
2
+ export interface ElementInfo {
3
+ tag: string;
4
+ classes: string[];
5
+ id: string | null;
6
+ }
7
+ export declare function matchSelector(selector: Selector, element: ElementInfo, ancestors: ElementInfo[]): boolean;
8
+ //# sourceMappingURL=selector-match.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"selector-match.d.ts","sourceRoot":"","sources":["../../src/styles/selector-match.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAgB,MAAM,cAAc,CAAC;AAE3D,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;CACnB;AAED,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,WAAW,EACpB,SAAS,EAAE,WAAW,EAAE,GACvB,OAAO,CAgCT"}
@@ -0,0 +1,49 @@
1
+ export function matchSelector(selector, element, ancestors) {
2
+ const parts = selector.parts;
3
+ if (parts.length === 0)
4
+ return false;
5
+ if (!matchPart(parts[parts.length - 1], element))
6
+ return false;
7
+ let partIdx = parts.length - 2;
8
+ let ancIdx = ancestors.length - 1;
9
+ while (partIdx >= 0) {
10
+ const part = parts[partIdx];
11
+ const rightPart = parts[partIdx + 1];
12
+ if (rightPart.combinator === 'child') {
13
+ if (ancIdx < 0)
14
+ return false;
15
+ if (!matchPart(part, ancestors[ancIdx]))
16
+ return false;
17
+ ancIdx--;
18
+ }
19
+ else {
20
+ let found = false;
21
+ while (ancIdx >= 0) {
22
+ if (matchPart(part, ancestors[ancIdx])) {
23
+ found = true;
24
+ ancIdx--;
25
+ break;
26
+ }
27
+ ancIdx--;
28
+ }
29
+ if (!found)
30
+ return false;
31
+ }
32
+ partIdx--;
33
+ }
34
+ return true;
35
+ }
36
+ function matchPart(part, el) {
37
+ if (part.tag && part.tag !== el.tag)
38
+ return false;
39
+ for (const cls of part.classes) {
40
+ if (!el.classes.includes(cls))
41
+ return false;
42
+ }
43
+ for (const id of part.ids) {
44
+ if (el.id !== id)
45
+ return false;
46
+ }
47
+ return true;
48
+ }
49
+ //# sourceMappingURL=selector-match.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"selector-match.js","sourceRoot":"","sources":["../../src/styles/selector-match.ts"],"names":[],"mappings":"AAQA,MAAM,UAAU,aAAa,CAC3B,QAAkB,EAClB,OAAoB,EACpB,SAAwB;IAExB,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC;IAC7B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAErC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAE,EAAE,OAAO,CAAC;QAAE,OAAO,KAAK,CAAC;IAEhE,IAAI,OAAO,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;IAC/B,IAAI,MAAM,GAAG,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC;IAElC,OAAO,OAAO,IAAI,CAAC,EAAE,CAAC;QACpB,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAE,CAAC;QAC7B,MAAM,SAAS,GAAG,KAAK,CAAC,OAAO,GAAG,CAAC,CAAE,CAAC;QACtC,IAAI,SAAS,CAAC,UAAU,KAAK,OAAO,EAAE,CAAC;YACrC,IAAI,MAAM,GAAG,CAAC;gBAAE,OAAO,KAAK,CAAC;YAC7B,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,SAAS,CAAC,MAAM,CAAE,CAAC;gBAAE,OAAO,KAAK,CAAC;YACvD,MAAM,EAAE,CAAC;QACX,CAAC;aAAM,CAAC;YACN,IAAI,KAAK,GAAG,KAAK,CAAC;YAClB,OAAO,MAAM,IAAI,CAAC,EAAE,CAAC;gBACnB,IAAI,SAAS,CAAC,IAAI,EAAE,SAAS,CAAC,MAAM,CAAE,CAAC,EAAE,CAAC;oBACxC,KAAK,GAAG,IAAI,CAAC;oBACb,MAAM,EAAE,CAAC;oBACT,MAAM;gBACR,CAAC;gBACD,MAAM,EAAE,CAAC;YACX,CAAC;YACD,IAAI,CAAC,KAAK;gBAAE,OAAO,KAAK,CAAC;QAC3B,CAAC;QACD,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,SAAS,CAAC,IAAkB,EAAE,EAAe;IACpD,IAAI,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,KAAK,EAAE,CAAC,GAAG;QAAE,OAAO,KAAK,CAAC;IAClD,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;QAC/B,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC;YAAE,OAAO,KAAK,CAAC;IAC9C,CAAC;IACD,KAAK,MAAM,EAAE,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;QAC1B,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE;YAAE,OAAO,KAAK,CAAC;IACjC,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,8 @@
1
+ import type { ResolvedStyle } from '../types';
2
+ import { type TextStyle, type ViewStyle } from 'react-native';
3
+ export interface StyleSplit {
4
+ view: ViewStyle;
5
+ text: TextStyle;
6
+ }
7
+ export declare function splitStyle(style: ResolvedStyle): StyleSplit;
8
+ //# sourceMappingURL=split.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"split.d.ts","sourceRoot":"","sources":["../../src/styles/split.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAC9C,OAAO,EAAY,KAAK,SAAS,EAAE,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AAkCxE,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,SAAS,CAAC;IAChB,IAAI,EAAE,SAAS,CAAC;CACjB;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,aAAa,GAAG,UAAU,CAqB3D"}
@@ -0,0 +1,52 @@
1
+ import { Platform } from 'react-native';
2
+ const MONO_FAMILY = Platform.select({ ios: 'Menlo', android: 'monospace', default: 'monospace' }) ??
3
+ 'monospace';
4
+ const TEXT_KEYS = [
5
+ 'color',
6
+ 'fontSize',
7
+ 'fontFamily',
8
+ 'fontWeight',
9
+ 'fontStyle',
10
+ 'textDecorationLine',
11
+ 'textAlign',
12
+ 'lineHeight',
13
+ ];
14
+ const VIEW_KEYS = [
15
+ 'margin',
16
+ 'marginHorizontal',
17
+ 'marginVertical',
18
+ 'marginTop',
19
+ 'marginBottom',
20
+ 'marginLeft',
21
+ 'marginRight',
22
+ 'padding',
23
+ 'paddingHorizontal',
24
+ 'paddingVertical',
25
+ 'paddingTop',
26
+ 'paddingBottom',
27
+ 'paddingLeft',
28
+ 'paddingRight',
29
+ ];
30
+ export function splitStyle(style) {
31
+ const view = {};
32
+ const text = {};
33
+ for (const k of TEXT_KEYS) {
34
+ const v = style[k];
35
+ if (v !== undefined)
36
+ text[k] = v;
37
+ }
38
+ if (text.fontFamily === 'monospace') {
39
+ text.fontFamily = MONO_FAMILY;
40
+ }
41
+ for (const k of VIEW_KEYS) {
42
+ const v = style[k];
43
+ if (v !== undefined)
44
+ view[k] = v;
45
+ }
46
+ if (style.backgroundColor !== undefined) {
47
+ view.backgroundColor = style.backgroundColor;
48
+ text.backgroundColor = style.backgroundColor;
49
+ }
50
+ return { view, text };
51
+ }
52
+ //# sourceMappingURL=split.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"split.js","sourceRoot":"","sources":["../../src/styles/split.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAkC,MAAM,cAAc,CAAC;AAExE,MAAM,WAAW,GACf,QAAQ,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC;IAC7E,WAAW,CAAC;AAEd,MAAM,SAAS,GAAG;IAChB,OAAO;IACP,UAAU;IACV,YAAY;IACZ,YAAY;IACZ,WAAW;IACX,oBAAoB;IACpB,WAAW;IACX,YAAY;CACJ,CAAC;AAEX,MAAM,SAAS,GAAG;IAChB,QAAQ;IACR,kBAAkB;IAClB,gBAAgB;IAChB,WAAW;IACX,cAAc;IACd,YAAY;IACZ,aAAa;IACb,SAAS;IACT,mBAAmB;IACnB,iBAAiB;IACjB,YAAY;IACZ,eAAe;IACf,aAAa;IACb,cAAc;CACN,CAAC;AAOX,MAAM,UAAU,UAAU,CAAC,KAAoB;IAC7C,MAAM,IAAI,GAAc,EAAE,CAAC;IAC3B,MAAM,IAAI,GAAc,EAAE,CAAC;IAE3B,KAAK,MAAM,CAAC,IAAI,SAAS,EAAE,CAAC;QAC1B,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACnB,IAAI,CAAC,KAAK,SAAS;YAAG,IAAgC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IAChE,CAAC;IACD,IAAI,IAAI,CAAC,UAAU,KAAK,WAAW,EAAE,CAAC;QACpC,IAAI,CAAC,UAAU,GAAG,WAAW,CAAC;IAChC,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,SAAS,EAAE,CAAC;QAC1B,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACnB,IAAI,CAAC,KAAK,SAAS;YAAG,IAAgC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IAChE,CAAC;IACD,IAAI,KAAK,CAAC,eAAe,KAAK,SAAS,EAAE,CAAC;QACxC,IAAI,CAAC,eAAe,GAAG,KAAK,CAAC,eAAe,CAAC;QAC7C,IAAI,CAAC,eAAe,GAAG,KAAK,CAAC,eAAe,CAAC;IAC/C,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;AACxB,CAAC"}
@@ -0,0 +1,69 @@
1
+ export type DomNode = DomElement | DomText;
2
+ export interface DomElement {
3
+ type: 'element';
4
+ name: string;
5
+ attribs: Record<string, string>;
6
+ children: DomNode[];
7
+ }
8
+ export interface DomText {
9
+ type: 'text';
10
+ data: string;
11
+ }
12
+ export interface ResolvedStyle {
13
+ color?: string;
14
+ fontSize?: number;
15
+ fontFamily?: string;
16
+ fontWeight?: 'normal' | 'bold';
17
+ fontStyle?: 'normal' | 'italic';
18
+ textDecorationLine?: 'none' | 'underline' | 'line-through' | 'underline line-through';
19
+ textAlign?: 'auto' | 'left' | 'right' | 'center' | 'justify';
20
+ lineHeight?: number;
21
+ backgroundColor?: string;
22
+ margin?: number;
23
+ marginHorizontal?: number;
24
+ marginVertical?: number;
25
+ marginTop?: number;
26
+ marginBottom?: number;
27
+ marginLeft?: number;
28
+ marginRight?: number;
29
+ padding?: number;
30
+ paddingHorizontal?: number;
31
+ paddingVertical?: number;
32
+ paddingTop?: number;
33
+ paddingBottom?: number;
34
+ paddingLeft?: number;
35
+ paddingRight?: number;
36
+ }
37
+ export type RenderNode = RenderElement | RenderText | RenderImage;
38
+ export interface RenderElement {
39
+ kind: 'element';
40
+ tag: string;
41
+ display: 'block' | 'inline';
42
+ style: ResolvedStyle;
43
+ href?: string;
44
+ attribs?: Record<string, string>;
45
+ listMarker?: string;
46
+ listOrdered?: boolean;
47
+ colSpan?: number;
48
+ children: RenderNode[];
49
+ }
50
+ export type StyleInput = ResolvedStyle | string;
51
+ export interface HTMLElementModel {
52
+ display?: 'block' | 'inline';
53
+ tagDefaultStyle?: StyleInput;
54
+ isVoid?: boolean;
55
+ }
56
+ export interface RenderText {
57
+ kind: 'text';
58
+ text: string;
59
+ style: ResolvedStyle;
60
+ preserveWhitespace?: boolean;
61
+ }
62
+ export interface RenderImage {
63
+ kind: 'image';
64
+ src: string;
65
+ alt?: string;
66
+ width?: number;
67
+ height?: number;
68
+ }
69
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
package/package.json ADDED
@@ -0,0 +1,74 @@
1
+ {
2
+ "name": "@nikpnevmatikos/html-renderer",
3
+ "version": "0.1.0-alpha.0",
4
+ "description": "React Native HTML renderer in TypeScript — zero native modules, Fabric/Expo compatible. Supports tagsStyles, stylesheet with CSS selectors, custom renderers, and more.",
5
+ "author": "NikPnevmatikos",
6
+ "license": "MIT",
7
+ "homepage": "https://github.com/NikPnevmatikos/Html-Renderer#readme",
8
+ "bugs": {
9
+ "url": "https://github.com/NikPnevmatikos/Html-Renderer/issues"
10
+ },
11
+ "repository": {
12
+ "type": "git",
13
+ "url": "git+https://github.com/NikPnevmatikos/Html-Renderer.git",
14
+ "directory": "packages/core"
15
+ },
16
+ "main": "./dist/index.js",
17
+ "module": "./dist/index.js",
18
+ "types": "./dist/index.d.ts",
19
+ "react-native": "./dist/index.js",
20
+ "files": [
21
+ "dist",
22
+ "README.md",
23
+ "LICENSE"
24
+ ],
25
+ "publishConfig": {
26
+ "access": "public"
27
+ },
28
+ "engines": {
29
+ "node": ">=20"
30
+ },
31
+ "sideEffects": false,
32
+ "scripts": {
33
+ "build": "tsc",
34
+ "dev": "tsc --watch --preserveWatchOutput",
35
+ "typecheck": "tsc --noEmit",
36
+ "test": "jest",
37
+ "clean": "rimraf dist"
38
+ },
39
+ "jest": {
40
+ "preset": "ts-jest",
41
+ "testEnvironment": "node",
42
+ "testMatch": [
43
+ "<rootDir>/src/**/*.test.ts"
44
+ ]
45
+ },
46
+ "keywords": [
47
+ "react-native",
48
+ "html",
49
+ "renderer",
50
+ "expo",
51
+ "fabric",
52
+ "typescript",
53
+ "stylesheet",
54
+ "css",
55
+ "react-native-web"
56
+ ],
57
+ "peerDependencies": {
58
+ "react": ">=18",
59
+ "react-native": ">=0.73"
60
+ },
61
+ "dependencies": {
62
+ "domhandler": "^5.0.3",
63
+ "htmlparser2": "^10.0.0"
64
+ },
65
+ "devDependencies": {
66
+ "@types/jest": "^29.5.14",
67
+ "@types/react": "~19.1.0",
68
+ "jest": "^29.7.0",
69
+ "react": "19.1.0",
70
+ "react-native": "0.81.5",
71
+ "ts-jest": "^29.4.9",
72
+ "typescript": "~5.9.2"
73
+ }
74
+ }