Skip to content

Demos

Label and value

Code Editor
<Field.String
  label="Label text"
  defaultValue="foo"
  onChange={(value) => console.log('onChange', value)}
/>

Label and description

Code Editor
<Form.Card>
  <Field.String
    label="Label text"
    labelDescription="Description text on the next line"
    placeholder="Enter a text..."
  />
  <Field.String
    label="Label text"
    labelDescription="Description text on the same line"
    labelDescriptionInline
    placeholder="Enter a text..."
  />
</Form.Card>

With a horizontal layout

This example uses Field.Provider to set the layout to horizontal and layoutOptions to { width: 'medium' } for all nested fields.

The width of the horizontal label can be set to small, medium, large or a rem value.

Short warning.
Aliqua eu aute id qui esse aliqua dolor in aute magna commodo anim enim et.
Code Editor
<Form.Card>
  <Field.Provider
    layout="horizontal"
    layoutOptions={{
      width: 'medium', // can be a rem value
    }}
    placeholder="Enter a text..."
    required
  >
    <Field.String label="Label text" warning="Short warning." />
    <Field.String
      label="Label with a long text that will wrap"
      placeholder="Enter a text..."
      size="medium"
      info="Aliqua eu aute id qui esse aliqua dolor in aute magna commodo anim enim et."
    />
    <Field.String
      label="Label with a long text that will wrap"
      placeholder="Enter a text..."
      size="large"
      width="stretch"
    />
  </Field.Provider>
</Form.Card>

Placeholder

Code Editor
<Field.String
  label="Label text"
  placeholder="Enter a text..."
  onChange={(value) => console.log('onChange', value)}
/>

With a status

This example demonstrates how the status message width adjusts according to the field width.

Short warning.
Aliqua eu aute id qui esse aliqua dolor in aute magna commodo anim enim et.
Aliqua eu aute id qui esse aliqua dolor in aute magna commodo anim enim et. Velit incididunt exercitation est magna ex irure dolore nisi eiusmod ea exercitation.
Feil som må rettes:
  • Error message A
  • Error message B
Oppsummering:
  • Warning message A
  • Warning message B
Oppsummering:
  • Info message A
  • Info message B
Code Editor
<Form.Card>
  <Field.String
    label="Label text"
    defaultValue="foo"
    warning="Short warning."
    required
  />
  <Field.String
    label="Label text"
    placeholder="Enter a text..."
    info="Aliqua eu aute id qui esse aliqua dolor in aute magna commodo anim enim et."
    required
  />
  <Field.String
    label="Label text"
    defaultValue="foo"
    width="small"
    warning="Aliqua eu aute id qui esse aliqua dolor in aute magna commodo anim enim et. Velit incididunt exercitation est magna ex irure dolore nisi eiusmod ea exercitation."
  />
  <Field.String
    label="Label text"
    error={[new Error('Error message A'), new Error('Error message B')]}
    warning={['Warning message A', 'Warning message B']}
    info={['Info message A', 'Info message B']}
  />
</Form.Card>

With help

Code Editor
<Field.String
  label="Label text"
  defaultValue="foo"
  help={{
    title: 'Help is available',
    content:
      'Take the time to help other people without expecting a reward or gratitude is definitely important in living an optimistic life.',
  }}
  onChange={(value) => console.log('onChange', value)}
/>

Capitalize each word

Code Editor
<Field.String
  label="Label text"
  defaultValue="foo bar"
  capitalize
  onChange={(value) => console.log('onChange', value)}
/>

Icons

Code Editor
<Form.Card>
  <Field.String
    label="Icon left"
    defaultValue="foo"
    leftIcon="check"
    onChange={(value) => console.log('onChange', value)}
  />
  <Field.String
    label="Icon right"
    defaultValue="foo"
    rightIcon="loupe"
    onChange={(value) => console.log('onChange', value)}
  />
</Form.Card>

Clear

Code Editor
<Field.String
  defaultValue="foo"
  onChange={(value) => console.log('onChange', value)}
  clear
/>

Disabled

Code Editor
<Field.String
  defaultValue="foo"
  label="Label text"
  onChange={(value) => console.log('onChange', value)}
  disabled
/>

Validation - Required

Code Editor
<Field.String
  defaultValue="foo"
  label="Label text"
  onChange={(value) => console.log('onChange', value)}
  required
/>

Validation - Minimum length

Code Editor
<Field.String
  defaultValue="foo"
  label="Label text (minimum 8 characters)"
  onChange={(value) => console.log('onChange', value)}
  minLength={8}
/>

Validation - Maximum length and custom error message

Code Editor
<Field.String
  defaultValue="foo"
  label="Label text (maximum 8 characters)"
  onChange={(value) => console.log('onChange', value)}
  maxLength={8}
  errorMessages={{
    maxLength: "You can't write THAT long.. Max 8 chars!",
  }}
/>

Validation - Maximum length with TextCounter

8 av 8 tegn gjenstår.

Code Editor
const MyFieldStringWithTextCounter = () => {
  const [text, setText] = React.useState('')
  return (
    <Flex.Vertical gap="x-small">
      <Field.String
        label="Label text (maximum 8 characters)"
        maxLength={8}
        onChange={setText}
      />
      <TextCounter variant="down" text={text} max={8} />
    </Flex.Vertical>
  )
}
render(<MyFieldStringWithTextCounter />)

Validation - Pattern

Code Editor
<Field.String
  defaultValue="foo"
  label="Label text"
  onChange={(value) => console.log('onChange', value)}
  pattern="^foo123"
/>

Validation - Multiple Errors

Code Editor
<Field.String
  label="Multiple errors"
  defaultValue="foo"
  pattern="bar"
  minLength={4}
  validateInitially
/>

