date-io icon indicating copy to clipboard operation
date-io copied to clipboard

Improve documenation for quickly using this as a wrapper for other date libraries

Open YPCrumble opened this issue 3 years ago • 2 comments

I've read the README and I think that this library may do what I want it to, but I'm not sure. If it does do what I think it does, I would love to help improve the README to make the potential clearer!

Here's what I'm looking for:

I want a wrapper around MomentJS, date-fns, dayjs, luxon, that allows me as a library author to use date-io in my library and then allow users of the library to install one of those four alternatives as a peer dependency, and the date functionality should just work.

So essentially, let's say I'm using MomentJS. I should be able to replace this code:

// my-logic-file.js
import moment from 'moment'

const now = moment().format('MMMM Do YYYY, h:mm:ss a')
console.log(now)

with something like this:

// custom-date-io.js
import dateio from 'dateio'
import moment from 'moment'

dateio.setup(moment)
export default dateio
// my-logic-file.js
import dateio from 'custom-date-io'

// I'm pretty sure this is the dateio format but not 100% sure
const now = dateio.date().format('fullDateTime12h')
console.log(now)

In the README, however, it appears that as a library author I have to choose one specific library for my users. For instance, the example in the readme chooses date-fns for its users here:

// you-awesome-lib/adapters/date-fns
export { default } from "@date-io/date-fns";

So perhaps what I'm looking for is not currently possible?

Thanks for building this and for taking a look at this issue!

YPCrumble avatar May 02 '22 14:05 YPCrumble

The idea of this library is that your users are choosing the right adapter and you are using it according the public interface we have. I will think how to improve readme but the idea is simple –

  1. you are exposing date-io adapters to your users
  2. user chooses one of available and giving you this interface
  3. you are using it according to documented interface because you know that all of them producing equal results

Basically this example is for your user

import { createMyAdapter } from "your-awesome-lib/adapters/date-fns";

<DateLibProvider adapter={createMyAdapter({ locale: "fr" })}>{/* ... */}</DateLibProvider>;

And this is your usage:

import { IUtils } from "@date-io/core/IUtils";

function myFunctionInLibrary<TDate>(date: TDate, adapter: IUtils<TDate>) {
  // ...
  const weekArray = adapter.getWeekArray(Date);
  // ...
}

dmtrKovalenko avatar May 02 '22 14:05 dmtrKovalenko

I agree that the README is confusing - not everyone uses React or tsx, so the examples are not clear.

Here is what I pieced together for a clearer example:


Create your own library:

// my-awesome-lib

// Choose which adapters library will support, and re-export them
export { default as dateFnsAdapter } from '@date-io/date-fns';
export { default as dayJsAdapter } from '@date-io/dayjs';
export { default as luxonAdapter } from '@date-io/luxon';

// Export new library code
export default class AwesomeLib {
    MyAdapter; // Will be one of the adapters above, which all have common interface

    // Adapter will be supplied by user of my-awesome-lib
    constructor(adapter) {
        this.MyAdapter = adapter;
    }

    function add5DaysAndFormat(theDate) {
        // Perform the following actions using the common adapter interface:
        //  - Create a new date instance
        //  - Manipulate the date (add 5 days)
        //  - Format the date (using one of the preset formats)
        const myDate = this.MyAdapter.date(theDate);
        const myDatePlus5 = this.MyAdapter.addDays(myDate, 5);
        const formattedResult = this.MyAdapter.format(myDatePlus5, 'fullDate');

        // Return the resulting string
        return formattedResult;
    }
}

Others use your library with whatever they choose - for example, dayjs:

// someone-using-my-awesome-lib
import dayjs from 'dayjs';

// They import your library, and the adapter that matches their own date library
import AwesomeLib, { dayJsAdapter } from 'my-awesome-lib';
const awesomeInstance = new AwesomeLib(new dayJsAdapter());

// They can use your library via the adapter they chose
const tomorrow = dayjs().add(1, 'day').toDate(); // JS Date via dayjs - eg. Sat Oct 22 2022 13:31:50 GMT-600
const tomorrowPlus5 = awesomeInstance.add5DaysAndFormat(tomorrow); // String via your lib - Oct 27, 2022

Or date-fns:

// someone-using-my-awesome-lib
import { addDays } from 'date-fns';

// They import your library, and the adapter that matches their own date library
import AwesomeLib, { dateFnsAdapter } from 'my-awesome-lib';
const awesomeInstance = new AwesomeLib(new dateFnsAdapter());

// They can use your library via the adapter they chose
const tomorrow = addDays(new Date(), 1); // JS Date via date-fns - eg. Sat Oct 22 2022 13:31:50 GMT-600
const tomorrowPlus5 = awesomeInstance.add5DaysAndFormat(tomorrow); // String via your lib - Oct 27, 2022

mgdodge avatar Oct 21 '22 19:10 mgdodge