diff --git a/lib/js/src/ReactDOMRe.js b/lib/js/src/ReactDOMRe.js index 2c4d6de33..cef67871c 100644 --- a/lib/js/src/ReactDOMRe.js +++ b/lib/js/src/ReactDOMRe.js @@ -76,6 +76,8 @@ function hydrateToElementWithId(reactElement, id) { var Ref = { }; +var Input = /* module */[]; + function createElementVariadic(domClassName, props, children) { var variadicArguments = [ domClassName, @@ -100,6 +102,7 @@ exports.Experimental = Experimental; exports.hydrateToElementWithClassName = hydrateToElementWithClassName; exports.hydrateToElementWithId = hydrateToElementWithId; exports.Ref = Ref; +exports.Input = Input; exports.createElementVariadic = createElementVariadic; exports.Style = Style; /* react Not a pure module */ diff --git a/src/ReactDOMRe.re b/src/ReactDOMRe.re index 7d8c5b599..8de5e07ef 100644 --- a/src/ReactDOMRe.re +++ b/src/ReactDOMRe.re @@ -121,13 +121,77 @@ module Ref = { external callbackDomRef: callbackDomRef => domRef = "%identity"; }; +/** Type-safe form input values. */ +module Input: { + type type_('value); + type t('value); + type step('value); + + external date: Js.Date.t => t(Js.Date.t) = "%identity"; + external float: float => t(float) = "%identity"; + external int: int => t(int) = "%identity"; + + [@bs.inline "checkbox"] + let checkbox: type_(bool); + + [@bs.inline "date"] + let dateType: type_(Js.Date.t); + + [@bs.inline "number"] + let intType: type_(int); + + [@bs.inline "number"] + let floatType: type_(float); + + external otherType: string => type_(_) = "%identity"; + + [@bs.inline "any"] + let anyStep: step(_); + + external dateStep: int => step(Js.Date.t) = "%identity"; + external floatStep: float => step(float) = "%identity"; + external intStep: int => step(int) = "%identity"; +} = { + type type_('value) = string; + type t('value); + type step('value) = string; + + external date: Js.Date.t => t(Js.Date.t) = "%identity"; + external float: float => t(float) = "%identity"; + external int: int => t(int) = "%identity"; + + [@bs.inline] + let checkbox = "checkbox"; + + [@bs.inline] + let dateType = "date"; + + [@bs.inline] + let intType = "number"; + + [@bs.inline] + let floatType = "number"; + + external otherType: string => type_(_) = "%identity"; + + [@bs.inline] + let anyStep = "any"; + + external dateStep: int => step(Js.Date.t) = "%identity"; + external floatStep: float => step(float) = "%identity"; + external intStep: int => step(int) = "%identity"; +}; + /* This list isn't exhaustive. We'll add more as we go. */ /* * Watch out! There are two props types and the only difference is the type of ref. * Please keep in sync. */ + +/** [domProps('input)] is the type of the React element attributes object. + ['input] is the type of values accepted by [input] elements. */ [@bs.deriving abstract] -type domProps = { +type domProps('input) = { [@bs.optional] key: string, [@bs.optional] @@ -369,7 +433,7 @@ type domProps = { [@bs.optional] manifest: string, /* uri */ [@bs.optional] - max: string, /* should be int or Js.Date.t */ + max: Input.t('input), [@bs.optional] maxLength: int, [@bs.optional] @@ -379,7 +443,7 @@ type domProps = { [@bs.optional] method: string, /* "post" or "get" */ [@bs.optional] - min: string, + min: Input.t('input), [@bs.optional] minLength: int, [@bs.optional] @@ -448,7 +512,7 @@ type domProps = { [@bs.optional] start: int, [@bs.optional] - step: float, + step: Input.step('input), [@bs.optional] summary: string, /* deprecated */ [@bs.optional] @@ -458,7 +522,7 @@ type domProps = { [@bs.optional] useMap: string, [@bs.optional] - value: string, + value: Input.t('input), [@bs.optional] width: string, /* in html5 this can only be a number, but in html4 it can ba a percentage as well */ [@bs.optional] @@ -1124,7 +1188,7 @@ type domProps = { [@bs.splice] [@bs.module "react"] external createDOMElementVariadic: - (string, ~props: domProps=?, array(React.element)) => React.element = + (string, ~props: domProps(_)=?, array(React.element)) => React.element = "createElement"; /* This list isn't exhaustive. We'll add more as we go. */ @@ -1132,8 +1196,11 @@ external createDOMElementVariadic: * Watch out! There are two props types and the only difference is the type of ref. * Please keep in sync. */ + +/** [props('input)] is the type of the React element attributes object. + ['input] is the type of values accepted by [input] elements. */ [@bs.deriving abstract] -type props = { +type props('input) = { [@bs.optional] key: string, [@bs.optional] @@ -1375,7 +1442,7 @@ type props = { [@bs.optional] manifest: string, /* uri */ [@bs.optional] - max: string, /* should be int or Js.Date.t */ + max: Input.t('input), [@bs.optional] maxLength: int, [@bs.optional] @@ -1385,7 +1452,7 @@ type props = { [@bs.optional] method: string, /* "post" or "get" */ [@bs.optional] - min: string, + min: Input.t('input), [@bs.optional] minLength: int, [@bs.optional] @@ -1454,7 +1521,7 @@ type props = { [@bs.optional] start: int, [@bs.optional] - step: float, + step: Input.step('input), [@bs.optional] summary: string, /* deprecated */ [@bs.optional] @@ -1464,7 +1531,7 @@ type props = { [@bs.optional] useMap: string, [@bs.optional] - value: string, + value: Input.t('input), [@bs.optional] width: string, /* in html5 this can only be a number, but in html4 it can ba a percentage as well */ [@bs.optional] @@ -2128,14 +2195,14 @@ type props = { suppressContentEditableWarning: bool, }; -external objToDOMProps: Js.t({..}) => props = "%identity"; +external objToDOMProps: Js.t({..}) => props(_) = "%identity"; [@deprecated "Please use ReactDOMRe.props instead"] -type reactDOMProps = props; +type reactDOMProps('a) = props('a); [@bs.splice] [@bs.val] [@bs.module "react"] external createElement: - (string, ~props: props=?, array(React.element)) => React.element = + (string, ~props: props(_)=?, array(React.element)) => React.element = "createElement"; /* Only wanna expose createElementVariadic here. Don't wanna write an interface file */ @@ -2163,7 +2230,8 @@ include ( }; }: { let createElementVariadic: - (string, ~props: props=?, array(React.element)) => React.element; + (string, ~props: props(_)=?, array(React.element)) => + React.element; } );