Synchronous external validator (called on every change)

Code Editor
<Field.String
  defaultValue="foo"
  label="Label text (minimum 4 characters)"
  onChangeValidator={(value) =>
    value.length < 4 ? Error('At least 4 characters') : undefined
  }
  onChange={(value) => console.log('onChange', value)}
/>

Asynchronous external validator (called on every change)

Code Editor
<Field.String
  defaultValue="foo"
  label="Label text (minimum 4 characters)"
  onChangeValidator={(value) =>
    new Promise((resolve) =>
      setTimeout(
        () =>
          resolve(
            value.length < 5 ? Error('At least 5 characters') : undefined,
          ),
        1500,
      ),
    )
  }
  onChange={(value) => console.log('onChange', value)}
/>

Synchronous external validator (called on blur)

Code Editor
<Field.String
  defaultValue="foo"
  label="Label text (minimum 4 characters)"
  onBlurValidator={(value) =>
    value.length < 4 ? Error('At least 4 characters') : undefined
  }
  onChange={(value) => console.log('onChange', value)}
/>

Asynchronous external validator (called on blur)

Code Editor
<Field.String
  defaultValue="foo"
  label="Label text (minimum 4 characters)"
  onBlurValidator={(value) =>
    new Promise((resolve) =>
      setTimeout(
        () =>
          resolve(
            value.length < 5 ? Error('At least 5 characters') : undefined,
          ),
        1500,
      ),
    )
  }
  onChange={(value) => console.log('onChange', value)}
/>

Multiline, empty

Code Editor
<Field.String
  onChange={(value) => console.log('onChange', value)}
  multiline
/>

Multiline, placeholder

Code Editor
<Field.String
  placeholder="Enter text here"
  onChange={(value) => console.log('onChange', value)}
  multiline
/>

Multiline, label & value

Code Editor
<Field.String
  defaultValue="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis in tempus odio, nec interdum orci. Integer vehicula ipsum et risus finibus, vitae commodo ex luctus. Nam viverra sollicitudin dictum. Vivamus maximus dignissim lorem, vitae viverra erat dapibus a."
  label="Label text"
  onChange={(value) => console.log('onChange', value)}
  multiline
/>

Multiline, with help

Code Editor
<Field.String
  label="Label text"
  help={{
    title: 'Help is available',
    content: 'There is more happiness in giving than in receiving.',
  }}
  multiline
  onChange={(value) => console.log('onChange', value)}
/>

TransformIn and TransformOut

String value(placeholder)

Data Context

"undefined" 
Code Editor
// From the Field (internal value) to the data context or event parameter
const transformOut = (value) => {
  return {
    value,
    foo: 'bar',
  }
}

// To the Field (from e.g. defaultValue)
const transformIn = (data) => {
  if (typeof data === 'string') {
    return data
  }
  return data?.value
}
const MyForm = () => {
  return (
    <Form.Handler onSubmit={console.log}>
      <Form.Card>
        <Field.String
          label="String field"
          path="/myValue"
          transformIn={transformIn}
          transformOut={transformOut}
          defaultValue="Default value"
        />

        <Value.String
          label="String value"
          path="/myValue"
          transformIn={transformIn}
          placeholder="(placeholder)"
          showEmpty
        />

        <Form.SubHeading>Data Context</Form.SubHeading>
        <Tools.Log />
      </Form.Card>
      <Form.SubmitButton />
    </Form.Handler>
  )
}
render(<MyForm />)

Prevent typing of invalid characters

You can use the onInput property together with the htmlAttributes property to prevent typing of invalid characters.

Code Editor
const forbiddenRegex = /\d/
const onInput = (event: React.FormEvent<HTMLInputElement>) => {
  const inputEl = event.currentTarget
  const oldVal = inputEl.dataset.oldVal || ''
  const addedLength = inputEl.value.length - oldVal.length
  const caretStart = inputEl.selectionStart
  const selectionStart = parseFloat(inputEl.dataset.selectionStart)
  const selectionEnd = parseFloat(inputEl.dataset.selectionEnd)
  let inserted = ''
  if (selectionStart !== selectionEnd) {
    inserted = inputEl.value.substring(selectionStart, selectionEnd)
  } else {
    inserted = inputEl.value.substring(
      caretStart - addedLength,
      caretStart,
    )
  }
  if (forbiddenRegex.test(inserted)) {
    inputEl.value = oldVal
    const { selectionStart, selectionEnd } = inputEl.dataset
    if (selectionStart !== selectionEnd) {
      inputEl.setSelectionRange(
        parseFloat(selectionStart),
        parseFloat(selectionEnd),
      )
    } else {
      inputEl.setSelectionRange(
        caretStart - addedLength,
        caretStart - addedLength,
      )
    }
  }
  inputEl.dataset.oldVal = inputEl.value
}
const onFocus = (event: React.FormEvent<HTMLInputElement>) => {
  const inputEl = event.currentTarget
  if (typeof inputEl.dataset.oldVal === 'undefined') {
    inputEl.dataset.oldVal = inputEl.value
  }
}
const onSelect = (event: React.FormEvent<HTMLInputElement>) => {
  const inputEl = event.currentTarget
  inputEl.dataset.selectionStart = String(inputEl.selectionStart)
  inputEl.dataset.selectionEnd = String(inputEl.selectionEnd)
}
render(
  <Form.Handler onSubmit={console.log} onChange={console.log}>
    <Form.Card>
      <Field.String
        path="/myValue"
        label="You can't type numbers here"
        value="Existing value: 123"
        htmlAttributes={{
          onFocus,
          onInput,
          onSelect,
        }}
        autoComplete="off"
        required
      />
    </Form.Card>

    <Form.SubmitButton />
  </Form.Handler>,
)

Widths