Skip to content

Commit

Permalink
[form-builder] Use text input for relative URL fields (#1179)
Browse files Browse the repository at this point in the history
  • Loading branch information
rexxars authored and bjoerge committed Feb 1, 2019
1 parent a89d445 commit 3146a78
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 14 deletions.
17 changes: 4 additions & 13 deletions packages/@sanity/form-builder/src/inputs/NumberInput.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import React from 'react'
import TextInput from 'part:@sanity/components/textinputs/default'
import FormField from 'part:@sanity/components/formfields/default'
import {getValidationRule} from '../utils/getValidationRule'
import PatchEvent, {set, unset} from '../PatchEvent'
import type {Type, Marker} from '../typedefs'

Expand Down Expand Up @@ -39,18 +40,8 @@ export default class NumberInput extends React.Component<Props> {
const errors = validation.filter(marker => marker.level === 'error')

// Show numpad on mobile if only positive numbers is preferred
let onlyPositiveNumber = false
if (type && type.validation && type.validation.length) {
type.validation.forEach(rule => {
if (rule._rules && rule._rules.length) {
rule._rules.forEach(_r => {
if (_r.flag === 'min' && _r.constraint >= 0) {
onlyPositiveNumber = true
}
})
}
})
}
const minRule = getValidationRule(type, 'min')
const onlyPositiveNumber = minRule && minRule.constraint >= 0

return (
<FormField markers={markers} level={level} label={type.title} description={type.description}>
Expand All @@ -63,7 +54,7 @@ export default class NumberInput extends React.Component<Props> {
onChange={this.handleChange}
onFocus={onFocus}
ref={this.setInput}
pattern={onlyPositiveNumber ? '[\d]*' : undefined}
pattern={onlyPositiveNumber ? '[d]*' : undefined}
/>
</FormField>
)
Expand Down
8 changes: 7 additions & 1 deletion packages/@sanity/form-builder/src/inputs/UrlInput.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
//@flow
import React from 'react'
import {get} from 'lodash'
import TextInput from 'part:@sanity/components/textinputs/default'
import FormField from 'part:@sanity/components/formfields/default'
import {getValidationRule} from '../utils/getValidationRule'
import PatchEvent, {set, unset} from '../PatchEvent'
import type {Type, Marker} from '../typedefs'

Expand Down Expand Up @@ -38,11 +40,15 @@ export default class UrlInput extends React.Component<Props> {
const validation = markers.filter(marker => marker.type === 'validation')
const errors = validation.filter(marker => marker.level === 'error')

// Use text input for relative URIs
const uriRule = getValidationRule(type, 'uri')
const inputType = uriRule && get(uriRule, 'constraint.options.allowRelative') ? 'text' : 'url'

return (
<FormField markers={markers} level={level} label={type.title} description={type.description}>
<TextInput
customValidity={errors && errors.length > 0 ? errors[0].item.message : ''}
type="url"
type={inputType}
value={value}
readOnly={readOnly}
placeholder={type.placeholder}
Expand Down
23 changes: 23 additions & 0 deletions packages/@sanity/form-builder/src/utils/getValidationRule.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import type {Type} from '../typedefs'

export function getValidationRule(type: Type, ruleName: string) {
if (!type || !type.validation || !type.validation.length) {
return null
}

for (let i = 0; i < type.validation.length; i++) {
const validation = type.validation[i]
if (!validation || !validation._rules) {
continue
}

for (let r = 0; r < validation._rules.length; r++) {
const rule = validation._rules[r]
if (rule.flag === ruleName) {
return rule
}
}
}

return null
}
13 changes: 13 additions & 0 deletions packages/test-studio/schemas/validation.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,13 @@ export default {
description: 'URL that only allows mailto: and tel: schemes',
validation: Rule => Rule.uri({scheme: ['mailto', 'tel']})
},
{
name: 'relativeUrl',
type: 'url',
title: 'Relative URL',
description: 'URL that allows relative URLs',
validation: Rule => Rule.uri({allowRelative: true})
},
{
name: 'date',
type: 'datetime',
Expand Down Expand Up @@ -89,6 +96,12 @@ export default {
description: 'Only positive numbers larger than lowest temperature',
validation: Rule => Rule.positive().min(Rule.valueOfField('lowestTemperature'))
},
{
name: 'onlyPositive',
type: 'number',
title: 'Only positive',
validation: Rule => Rule.positive()
},
{
name: 'someInteger',
type: 'number',
Expand Down

0 comments on commit 3146a78

Please sign in to comment.