Skip to content

Commit 3ca281e

Browse files
tesujimathmaddie927
authored andcommitted
Removed SharedProps in favour of "*" from react-html-attributes (#84)
* Codegen now supports global and React-specific attributes. These are the ones stored under the key "*" in react-html-attributes. How to handle some of these is currently unclear (to me). Fixes #83. * codegen: support dangerouslySetInnerHTML as a plain record. * codegen: resolved TODO attributes, turned out all to be Strings. Needed to look into the React source code, see https://github.com/facebook/react/blob/master/fixtures/attribute-behavior/AttributeTableSnapshot.md They are apparently not documented anywhere else that I could find. * codegen: HTML attribute types may differ across containing elements. * Bumped version of react-html-attributes we depend on. Fixes #76. * Use own copy of react-html-attributes. Currently unmodified 1.4.6. * Removed SharedProps, in favour of "*" in react-html-attributes. * Added global attribute "ref". * Updated generated-docs.
1 parent 05f0cf2 commit 3ca281e

File tree

15 files changed

+12457
-870
lines changed

15 files changed

+12457
-870
lines changed

codegen/consts.js

Lines changed: 61 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,93 @@
1-
module.exports.props = require("react-html-attributes");
1+
// For now, we are using a local copy of react-html-attributes.
2+
// Eventually, the relative path here should be removed, and
3+
// the version number of react-html-attributes should be bumped.
4+
module.exports.props = require("./react-html-attributes");
5+
26
module.exports.voids = ["area", "base", "br", "col", "embed", "hr", "img", "input", "link", "meta", "param", "source", "track", "wbr"];
7+
// The types for certain attributes differ according to their containing element.
8+
// These appear in the typesByElement object, using "*" as a default element
9+
// (required only if the default attribute type is other than `String`).
10+
// For clarity, it is an error for any attribute to be in both `types` and `typesByElement`.
11+
module.exports.typesByElement = {
12+
"cols": {
13+
"textarea": "Int",
14+
},
15+
"max": {
16+
"meter": "Number",
17+
"progress": "Number"
18+
},
19+
"min": {
20+
"meter": "Number"
21+
},
22+
"rows": {
23+
"textarea": "Int"
24+
},
25+
"size" : {
26+
"input": "Int",
27+
"select": "Int"
28+
}
29+
};
330
module.exports.types = {
431
"allowFullScreen": "Boolean",
32+
"allowTransparency": "Boolean",
533
"async": "Boolean",
34+
"autoComplete": "Boolean",
35+
"autoFocus": "Boolean",
636
"autoPlay": "Boolean",
737
"capture": "Boolean",
838
"checked": "Boolean",
939
"children": "Array JSX",
10-
"cols": "Number",
40+
"colSpan": "Int",
41+
"contentEditable": "Boolean",
1142
"controls": "Boolean",
43+
"dangerouslySetInnerHTML": "{ __html :: String }",
1244
"default": "Boolean",
1345
"defer": "Boolean",
1446
"disabled": "Boolean",
47+
"draggable": "Boolean",
1548
"formNoValidate": "Boolean",
1649
"hidden": "Boolean",
1750
"itemScope": "Boolean",
1851
"loop": "Boolean",
19-
"max": "Number",
20-
"min": "Number",
52+
"maxLength": "Int",
53+
"minLength": "Int",
2154
"multiple": "Boolean",
2255
"muted": "Boolean",
56+
"noValidate": "Boolean",
57+
"onBlur": "EventHandler",
58+
"onChange": "EventHandler",
2359
"onClick": "EventHandler",
60+
"onFocus": "EventHandler",
2461
"onInput": "EventHandler",
2562
"onInvalid": "EventHandler",
63+
"onKeyDown": "EventHandler",
64+
"onKeyPress": "EventHandler",
65+
"onKeyUp": "EventHandler",
66+
"onMouseDown": "EventHandler",
67+
"onMouseEnter": "EventHandler",
68+
"onMouseLeave": "EventHandler",
69+
"onMouseMove": "EventHandler",
70+
"onMouseOut": "EventHandler",
71+
"onMouseOver": "EventHandler",
72+
"onMouseUp": "EventHandler",
2673
"onSubmit": "EventHandler",
27-
"noValidate": "Boolean",
28-
"onChange": "EventHandler",
2974
"open": "Boolean",
3075
"playsInline": "Boolean",
3176
"readOnly": "Boolean",
77+
"ref": "Ref (Nullable Node)",
3278
"required": "Boolean",
3379
"reversed": "Boolean",
34-
"rowSpan": "Number",
35-
"rows": "Number",
80+
"rowSpan": "Int",
3681
"scoped": "Boolean",
3782
"seamless": "Boolean",
3883
"selected": "Boolean",
39-
"size": "Number",
40-
"span": "Number",
41-
"start": "Number"
84+
"span": "Int",
85+
"spellCheck": "Boolean",
86+
"srcDoc": "JSX",
87+
"start": "Int",
88+
"style": "CSS",
89+
"suppressContentEditableWarning": "Boolean",
90+
"tabIndex": "Int",
91+
"unselectable": "Boolean"
4292
};
4393
module.exports.reserved = ["module", "data", "type", "newtype", "class", "instance", "where", "derive", "if", "then", "else", "case", "of"];

codegen/index.js

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
const fs = require("fs");
2-
const { props, voids, types, reserved } = require("./consts");
2+
const { props, voids, types, typesByElement, reserved } = require("./consts");
33
const genFile = "../src/React/Basic/DOM/Generated.purs";
44

55
const header = `-- | ----------------------------------------
@@ -8,17 +8,31 @@ const header = `-- | ----------------------------------------
88
99
module React.Basic.DOM.Generated where
1010
11+
import Data.Nullable (Nullable)
1112
import Prim.Row (class Union)
12-
import React.Basic (JSX, element)
13-
import React.Basic.DOM.Internal (SharedProps, unsafeCreateDOMComponent)
13+
import Web.DOM (Node)
14+
import React.Basic (JSX, Ref, element)
15+
import React.Basic.DOM.Internal (CSS, unsafeCreateDOMComponent)
1416
import React.Basic.Events (EventHandler)
1517
1618
`;
1719

18-
const printRecord = elProps =>
20+
const propType = (e, p) => {
21+
const elPropTypes = typesByElement[p];
22+
if (elPropTypes) {
23+
if (types[p]) {
24+
throw new TypeError(`${p} appears in both types and typesByElement`);
25+
}
26+
return elPropTypes[e] || elPropTypes["*"] || "String";
27+
} else {
28+
return types[p] || "String";
29+
}
30+
}
31+
32+
const printRecord = (e, elProps) =>
1933
elProps.length
2034
? `
21-
( ${elProps.map(p => `${p} :: ${types[p] || "String"}`).join("\n , ")}
35+
( ${elProps.map(p => `${p} :: ${propType(e, p)}`).join("\n , ")}
2236
)`
2337
: "()";
2438

@@ -27,13 +41,13 @@ const domTypes = props.elements.html
2741
const noChildren = voids.includes(e);
2842
const symbol = reserved.includes(e) ? `${e}'` : e;
2943
return `
30-
type Props_${e} =${printRecord(
31-
(noChildren ? [] : ["children"]).concat(props[e] || []).sort()
44+
type Props_${e} =${printRecord(e,
45+
(noChildren ? [] : ["children"]).concat(props[e] || [], props["*"] || []).sort()
3246
)}
3347
3448
${symbol}
3549
:: forall attrs attrs_
36-
. Union attrs attrs_ (SharedProps Props_${e})
50+
. Union attrs attrs_ Props_${e}
3751
=> Record attrs
3852
-> JSX
3953
${symbol} = element (unsafeCreateDOMComponent "${e}")${

codegen/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,6 @@
55
"main": "index.js",
66
"author": "",
77
"dependencies": {
8-
"react-html-attributes": "^1.4.3"
8+
"react-html-attributes": "^1.4.6"
99
}
1010
}

0 commit comments

Comments
 (0)