Skip to content

useDateFieldState: setValue not correctly setting value for incomplete fields #4791

@reidbarber

Description

@reidbarber

Discussed in #4790

Originally posted by Darmun July 19, 2023
Hello,

recently I've been working on custom Datepicker which would work with Calendar placed in container which doesn't block interactions with other elements on the page, and which is visible when focused on an input.

However I stumbled on problem with updating state of input fields: for some reason if input is clear, without any value, it won't update value, when I try to invoke state.setValue destructured from useDateFieldState from button/RAC Calendar. Here is codesandbox with reproduction, and below code I wrote for this.

To reproduce, try click button with set date label. Despite an action, input will not update.

It works fine, if first value is set manually, and then button is used.

import { createCalendar, parseDate } from "@internationalized/date";
import { useRef } from "react";
import { useDateField, useDateSegment, useLocale } from "react-aria";
import { useDateFieldState } from "react-stately";

export function DateField(props) {
  const { label, ...rest } = props;
  const { locale } = useLocale();

  const state = useDateFieldState({
    ...rest,
    locale,
    createCalendar
  });

  const ref = useRef(null);
  const { labelProps, fieldProps } = useDateField(props, state, ref);

  return (
    <div
      className="wrapper"
      style={{
        display: "flex",
        flexDirection: "column",
        alignItems: "flex-start"
      }}
    >
      <span {...labelProps}>{label || "fallback label"}</span>
      <div
        {...fieldProps}
        ref={ref}
        className="field"
        style={{
          display: "inline-flex",
          padding: "2px 4px",
          border: "1px solid black",
          borderRadius: "2px"
        }}
      >
        {state.segments.map((segment, i) => (
          <DateSegment key={segment.type} segment={segment} state={state} />
        ))}
      </div>
      <button onClick={() => state.setValue(parseDate("2023-07-07"))}>
        set date
      </button>
    </div>
  );
}

function DateSegment({ segment, state }) {
  const ref = useRef(null);
  const { segmentProps } = useDateSegment(segment, state, ref);

  return (
    <div
      {...segmentProps}
      ref={ref}
      className={`segment ${segment.isPlaceholder ? "placeholder" : ""}`}
    >
      {segment.text}
    </div>
  );
}

Is there a mistake in the example? Or am I missing something?

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    Status

    ✅ Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions