@@ -1,6 +1,6 @@
{
"name": "auth0-lock",
"version": "11.20.4",
"version": "11.21.0",
"description": "Auth0 Lock",
"author": "Auth0 <support@auth0.com> (http://auth0.com)",
"license": "MIT",
@@ -104,6 +104,7 @@ exports[`SignUpPane onlyEmail is false shows custom fields when additionalSignUp
data-name="name1"
data-options="options1"
data-placeholder="placeholder1"
data-placeholderHTML="placeholderHTML1"
data-type="type1"
data-validator="validator1"
data-value="value1"
@@ -116,6 +117,7 @@ exports[`SignUpPane onlyEmail is false shows custom fields when additionalSignUp
data-name="name2"
data-options="options2"
data-placeholder="placeholder2"
data-placeholderHTML="placeholderHTML2"
data-type="type2"
data-validator="validator2"
data-value="value2"
@@ -1,6 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`CustomInput when type == checkbox renders correctly as a CheckBoxInput 1`] = `
exports[`CustomInput when type == checkbox and when placeholderHTML is set renders correctly as a CheckBoxInput 1`] = `
<div
className="auth0-lock-input-checkbox"
>
@@ -16,14 +16,34 @@ exports[`CustomInput when type == checkbox renders correctly as a CheckBoxInput
<span
dangerouslySetInnerHTML={
Object {
"__html": "placeholder",
"__html": "<b>Placeholder</b>",
}
}
/>
</label>
</div>
`;

exports[`CustomInput when type == checkbox renders correctly as a CheckBoxInput 1`] = `
<div
className="auth0-lock-input-checkbox"
>
<label>
<input
aria-label="Custom Input"
checked={false}
id="1-custom_input"
name="custom_input"
onChange={[Function]}
type="checkbox"
/>
<span>
placeholder
</span>
</label>
</div>
`;

exports[`CustomInput when type == hidden renders correctly as a input[type=hidden] 1`] = `
<input
id={1}
@@ -101,6 +101,16 @@ describe('CustomInput', () => {

expectComponent(<CustomInput {...defaultProps} />).toMatchSnapshot();
});

describe('and when placeholderHTML is set', () => {
it('renders correctly as a CheckBoxInput', () => {
const CustomInput = getComponent();

expectComponent(
<CustomInput {...defaultProps} placeholderHTML={'<b>Placeholder</b>'} />
).toMatchSnapshot();
});
});
});
describe('when type == hidden', () => {
beforeEach(() => {
@@ -95,7 +95,18 @@ function processDatabaseOptions(opts) {
additionalSignUpFields = undefined;
} else if (additionalSignUpFields) {
additionalSignUpFields = additionalSignUpFields.reduce((r, x) => {
let { icon, name, options, placeholder, prefill, type, validator, value, storage } = x;
let {
icon,
name,
options,
placeholder,
placeholderHTML,
prefill,
type,
validator,
value,
storage
} = x;
let filter = true;

const reservedNames = ['email', 'username', 'password'];
@@ -113,14 +124,25 @@ function processDatabaseOptions(opts) {
filter = false;
}

if (type !== 'hidden' && (typeof placeholder != 'string' || !placeholder)) {
if (
type !== 'hidden' &&
(typeof placeholder != 'string' || !placeholder) &&
(typeof placeholderHTML != 'string' || !placeholderHTML)
) {
l.warn(
opts,
`Ignoring an element of \`additionalSignUpFields\` (${name}) because it does not contain a valid \`placeholder\` property. Every element of \`additionalSignUpFields\` must have a \`placeholder\` property that is a non-empty string.`
`Ignoring an element of \`additionalSignUpFields\` (${name}) because it does not contain a valid \`placeholder\` or \`placeholderHTML\` property. Every element of \`additionalSignUpFields\` must have a \`placeholder\` or \`placeholderHTML\` property that is a non-empty string.`
);
filter = false;
}

if (placeholderHTML && placeholder) {
l.warn(
opts,
'When provided, the `placeholderHTML` property of an element of `additionalSignUpFields` will override the `placeholder` property of that element'
);
}

if (icon != undefined && (typeof icon != 'string' || !icon)) {
l.warn(
opts,
@@ -195,7 +217,20 @@ function processDatabaseOptions(opts) {
}

return filter
? r.concat([{ icon, name, options, placeholder, prefill, type, validator, value, storage }])
? r.concat([
{
icon,
name,
options,
placeholder,
placeholderHTML,
prefill,
type,
validator,
value,
storage
}
])
: r;
}, []);

@@ -46,6 +46,7 @@ export default class SignUpPane extends React.Component {
ariaLabel={x.get('ariaLabel')}
options={x.get('options')}
placeholder={x.get('placeholder')}
placeholderHTML={x.get('placeholderHTML')}
type={x.get('type')}
validator={x.get('validator')}
value={x.get('value')}
@@ -6,7 +6,17 @@ import SelectInput from '../ui/input/select_input';
import CheckboxInput from '../ui/input/checkbox_input';
import * as l from '../core/index';

const CustomInput = ({ iconUrl, model, name, ariaLabel, placeholder, type, validator, value }) => {
const CustomInput = ({
iconUrl,
model,
name,
ariaLabel,
placeholder,
placeholderHTML,
type,
validator,
value
}) => {
const props = {
iconUrl,
isValid: !isFieldVisiblyInvalid(model, name),
@@ -31,6 +41,7 @@ const CustomInput = ({ iconUrl, model, name, ariaLabel, placeholder, type, valid
lockId={l.id(model)}
onChange={e => changeField(l.id(model), name, `${e.target.checked}`, validator)}
checked={getFieldValue(model, name)}
placeholderHTML={placeholderHTML}
{...props}
/>
);
@@ -1,9 +1,8 @@
import React from 'react';
import InputWrap from './input_wrap';

export default class CheckboxInput extends React.Component {
render() {
const { lockId, name, ariaLabel, placeholder, checked } = this.props;
const { lockId, name, ariaLabel, placeholder, checked, placeholderHTML } = this.props;
return (
<div className="auth0-lock-input-checkbox">
<label>
@@ -15,7 +14,11 @@ export default class CheckboxInput extends React.Component {
name={name}
aria-label={ariaLabel || name}
/>
<span dangerouslySetInnerHTML={{ __html: placeholder }} />
{placeholderHTML ? (
<span dangerouslySetInnerHTML={{ __html: placeholderHTML }} />
) : (
<span>{placeholder}</span>
)}
</label>
</div>
);