dan-lee / timescape

A flexible, headless date and time input library for JavaScript. Provides tools for building fully customizable date and time input fields, with support for libraries like React, Preact, Vue, Svelte and Solid.
https://timescape.daniellehr.de
MIT License
155 stars 2 forks source link

`useTimescape` / `useTimescapeRange` should be Reactive by default #40

Open junwen-k opened 3 weeks ago

junwen-k commented 3 weeks ago

Recently I've just came across this library, exactly what I was looking for a long time, awesome! However, there is a slight problem with the React (and possibly other frameworks) integration.

Problem

Currently, useTimescape is not declarative by default, and to sync the state with external sources, we need to use useEffect to handle it manually.

const [date, setDate] = React.useState(new Date());

const { getRootProps, getInputProps, update } = useTimescape({
  date, // This is the default value (initial value) and is not reactive by default, which is not ideal in my opinion.
  onValueChange: setDate,
});

// In controlled mode, we need to add this manually to sync changes in `date` from an external source.
React.useEffect(() => {
  update((prevOptions) => ({
    ...prevOptions,
    date,
  }));
}, [date]);

// We need to repeat `useEffect` for each individual option if any option changes.

Suggestion

To better align with the declarative nature of React, useTimescape should be reactive by default, without requiring users to call update() imperatively. For instance:

// `update`, `options`, `_manager` don’t need to be exposed.
const { getRootProps, getInputProps } = useTimescape({
  // Inspired by Radix's API
  value, // or `date` for controlled mode
  defaultValue, // or `defaultDate` for uncontrolled mode
  onValueChange, // or `onDateChange`, called with the new value on change
  ...options, // All options should be reactive by default
});

This change aligns well with the React ecosystem API, making it more predictable and declarative.

Remark

Some popular libraries that uses the method that I described

This proposed change could also potentially apply to other frameworks like Solid.


Thank you so much for this awesome library.

dan-lee commented 3 weeks ago

Hey @junwen-k, thanks for flagging this! I agree that this would be a good change for the React implementation. However, I am not so sure about the other integrations (because I haven't worked intensively with them before).

I don't know if I'll be able to get to this soon, but if you want to shoot a PR I'd appreciate it. No worries if not :)