Repository: remarkablemark/html-react-parser (ts)

Issue:
`value=` shouldn't be converted to `defaultValue=` for `<option>`
The value of `<option>` tags of `<select>` are fixed. Converting their `value=` to `defaultValue=` results bug if the option label is different from the value. For example:

```html
<select name="range" value="gte-2">
  <option value="lt-1">Less than 1</option>
  <option value="gte-2">≥2<option>
</select>
```

The value of `<select>`'s "gte-2" won't get a match and it will fallback to "Less than 1".

https://github.com/remarkablemark/html-react-parser/blob/cffffc71fe8e72e6a662de50c0b00a3d77c60cc6/lib/attributes-to-props.js#L42-L49

Pull request:
fix(attributes-to-props): don't convert value of option tag
## What is the motivation for this pull request?

Fixes #625 and closes #790. Not sure if there is another element affected with this issue then `option`.

## What is the current behavior?

`attributesToProps` converts `value` attribute to `defaultValue` of `option` element what is not desirable.

## What is the new behavior?

`value` attribute is preserved on `option` element.

## Checklist:

- [x] [Conventional Commits](https://www.conventionalcommits.org/)
- [x] Tests
- [ ] Documentation
- [x] Types




Patch:
diff --git a/.size-limit.json b/.size-limit.json
index 99900b4..a8fb232 100644
--- a/.size-limit.json
+++ b/.size-limit.json
@@ -1,6 +1,6 @@
 [
   {
     "path": "dist/html-react-parser.min.js",
-    "limit": "10.541 KB"
+    "limit": "10.553 KB"
   }
 ]
diff --git a/lib/attributes-to-props.d.ts b/lib/attributes-to-props.d.ts
index 02fd844..b6d95ce 100644
--- a/lib/attributes-to-props.d.ts
+++ b/lib/attributes-to-props.d.ts
@@ -10,6 +10,10 @@ export type Props = Record<string, string> & {
  * Converts HTML/SVG DOM attributes to React props.
  *
  * @param attributes - HTML/SVG DOM attributes.
+ * @param nodeName - DOM node name.
  * @returns - React props.
  */
-export default function attributesToProps(attributes: Attributes): Props;
+export default function attributesToProps(
+  attributes: Attributes,
+  nodeName?: string
+): Props;
diff --git a/lib/attributes-to-props.js b/lib/attributes-to-props.js
index 706a747..0d5c8f7 100644
--- a/lib/attributes-to-props.js
+++ b/lib/attributes-to-props.js
@@ -5,9 +5,10 @@ var utilities = require('./utilities');
  * Converts HTML/SVG DOM attributes to React props.
  *
  * @param {object} [attributes={}] - HTML/SVG DOM attributes.
+ * @param {string} [nodeName] - DOM node name.
  * @returns - React props.
  */
-module.exports = function attributesToProps(attributes) {
+module.exports = function attributesToProps(attributes, nodeName) {
   attributes = attributes || {};
 
   var valueOnlyInputs = {
@@ -43,6 +44,7 @@ module.exports = function attributesToProps(attributes) {
       // https://reactjs.org/docs/uncontrolled-components.html
       if (
         (propName === 'checked' || propName === 'value') &&
+        nodeName !== 'option' &&
         !inputIsValueOnly
       ) {
         propName = getPropName('default' + attributeNameLowerCased);
diff --git a/lib/dom-to-react.js b/lib/dom-to-react.js
index 54cc77b..4f46d65 100644
--- a/lib/dom-to-react.js
+++ b/lib/dom-to-react.js
@@ -76,7 +76,7 @@ function domToReact(nodes, options) {
     if (skipAttributesToProps(node)) {
       setStyleProp(props.style, props);
     } else if (props) {
-      props = attributesToProps(props);
+      props = attributesToProps(props, node.name);
     }
 
     children = null;


Test patch:
diff --git a/test/attributes-to-props.test.js b/test/attributes-to-props.test.js
index d369f5e..ab9d164 100644
--- a/test/attributes-to-props.test.js
+++ b/test/attributes-to-props.test.js
@@ -186,6 +186,12 @@ describe('attributesToProps with HTML attribute', () => {
       expect(attributesToProps(attributes)).toEqual(props);
     }
   );
+
+  it('preserves value of option element', () => {
+    expect(attributesToProps({ value: 'foo' }, 'option')).toEqual({
+      value: 'foo'
+    });
+  });
 });
 
 describe('attributesToProps with SVG attribute', () => {