Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Component for selecting a time interval #77

Open
Estasie opened this issue May 17, 2024 · 2 comments
Open

Component for selecting a time interval #77

Estasie opened this issue May 17, 2024 · 2 comments
Labels
enhancement New feature or request

Comments

@Estasie
Copy link

Estasie commented May 17, 2024

We already have RangeDatePicker and RelativeRangeDatePicker components, so we can create a set of new auxiliary components.
For example, if I want to pick a time now I have to open time picker6 click the date, select to value and click Apply button.
To solve this problem I suggest:

  1. Make a shortcuts component with a buttons set (should be customizable, depending on user's needs and also provide default shortcuts). The Controls will have a RelativeRangeDatePicker under the hood and operate with absolute and relative data types.
    Example of usage:
    <Controls from={from} to={to} onUpdate={onUpdate} // ... />
  2. And my favourite one and a very convenient thing to use - timeline ruler. Visually, it is a time band that allows you to navigate through time intervals, shorten and distance them in order to explore segments of different sizes. For example, for the last day, week, a couple of minutes, a certain time interval.
    I suggest making this component initially independent and working with an absolute dates. But provide a hook for a possible combination of Controls and Ruler (make them work together).
    Simple example of Ruler usage:
<Timeline
                from={fromMillis}
                to={toMillis}
                onUpdate={onUpdateMillis}
                // ...
 />

Pretty simple and same as controls.

An example of common usage of the components (remembering hook):

import {ThinTimelineRuler, ThinTimelineControls, useThinTimelineRuler, TimelineProps} from '...';

export function MyComponent() {
    const [{from, to}, onUpdate] = React.useState<TimelineProps>(/* ... */);

    const {
        fromMillis,
        toMillis,
        onUpdateMillis,
    } = useTimeline({from, to, onUpdate});

    // ...

    return (
        <div>
            <Controls
                from={from}
                to={to}
                onUpdate={onUpdate}
                // ...
            />
            <Timeline
                from={frommillis}
                to={toMillis}
                onUpdate={onUpdateMillis}
                // ...
            />
        </div>
    );
}

We can also provide some usable hooks and etc. Open to discuss details and API!

@Estasie
Copy link
Author

Estasie commented May 17, 2024

Interface for ThinTimelineRuler

interface Period {
    /** Selected period start (millis from epoch) */
    start: number;
    /** Selected period end (millis from epoch) */
    end: number;
}
interface HasHandlesProp {
    /**
     * If `false` handles are not shown and cannot be dragged.
     * Selection window will have bordered style
     */
    hasHandles?: boolean;
}
interface UncontrolledThinTimelineRulerProps extends Period, HasHandlesProp {
    /** Gets invoked whenever selected period gets updated */
    onUpdate?: (value: Period) => void;
    /** If display red line denoting current instant */
    displayNow?: boolean;
    /** If render '-' and '+' buttons */
    hasZoomButtons?: boolean;
    /** Position of the '-' and '+' zoom buttons */
    zoomButtonsPosition?: 'left' | 'right';
    /** Use this to customize rendering of selected period */
    renderSelection?: (opts: RenderSelectionOptions) => React.ReactNode;
    /** Use this to render additional SVG nodes on the ruler */
    renderAdditionalSvg?: (opts: RenderSelectionOptions) => React.ReactNode;
    /** Use this to allow custom rendering of time ticks */
    formatTime?: (time: DateTime) => string;

    /**
     * This prop can be used to specify the point of maximal interest in the
     * selected period. 0 means the earliest point, 1 means the latest, 0.5 can
     * be used to mark the middle of the selected period.
     *
     * When zoom buttons are pressed, this point in the selected period will
     * remain fixed.
     */
    pointOfMaxInterest?: number;

    /** Min ruler viewport length (ms, default is 1m) */
    viewportMinLength?: number;
    /** Max ruler viewport length (ms, default is 20y) */
    viewportMaxLength?: number;

    /** Fixed ruler viewport start point (ms) */
    viewportStart?: number;
    /** Fixed ruler viewport end point (ms) */
    viewportEnd?: number;

    /** If disabled, prevents timeline drag. Default: true */
    isTimelineDragEnabled?: boolean;

    /**
     * Specify this if you want to override the timeZone used when parsing or formatting a date and time value.
     * If no timeZone is set, the default timeZone for the current user is used.
     */
    timeZone?: string;

    className?: string;
}

Interface for Controls:

interface ThinTimelineControlsProps {
    value: RelativeRangeDatePickerProps['value'];

    /** Gets called whenever selected period, stickToNow, or period name are updated */
    onUpdate: (value: RelativeRangeDatePickerProps['value']) => void;

    /** Presets for toolbar at the top as duration strings (e.g. '1m', '15d', '1y') */
    toolbarPresets?: string[];
    /** Presets for date input popup as duration strings (e.g. '1m', '15d', '1y') */
    relativeRangesPalette?: string[];
    /** Enables/disables toolbar custom button that is used to input arbitrary duration string */
    hasCustomPresetInput?: boolean;

    /** Indicates whether to add a 'Now' block */
    withNow?: boolean;
    /** Indicates whether to show popup presets */
    withPresets?: boolean;
    /** Indicates whether to add a range date picker block */
    withRangeDatePicker?: boolean;

    /** Set one of proposed date and time formats in Datepicker [Available formats](https://day.js.org/docs/en/display/format) */
    format?: string;
    /** Indicates whether to add a refresh block */
    withRefresh?: boolean;
    /** Selected refresh interval value (milliseconds, 0 = off) */
    refreshInterval?: number;
    /** Available refresh interval options (milliseconds, 0 = off) */
    availableRefreshIntervals?: number[];
    alwaysShowAsAbsolute?: boolean;
    /** Gets invoked whenever refresh interval is updated */
    onRefreshIntervalUpdate?: (value: number) => void;
    /** Gets invoked when refresh button is clicked */
    onRefreshClick?: () => void;
    /**
     * If `true`, selected refresh interval is rendered as human-readable string;
     * otherwise shorthand duration string is used (e.g. '30s')
     */
    humanReadableActiveRefreshInterval?: boolean;
    /**
     * Allows to specify a default refresh interval. If 'Now' button gets clicked,
     * this interval will be automatically enabled.
     * If not provided, the first non-zero value from `availableRefreshIntervals`
     * will be taken.
     */
    defaultRefreshInterval?: number;

    className?: string;

    /**
     * Custom content to render before all toolbar items.
     * Can be utilized to reuse the same flex container as the rest of the toolbar.
     */
    prepend?: React.ReactNode;
    /** Same as `prepend`, but after all toolbar items. */
    append?: React.ReactNode;

    /**
     * This prop can be used to specify the point of maximal interest in the
     * selected period. 0 means the earliest point, 1 means the latest, 0.5 can
     * be used to mark the middle of the selected period.
     *
     * When 'Now' button is pressed, this point is set to match current datetime.
     */
    pointOfMaxInterest?: number;

    /**
     * Maximum time limit for suggest values
     * By default, suggest includes values up to '2y'
     * With this prop you can set max suggest value
     */
    suggestLimit?: string;

    /**
     * Specify this if you want to override the timeZone used when parsing or formatting a date and time value.
     * If no timeZone is set, the default timeZone for the current user is used.
     */
    timeZone?: string;
}

@korvin89 korvin89 added the enhancement New feature or request label May 17, 2024
@korvin89
Copy link
Contributor

cc @ValeraS

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants