@tcn/ui-time-selector 2.0.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/time_selector/time_selector.d.ts +3 -1
- package/dist/components/time_selector/time_selector.d.ts.map +1 -1
- package/dist/components/time_selector/time_selector.js +57 -51
- package/dist/components/time_selector/time_selector.js.map +1 -1
- package/dist/components/time_selector/time_selector_presenter.d.ts +1 -0
- package/dist/components/time_selector/time_selector_presenter.d.ts.map +1 -1
- package/dist/components/time_selector/time_selector_presenter.js +24 -20
- package/dist/components/time_selector/time_selector_presenter.js.map +1 -1
- package/package.json +3 -3
- package/src/__stories__/time_selector.stories.tsx +73 -0
- package/src/components/time_selector/time_selector.tsx +11 -1
- package/src/components/time_selector/time_selector_presenter.ts +11 -0
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
export interface TimeSelectorOwnProps {
|
|
2
2
|
onChange?: (start: Date, end: Date) => void;
|
|
3
3
|
onTimezoneChange?: (timezone: string) => void;
|
|
4
|
+
startDate?: Date | null;
|
|
5
|
+
endDate?: Date | null;
|
|
4
6
|
startDateMin?: Date | null;
|
|
5
7
|
startDateMax?: Date | null;
|
|
6
8
|
endDateMin?: Date | null;
|
|
@@ -8,5 +10,5 @@ export interface TimeSelectorOwnProps {
|
|
|
8
10
|
timezones?: string[];
|
|
9
11
|
}
|
|
10
12
|
export type TimeSelectorProps = TimeSelectorOwnProps;
|
|
11
|
-
export declare function TimeSelector({ onChange, onTimezoneChange, startDateMin, startDateMax, endDateMin, endDateMax, timezones, }: TimeSelectorProps): import("react/jsx-runtime").JSX.Element;
|
|
13
|
+
export declare function TimeSelector({ onChange, onTimezoneChange, startDate, endDate, startDateMin, startDateMax, endDateMin, endDateMax, timezones, }: TimeSelectorProps): import("react/jsx-runtime").JSX.Element;
|
|
12
14
|
//# sourceMappingURL=time_selector.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"time_selector.d.ts","sourceRoot":"","sources":["../../../src/components/time_selector/time_selector.tsx"],"names":[],"mappings":"AAaA,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,KAAK,IAAI,CAAC;IAC5C,gBAAgB,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9C,YAAY,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IAC3B,YAAY,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IAC3B,UAAU,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IACzB,UAAU,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,MAAM,MAAM,iBAAiB,GAAG,oBAAoB,CAAC;AAErD,wBAAgB,YAAY,CAAC,EAC3B,QAAQ,EACR,gBAAgB,EAChB,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,UAAU,EACV,SAAS,GACV,EAAE,iBAAiB,
|
|
1
|
+
{"version":3,"file":"time_selector.d.ts","sourceRoot":"","sources":["../../../src/components/time_selector/time_selector.tsx"],"names":[],"mappings":"AAaA,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,KAAK,IAAI,CAAC;IAC5C,gBAAgB,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9C,SAAS,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IACxB,OAAO,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IACtB,YAAY,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IAC3B,YAAY,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IAC3B,UAAU,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IACzB,UAAU,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,MAAM,MAAM,iBAAiB,GAAG,oBAAoB,CAAC;AAErD,wBAAgB,YAAY,CAAC,EAC3B,QAAQ,EACR,gBAAgB,EAChB,SAAS,EACT,OAAO,EACP,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,UAAU,EACV,SAAS,GACV,EAAE,iBAAiB,2CA2EnB"}
|
|
@@ -1,97 +1,103 @@
|
|
|
1
|
-
import { jsxs as r, Fragment as
|
|
1
|
+
import { jsxs as r, Fragment as x, jsx as t } from "react/jsx-runtime";
|
|
2
2
|
import { useSignalValue as n } from "@tcn/state";
|
|
3
|
-
import { ElementPopper as
|
|
4
|
-
import { HStack as
|
|
5
|
-
import { BodyText as
|
|
6
|
-
import { ChevronDownIcon as
|
|
7
|
-
import { ChevronUpIcon as
|
|
8
|
-
import { useState as
|
|
9
|
-
import { TimeSelectorPresenter as
|
|
10
|
-
import { PresetPanel as
|
|
11
|
-
import { DateRangePanel as
|
|
12
|
-
import { TimezoneFooter as
|
|
13
|
-
import '../../time_selector.css';const
|
|
14
|
-
function
|
|
15
|
-
onChange:
|
|
3
|
+
import { ElementPopper as z } from "@tcn/ui/overlay";
|
|
4
|
+
import { HStack as f, VStack as _ } from "@tcn/ui/stacks";
|
|
5
|
+
import { BodyText as g } from "@tcn/ui/typography";
|
|
6
|
+
import { ChevronDownIcon as w } from "@tcn/icons/chevron_down_icon.js";
|
|
7
|
+
import { ChevronUpIcon as A } from "@tcn/icons/chevron_up_icon.js";
|
|
8
|
+
import { useState as E, useRef as R, useEffect as T } from "react";
|
|
9
|
+
import { TimeSelectorPresenter as k } from "./time_selector_presenter.js";
|
|
10
|
+
import { PresetPanel as F } from "../preset_panel/preset_panel.js";
|
|
11
|
+
import { DateRangePanel as V } from "../date_range_panel/date_range_panel.js";
|
|
12
|
+
import { TimezoneFooter as C } from "../timezone_footer/timezone_footer.js";
|
|
13
|
+
import '../../time_selector.css';const N = "_trigger-abbreviation_8e22c20", O = "_trigger_1096f0b", j = "_popper-content_9403264", c = { "trigger-abbreviation": N, trigger: O, "popper-content": j };
|
|
14
|
+
function Q({
|
|
15
|
+
onChange: p,
|
|
16
16
|
onTimezoneChange: d,
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
17
|
+
startDate: s,
|
|
18
|
+
endDate: i,
|
|
19
|
+
startDateMin: h,
|
|
20
|
+
startDateMax: u,
|
|
21
|
+
endDateMin: b,
|
|
22
|
+
endDateMax: P,
|
|
23
|
+
timezones: v
|
|
22
24
|
}) {
|
|
23
|
-
const [e] =
|
|
25
|
+
const [e] = E(() => new k()), m = R(null);
|
|
26
|
+
T(() => {
|
|
27
|
+
s != null && i != null && e.setExternalDates(s, i);
|
|
28
|
+
}, [s, i, e]);
|
|
29
|
+
const o = n(e.broadcasts.isOpen), l = n(e.broadcasts.selectedPreset), y = n(e.broadcasts.displayValue), S = n(
|
|
24
30
|
e.timezoneFooterPresenter.broadcasts.timezoneAbbreviation
|
|
25
31
|
);
|
|
26
|
-
return /* @__PURE__ */ r(
|
|
32
|
+
return /* @__PURE__ */ r(x, { children: [
|
|
27
33
|
/* @__PURE__ */ t(
|
|
28
34
|
"div",
|
|
29
35
|
{
|
|
30
|
-
ref:
|
|
31
|
-
className:
|
|
36
|
+
ref: m,
|
|
37
|
+
className: c.trigger,
|
|
32
38
|
onClick: () => e.toggleOpen(),
|
|
33
|
-
children: /* @__PURE__ */ r(
|
|
34
|
-
/* @__PURE__ */ r(
|
|
35
|
-
|
|
39
|
+
children: /* @__PURE__ */ r(f, { height: "auto", width: "auto", gap: "4px", children: [
|
|
40
|
+
/* @__PURE__ */ r(g, { selectable: !1, children: [
|
|
41
|
+
y,
|
|
36
42
|
","
|
|
37
43
|
] }),
|
|
38
44
|
/* @__PURE__ */ t(
|
|
39
|
-
|
|
45
|
+
g,
|
|
40
46
|
{
|
|
41
47
|
selectable: !1,
|
|
42
48
|
style: { fontWeight: 700 },
|
|
43
|
-
className:
|
|
44
|
-
children:
|
|
49
|
+
className: c["trigger-abbreviation"],
|
|
50
|
+
children: S
|
|
45
51
|
}
|
|
46
52
|
),
|
|
47
|
-
o ? /* @__PURE__ */ t(
|
|
53
|
+
o ? /* @__PURE__ */ t(A, { size: "sm" }) : /* @__PURE__ */ t(w, { size: "sm" })
|
|
48
54
|
] })
|
|
49
55
|
}
|
|
50
56
|
),
|
|
51
57
|
/* @__PURE__ */ t(
|
|
52
|
-
|
|
58
|
+
z,
|
|
53
59
|
{
|
|
54
|
-
anchorElement:
|
|
60
|
+
anchorElement: m,
|
|
55
61
|
open: o,
|
|
56
62
|
onDismissal: () => e.close(),
|
|
57
63
|
dismissals: [],
|
|
58
64
|
children: /* @__PURE__ */ r(
|
|
59
|
-
|
|
65
|
+
_,
|
|
60
66
|
{
|
|
61
|
-
className:
|
|
67
|
+
className: c["popper-content"],
|
|
62
68
|
height: "auto",
|
|
63
|
-
onKeyDown: (
|
|
64
|
-
|
|
69
|
+
onKeyDown: (a) => {
|
|
70
|
+
a.key === "Escape" && e.close();
|
|
65
71
|
},
|
|
66
72
|
children: [
|
|
67
|
-
/* @__PURE__ */ r(
|
|
73
|
+
/* @__PURE__ */ r(f, { height: "auto", width: "100%", vAlign: "start", children: [
|
|
68
74
|
/* @__PURE__ */ t(
|
|
69
|
-
|
|
75
|
+
V,
|
|
70
76
|
{
|
|
71
77
|
presenter: e.dateRangePanelPresenter,
|
|
72
|
-
focused: o &&
|
|
73
|
-
startDateMin:
|
|
74
|
-
startDateMax:
|
|
75
|
-
endDateMin:
|
|
76
|
-
endDateMax:
|
|
77
|
-
onApply: () => e.applyTimeRange(
|
|
78
|
+
focused: o && l == null,
|
|
79
|
+
startDateMin: h,
|
|
80
|
+
startDateMax: u,
|
|
81
|
+
endDateMin: b,
|
|
82
|
+
endDateMax: P,
|
|
83
|
+
onApply: () => e.applyTimeRange(p)
|
|
78
84
|
}
|
|
79
85
|
),
|
|
80
86
|
/* @__PURE__ */ t(
|
|
81
|
-
|
|
87
|
+
F,
|
|
82
88
|
{
|
|
83
89
|
presenter: e.presetPanelPresenter,
|
|
84
|
-
selectedPreset:
|
|
85
|
-
focused: o &&
|
|
86
|
-
onSelect: (
|
|
90
|
+
selectedPreset: l,
|
|
91
|
+
focused: o && l != null,
|
|
92
|
+
onSelect: (a) => e.handlePresetSelect(a, p)
|
|
87
93
|
}
|
|
88
94
|
)
|
|
89
95
|
] }),
|
|
90
96
|
/* @__PURE__ */ t(
|
|
91
|
-
|
|
97
|
+
C,
|
|
92
98
|
{
|
|
93
99
|
presenter: e.timezoneFooterPresenter,
|
|
94
|
-
timezones:
|
|
100
|
+
timezones: v,
|
|
95
101
|
onTimezoneChange: d
|
|
96
102
|
}
|
|
97
103
|
)
|
|
@@ -103,6 +109,6 @@ function J({
|
|
|
103
109
|
] });
|
|
104
110
|
}
|
|
105
111
|
export {
|
|
106
|
-
|
|
112
|
+
Q as TimeSelector
|
|
107
113
|
};
|
|
108
114
|
//# sourceMappingURL=time_selector.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"time_selector.js","sources":["../../../src/components/time_selector/time_selector.tsx"],"sourcesContent":["import { useSignalValue } from '@tcn/state';\nimport { ElementPopper } from '@tcn/ui/overlay';\nimport { HStack, VStack } from '@tcn/ui/stacks';\nimport { BodyText } from '@tcn/ui/typography';\nimport { ChevronDownIcon } from '@tcn/icons/chevron_down_icon.js';\nimport { ChevronUpIcon } from '@tcn/icons/chevron_up_icon.js';\nimport { useRef, useState } from 'react';\nimport { TimeSelectorPresenter } from './time_selector_presenter.js';\nimport { PresetPanel } from '../preset_panel/preset_panel.js';\nimport { DateRangePanel } from '../date_range_panel/date_range_panel.js';\nimport { TimezoneFooter } from '../timezone_footer/timezone_footer.js';\nimport styles from './time_selector.module.css';\n\nexport interface TimeSelectorOwnProps {\n onChange?: (start: Date, end: Date) => void;\n onTimezoneChange?: (timezone: string) => void;\n startDateMin?: Date | null;\n startDateMax?: Date | null;\n endDateMin?: Date | null;\n endDateMax?: Date | null;\n timezones?: string[];\n}\n\nexport type TimeSelectorProps = TimeSelectorOwnProps;\n\nexport function TimeSelector({\n onChange,\n onTimezoneChange,\n startDateMin,\n startDateMax,\n endDateMin,\n endDateMax,\n timezones,\n}: TimeSelectorProps) {\n const [presenter] = useState(() => new TimeSelectorPresenter());\n const anchorRef = useRef<HTMLDivElement>(null);\n\n const isOpen = useSignalValue(presenter.broadcasts.isOpen);\n const selectedPreset = useSignalValue(presenter.broadcasts.selectedPreset);\n const displayValue = useSignalValue(presenter.broadcasts.displayValue);\n const displayAbbreviation = useSignalValue(\n presenter.timezoneFooterPresenter.broadcasts.timezoneAbbreviation\n );\n\n return (\n <>\n <div\n ref={anchorRef}\n className={styles.trigger}\n onClick={() => presenter.toggleOpen()}\n >\n <HStack height=\"auto\" width=\"auto\" gap=\"4px\">\n <BodyText selectable={false}>{displayValue},</BodyText>\n <BodyText\n selectable={false}\n style={{ fontWeight: 700 }}\n className={styles['trigger-abbreviation']}\n >\n {displayAbbreviation}\n </BodyText>\n {isOpen ? <ChevronUpIcon size=\"sm\" /> : <ChevronDownIcon size=\"sm\" />}\n </HStack>\n </div>\n <ElementPopper\n anchorElement={anchorRef}\n open={isOpen}\n onDismissal={() => presenter.close()}\n dismissals={[]}\n >\n <VStack\n className={styles['popper-content']}\n height=\"auto\"\n onKeyDown={e => {\n if (e.key === 'Escape') presenter.close();\n }}\n >\n <HStack height=\"auto\" width=\"100%\" vAlign=\"start\">\n <DateRangePanel\n presenter={presenter.dateRangePanelPresenter}\n focused={isOpen && selectedPreset == null}\n startDateMin={startDateMin}\n startDateMax={startDateMax}\n endDateMin={endDateMin}\n endDateMax={endDateMax}\n onApply={() => presenter.applyTimeRange(onChange)}\n />\n <PresetPanel\n presenter={presenter.presetPanelPresenter}\n selectedPreset={selectedPreset}\n focused={isOpen && selectedPreset != null}\n onSelect={item => presenter.handlePresetSelect(item, onChange)}\n />\n </HStack>\n <TimezoneFooter\n presenter={presenter.timezoneFooterPresenter}\n timezones={timezones}\n onTimezoneChange={onTimezoneChange}\n />\n </VStack>\n </ElementPopper>\n </>\n );\n}\n"],"names":["TimeSelector","onChange","onTimezoneChange","startDateMin","startDateMax","endDateMin","endDateMax","timezones","presenter","useState","TimeSelectorPresenter","anchorRef","useRef","isOpen","useSignalValue","selectedPreset","displayValue","displayAbbreviation","jsxs","Fragment","jsx","styles","HStack","BodyText","ChevronUpIcon","ChevronDownIcon","ElementPopper","VStack","e","DateRangePanel","PresetPanel","item","TimezoneFooter"],"mappings":";;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"time_selector.js","sources":["../../../src/components/time_selector/time_selector.tsx"],"sourcesContent":["import { useSignalValue } from '@tcn/state';\nimport { ElementPopper } from '@tcn/ui/overlay';\nimport { HStack, VStack } from '@tcn/ui/stacks';\nimport { BodyText } from '@tcn/ui/typography';\nimport { ChevronDownIcon } from '@tcn/icons/chevron_down_icon.js';\nimport { ChevronUpIcon } from '@tcn/icons/chevron_up_icon.js';\nimport { useEffect, useRef, useState } from 'react';\nimport { TimeSelectorPresenter } from './time_selector_presenter.js';\nimport { PresetPanel } from '../preset_panel/preset_panel.js';\nimport { DateRangePanel } from '../date_range_panel/date_range_panel.js';\nimport { TimezoneFooter } from '../timezone_footer/timezone_footer.js';\nimport styles from './time_selector.module.css';\n\nexport interface TimeSelectorOwnProps {\n onChange?: (start: Date, end: Date) => void;\n onTimezoneChange?: (timezone: string) => void;\n startDate?: Date | null;\n endDate?: Date | null;\n startDateMin?: Date | null;\n startDateMax?: Date | null;\n endDateMin?: Date | null;\n endDateMax?: Date | null;\n timezones?: string[];\n}\n\nexport type TimeSelectorProps = TimeSelectorOwnProps;\n\nexport function TimeSelector({\n onChange,\n onTimezoneChange,\n startDate,\n endDate,\n startDateMin,\n startDateMax,\n endDateMin,\n endDateMax,\n timezones,\n}: TimeSelectorProps) {\n const [presenter] = useState(() => new TimeSelectorPresenter());\n const anchorRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n if (startDate != null && endDate != null) {\n presenter.setExternalDates(startDate, endDate);\n }\n }, [startDate, endDate, presenter]);\n\n const isOpen = useSignalValue(presenter.broadcasts.isOpen);\n const selectedPreset = useSignalValue(presenter.broadcasts.selectedPreset);\n const displayValue = useSignalValue(presenter.broadcasts.displayValue);\n const displayAbbreviation = useSignalValue(\n presenter.timezoneFooterPresenter.broadcasts.timezoneAbbreviation\n );\n\n return (\n <>\n <div\n ref={anchorRef}\n className={styles.trigger}\n onClick={() => presenter.toggleOpen()}\n >\n <HStack height=\"auto\" width=\"auto\" gap=\"4px\">\n <BodyText selectable={false}>{displayValue},</BodyText>\n <BodyText\n selectable={false}\n style={{ fontWeight: 700 }}\n className={styles['trigger-abbreviation']}\n >\n {displayAbbreviation}\n </BodyText>\n {isOpen ? <ChevronUpIcon size=\"sm\" /> : <ChevronDownIcon size=\"sm\" />}\n </HStack>\n </div>\n <ElementPopper\n anchorElement={anchorRef}\n open={isOpen}\n onDismissal={() => presenter.close()}\n dismissals={[]}\n >\n <VStack\n className={styles['popper-content']}\n height=\"auto\"\n onKeyDown={e => {\n if (e.key === 'Escape') presenter.close();\n }}\n >\n <HStack height=\"auto\" width=\"100%\" vAlign=\"start\">\n <DateRangePanel\n presenter={presenter.dateRangePanelPresenter}\n focused={isOpen && selectedPreset == null}\n startDateMin={startDateMin}\n startDateMax={startDateMax}\n endDateMin={endDateMin}\n endDateMax={endDateMax}\n onApply={() => presenter.applyTimeRange(onChange)}\n />\n <PresetPanel\n presenter={presenter.presetPanelPresenter}\n selectedPreset={selectedPreset}\n focused={isOpen && selectedPreset != null}\n onSelect={item => presenter.handlePresetSelect(item, onChange)}\n />\n </HStack>\n <TimezoneFooter\n presenter={presenter.timezoneFooterPresenter}\n timezones={timezones}\n onTimezoneChange={onTimezoneChange}\n />\n </VStack>\n </ElementPopper>\n </>\n );\n}\n"],"names":["TimeSelector","onChange","onTimezoneChange","startDate","endDate","startDateMin","startDateMax","endDateMin","endDateMax","timezones","presenter","useState","TimeSelectorPresenter","anchorRef","useRef","useEffect","isOpen","useSignalValue","selectedPreset","displayValue","displayAbbreviation","jsxs","Fragment","jsx","styles","HStack","BodyText","ChevronUpIcon","ChevronDownIcon","ElementPopper","VStack","e","DateRangePanel","PresetPanel","item","TimezoneFooter"],"mappings":"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"}
|
|
@@ -23,6 +23,7 @@ export declare class TimeSelectorPresenter {
|
|
|
23
23
|
handlePresetSelect(item: PresetItem, onChange?: (start: Date, end: Date) => void): void;
|
|
24
24
|
applyTimeRange(onChange?: (start: Date, end: Date) => void): void;
|
|
25
25
|
toggleOpen(): void;
|
|
26
|
+
setExternalDates(start: Date, end: Date): void;
|
|
26
27
|
close(): void;
|
|
27
28
|
}
|
|
28
29
|
//# sourceMappingURL=time_selector_presenter.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"time_selector_presenter.d.ts","sourceRoot":"","sources":["../../../src/components/time_selector/time_selector_presenter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AACpC,OAAO,EAKL,KAAK,UAAU,EAChB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,uBAAuB,EAAE,MAAM,mDAAmD,CAAC;AAC5F,OAAO,EAAE,uBAAuB,EAAE,MAAM,iDAAiD,CAAC;AAE1F,YAAY,EAAE,UAAU,EAAE,CAAC;AAE3B,eAAO,MAAM,YAAY,EAAE,UAAU,EAYpC,CAAC;AAEF,qBAAa,qBAAqB;IAChC,OAAO,CAAC,OAAO,CAA8B;IAC7C,OAAO,CAAC,eAAe,CAAkD;IACzE,OAAO,CAAC,aAAa,CAAiB;IACtC,OAAO,CAAC,UAAU,CAAsB;IACxC,OAAO,CAAC,QAAQ,CAAsB;IAEtC,QAAQ,CAAC,oBAAoB,EAAE,oBAAoB,CAAC;IACpD,QAAQ,CAAC,uBAAuB,EAAE,uBAAuB,CAAC;IAC1D,QAAQ,CAAC,uBAAuB,EAAE,uBAAuB,CAAC;IAE1D,QAAQ,CAAC,UAAU,EAAE;QACnB,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,WAAW,CAAC,CAAC;QACrC,cAAc,EAAE,MAAM,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC,WAAW,CAAC,CAAC;QACvD,YAAY,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,WAAW,CAAC,CAAC;KAC3C,CAAC;;IA4BF,kBAAkB,CAAC,IAAI,EAAE,UAAU,EAAE,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,KAAK,IAAI;IAchF,cAAc,CAAC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,KAAK,IAAI;IAkB1D,UAAU;IAQV,KAAK;CAIN"}
|
|
1
|
+
{"version":3,"file":"time_selector_presenter.d.ts","sourceRoot":"","sources":["../../../src/components/time_selector/time_selector_presenter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AACpC,OAAO,EAKL,KAAK,UAAU,EAChB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,uBAAuB,EAAE,MAAM,mDAAmD,CAAC;AAC5F,OAAO,EAAE,uBAAuB,EAAE,MAAM,iDAAiD,CAAC;AAE1F,YAAY,EAAE,UAAU,EAAE,CAAC;AAE3B,eAAO,MAAM,YAAY,EAAE,UAAU,EAYpC,CAAC;AAEF,qBAAa,qBAAqB;IAChC,OAAO,CAAC,OAAO,CAA8B;IAC7C,OAAO,CAAC,eAAe,CAAkD;IACzE,OAAO,CAAC,aAAa,CAAiB;IACtC,OAAO,CAAC,UAAU,CAAsB;IACxC,OAAO,CAAC,QAAQ,CAAsB;IAEtC,QAAQ,CAAC,oBAAoB,EAAE,oBAAoB,CAAC;IACpD,QAAQ,CAAC,uBAAuB,EAAE,uBAAuB,CAAC;IAC1D,QAAQ,CAAC,uBAAuB,EAAE,uBAAuB,CAAC;IAE1D,QAAQ,CAAC,UAAU,EAAE;QACnB,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,WAAW,CAAC,CAAC;QACrC,cAAc,EAAE,MAAM,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC,WAAW,CAAC,CAAC;QACvD,YAAY,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,WAAW,CAAC,CAAC;KAC3C,CAAC;;IA4BF,kBAAkB,CAAC,IAAI,EAAE,UAAU,EAAE,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,KAAK,IAAI;IAchF,cAAc,CAAC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,KAAK,IAAI;IAkB1D,UAAU;IAQV,gBAAgB,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI;IAWvC,KAAK;CAIN"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { Signal as
|
|
2
|
-
import { datesFromPreset as
|
|
1
|
+
import { Signal as i } from "@tcn/state";
|
|
2
|
+
import { datesFromPreset as h, shiftForDisplay as r, unshiftFromDisplay as d, formatDate as l } from "../utils.js";
|
|
3
3
|
import { PresetPanelPresenter as c } from "../preset_panel/preset_panel_presenter.js";
|
|
4
4
|
import { DateRangePanelPresenter as p } from "../date_range_panel/date_range_panel_presenter.js";
|
|
5
5
|
import { TimezoneFooterPresenter as P } from "../timezone_footer/timezone_footer_presenter.js";
|
|
6
|
-
const
|
|
6
|
+
const o = [
|
|
7
7
|
{ label: "Last 5 mins", minutes: 5 },
|
|
8
8
|
{ label: "Last 15 mins", minutes: 15 },
|
|
9
9
|
{ label: "Last 30 mins", minutes: 30 },
|
|
@@ -16,9 +16,9 @@ const l = [
|
|
|
16
16
|
{ label: "Last 7 days", minutes: 10080 },
|
|
17
17
|
{ label: "Last 30 days", minutes: 43200 }
|
|
18
18
|
];
|
|
19
|
-
class
|
|
20
|
-
_isOpen = new
|
|
21
|
-
_selectedPreset = new
|
|
19
|
+
class z {
|
|
20
|
+
_isOpen = new i(!1);
|
|
21
|
+
_selectedPreset = new i(o[0]);
|
|
22
22
|
_displayValue;
|
|
23
23
|
_startDate;
|
|
24
24
|
_endDate;
|
|
@@ -27,40 +27,44 @@ class g {
|
|
|
27
27
|
timezoneFooterPresenter;
|
|
28
28
|
broadcasts;
|
|
29
29
|
constructor() {
|
|
30
|
-
const
|
|
31
|
-
this._startDate = new
|
|
30
|
+
const t = Intl.DateTimeFormat().resolvedOptions().timeZone, { start: s, end: e } = h(o[0]);
|
|
31
|
+
this._startDate = new i(r(s, t)), this._endDate = new i(r(e, t)), this.presetPanelPresenter = new c(o), this.dateRangePanelPresenter = new p(
|
|
32
32
|
this._startDate,
|
|
33
33
|
this._endDate
|
|
34
34
|
), this.timezoneFooterPresenter = new P(
|
|
35
35
|
this._startDate,
|
|
36
36
|
this._endDate
|
|
37
|
-
), this._displayValue = new
|
|
37
|
+
), this._displayValue = new i(o[0].label), this.broadcasts = {
|
|
38
38
|
isOpen: this._isOpen.broadcast,
|
|
39
39
|
selectedPreset: this._selectedPreset.broadcast,
|
|
40
40
|
displayValue: this._displayValue.broadcast
|
|
41
41
|
};
|
|
42
42
|
}
|
|
43
|
-
handlePresetSelect(
|
|
44
|
-
this._selectedPreset.set(
|
|
45
|
-
const { start:
|
|
46
|
-
this._startDate.set(
|
|
43
|
+
handlePresetSelect(t, s) {
|
|
44
|
+
this._selectedPreset.set(t);
|
|
45
|
+
const { start: e, end: a } = h(t), n = this.timezoneFooterPresenter.getTimezone();
|
|
46
|
+
this._startDate.set(r(e, n)), this._endDate.set(r(a, n)), this._displayValue.set(t.label), s?.(e, a), this.close();
|
|
47
47
|
}
|
|
48
|
-
applyTimeRange(
|
|
49
|
-
const s = this._startDate.get(),
|
|
50
|
-
if (s != null &&
|
|
51
|
-
const a = this.timezoneFooterPresenter.getTimezone(),
|
|
52
|
-
this._selectedPreset.set(null), this._displayValue.set(`${
|
|
48
|
+
applyTimeRange(t) {
|
|
49
|
+
const s = this._startDate.get(), e = this._endDate.get();
|
|
50
|
+
if (s != null && e != null) {
|
|
51
|
+
const a = this.timezoneFooterPresenter.getTimezone(), n = d(s, a), m = d(e, a);
|
|
52
|
+
this._selectedPreset.set(null), this._displayValue.set(`${l(s)} to ${l(e)}`), t?.(n, m), this.close();
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
55
|
toggleOpen() {
|
|
56
56
|
this._isOpen.get() ? this.close() : this._isOpen.set(!0);
|
|
57
57
|
}
|
|
58
|
+
setExternalDates(t, s) {
|
|
59
|
+
const e = this.timezoneFooterPresenter.getTimezone(), a = r(t, e), n = r(s, e);
|
|
60
|
+
this._selectedPreset.set(null), this._startDate.set(a), this._endDate.set(n), this._displayValue.set(`${l(a)} to ${l(n)}`);
|
|
61
|
+
}
|
|
58
62
|
close() {
|
|
59
63
|
this._isOpen.set(!1), this.presetPanelPresenter.reset();
|
|
60
64
|
}
|
|
61
65
|
}
|
|
62
66
|
export {
|
|
63
|
-
|
|
64
|
-
|
|
67
|
+
o as PRESET_ITEMS,
|
|
68
|
+
z as TimeSelectorPresenter
|
|
65
69
|
};
|
|
66
70
|
//# sourceMappingURL=time_selector_presenter.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"time_selector_presenter.js","sources":["../../../src/components/time_selector/time_selector_presenter.ts"],"sourcesContent":["import { Signal } from '@tcn/state';\nimport {\n formatDate,\n datesFromPreset,\n shiftForDisplay,\n unshiftFromDisplay,\n type PresetItem,\n} from '../utils.js';\nimport { PresetPanelPresenter } from '../preset_panel/preset_panel_presenter.js';\nimport { DateRangePanelPresenter } from '../date_range_panel/date_range_panel_presenter.js';\nimport { TimezoneFooterPresenter } from '../timezone_footer/timezone_footer_presenter.js';\n\nexport type { PresetItem };\n\nexport const PRESET_ITEMS: PresetItem[] = [\n { label: 'Last 5 mins', minutes: 5 },\n { label: 'Last 15 mins', minutes: 15 },\n { label: 'Last 30 mins', minutes: 30 },\n { label: 'Last 1 hour', minutes: 60 },\n { label: 'Last 3 hours', minutes: 180 },\n { label: 'Last 6 hours', minutes: 360 },\n { label: 'Last 12 hours', minutes: 720 },\n { label: 'Last 24 hours', minutes: 1440 },\n { label: 'Last 2 days', minutes: 2880 },\n { label: 'Last 7 days', minutes: 10080 },\n { label: 'Last 30 days', minutes: 43200 },\n];\n\nexport class TimeSelectorPresenter {\n private _isOpen = new Signal<boolean>(false);\n private _selectedPreset = new Signal<PresetItem | null>(PRESET_ITEMS[0]);\n private _displayValue: Signal<string>;\n private _startDate: Signal<Date | null>;\n private _endDate: Signal<Date | null>;\n\n readonly presetPanelPresenter: PresetPanelPresenter;\n readonly dateRangePanelPresenter: DateRangePanelPresenter;\n readonly timezoneFooterPresenter: TimezoneFooterPresenter;\n\n readonly broadcasts: {\n isOpen: Signal<boolean>['broadcast'];\n selectedPreset: Signal<PresetItem | null>['broadcast'];\n displayValue: Signal<string>['broadcast'];\n };\n\n constructor() {\n const browserTz = Intl.DateTimeFormat().resolvedOptions().timeZone;\n const { start, end } = datesFromPreset(PRESET_ITEMS[0]);\n\n this._startDate = new Signal<Date | null>(shiftForDisplay(start, browserTz));\n this._endDate = new Signal<Date | null>(shiftForDisplay(end, browserTz));\n\n this.presetPanelPresenter = new PresetPanelPresenter(PRESET_ITEMS);\n this.dateRangePanelPresenter = new DateRangePanelPresenter(\n this._startDate,\n this._endDate\n );\n this.timezoneFooterPresenter = new TimezoneFooterPresenter(\n this._startDate,\n this._endDate\n );\n\n this._displayValue = new Signal<string>(PRESET_ITEMS[0].label);\n\n this.broadcasts = {\n isOpen: this._isOpen.broadcast,\n selectedPreset: this._selectedPreset.broadcast,\n displayValue: this._displayValue.broadcast,\n };\n }\n\n handlePresetSelect(item: PresetItem, onChange?: (start: Date, end: Date) => void) {\n this._selectedPreset.set(item);\n\n const { start, end } = datesFromPreset(item);\n const tz = this.timezoneFooterPresenter.getTimezone();\n\n this._startDate.set(shiftForDisplay(start, tz));\n this._endDate.set(shiftForDisplay(end, tz));\n\n this._displayValue.set(item.label);\n onChange?.(start, end);\n this.close();\n }\n\n applyTimeRange(onChange?: (start: Date, end: Date) => void) {\n const displayStart = this._startDate.get();\n const displayEnd = this._endDate.get();\n\n if (displayStart != null && displayEnd != null) {\n const tz = this.timezoneFooterPresenter.getTimezone();\n const realStart = unshiftFromDisplay(displayStart, tz);\n const realEnd = unshiftFromDisplay(displayEnd, tz);\n\n this._selectedPreset.set(null);\n this._displayValue.set(`${formatDate(displayStart)} to ${formatDate(displayEnd)}`);\n\n onChange?.(realStart, realEnd);\n\n this.close();\n }\n }\n\n toggleOpen() {\n if (this._isOpen.get()) {\n this.close();\n } else {\n this._isOpen.set(true);\n }\n }\n\n close() {\n this._isOpen.set(false);\n this.presetPanelPresenter.reset();\n }\n}\n"],"names":["PRESET_ITEMS","TimeSelectorPresenter","Signal","browserTz","start","end","datesFromPreset","shiftForDisplay","PresetPanelPresenter","DateRangePanelPresenter","TimezoneFooterPresenter","item","onChange","tz","displayStart","displayEnd","realStart","unshiftFromDisplay","realEnd","formatDate"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"time_selector_presenter.js","sources":["../../../src/components/time_selector/time_selector_presenter.ts"],"sourcesContent":["import { Signal } from '@tcn/state';\nimport {\n formatDate,\n datesFromPreset,\n shiftForDisplay,\n unshiftFromDisplay,\n type PresetItem,\n} from '../utils.js';\nimport { PresetPanelPresenter } from '../preset_panel/preset_panel_presenter.js';\nimport { DateRangePanelPresenter } from '../date_range_panel/date_range_panel_presenter.js';\nimport { TimezoneFooterPresenter } from '../timezone_footer/timezone_footer_presenter.js';\n\nexport type { PresetItem };\n\nexport const PRESET_ITEMS: PresetItem[] = [\n { label: 'Last 5 mins', minutes: 5 },\n { label: 'Last 15 mins', minutes: 15 },\n { label: 'Last 30 mins', minutes: 30 },\n { label: 'Last 1 hour', minutes: 60 },\n { label: 'Last 3 hours', minutes: 180 },\n { label: 'Last 6 hours', minutes: 360 },\n { label: 'Last 12 hours', minutes: 720 },\n { label: 'Last 24 hours', minutes: 1440 },\n { label: 'Last 2 days', minutes: 2880 },\n { label: 'Last 7 days', minutes: 10080 },\n { label: 'Last 30 days', minutes: 43200 },\n];\n\nexport class TimeSelectorPresenter {\n private _isOpen = new Signal<boolean>(false);\n private _selectedPreset = new Signal<PresetItem | null>(PRESET_ITEMS[0]);\n private _displayValue: Signal<string>;\n private _startDate: Signal<Date | null>;\n private _endDate: Signal<Date | null>;\n\n readonly presetPanelPresenter: PresetPanelPresenter;\n readonly dateRangePanelPresenter: DateRangePanelPresenter;\n readonly timezoneFooterPresenter: TimezoneFooterPresenter;\n\n readonly broadcasts: {\n isOpen: Signal<boolean>['broadcast'];\n selectedPreset: Signal<PresetItem | null>['broadcast'];\n displayValue: Signal<string>['broadcast'];\n };\n\n constructor() {\n const browserTz = Intl.DateTimeFormat().resolvedOptions().timeZone;\n const { start, end } = datesFromPreset(PRESET_ITEMS[0]);\n\n this._startDate = new Signal<Date | null>(shiftForDisplay(start, browserTz));\n this._endDate = new Signal<Date | null>(shiftForDisplay(end, browserTz));\n\n this.presetPanelPresenter = new PresetPanelPresenter(PRESET_ITEMS);\n this.dateRangePanelPresenter = new DateRangePanelPresenter(\n this._startDate,\n this._endDate\n );\n this.timezoneFooterPresenter = new TimezoneFooterPresenter(\n this._startDate,\n this._endDate\n );\n\n this._displayValue = new Signal<string>(PRESET_ITEMS[0].label);\n\n this.broadcasts = {\n isOpen: this._isOpen.broadcast,\n selectedPreset: this._selectedPreset.broadcast,\n displayValue: this._displayValue.broadcast,\n };\n }\n\n handlePresetSelect(item: PresetItem, onChange?: (start: Date, end: Date) => void) {\n this._selectedPreset.set(item);\n\n const { start, end } = datesFromPreset(item);\n const tz = this.timezoneFooterPresenter.getTimezone();\n\n this._startDate.set(shiftForDisplay(start, tz));\n this._endDate.set(shiftForDisplay(end, tz));\n\n this._displayValue.set(item.label);\n onChange?.(start, end);\n this.close();\n }\n\n applyTimeRange(onChange?: (start: Date, end: Date) => void) {\n const displayStart = this._startDate.get();\n const displayEnd = this._endDate.get();\n\n if (displayStart != null && displayEnd != null) {\n const tz = this.timezoneFooterPresenter.getTimezone();\n const realStart = unshiftFromDisplay(displayStart, tz);\n const realEnd = unshiftFromDisplay(displayEnd, tz);\n\n this._selectedPreset.set(null);\n this._displayValue.set(`${formatDate(displayStart)} to ${formatDate(displayEnd)}`);\n\n onChange?.(realStart, realEnd);\n\n this.close();\n }\n }\n\n toggleOpen() {\n if (this._isOpen.get()) {\n this.close();\n } else {\n this._isOpen.set(true);\n }\n }\n\n setExternalDates(start: Date, end: Date) {\n const tz = this.timezoneFooterPresenter.getTimezone();\n const displayStart = shiftForDisplay(start, tz);\n const displayEnd = shiftForDisplay(end, tz);\n\n this._selectedPreset.set(null);\n this._startDate.set(displayStart);\n this._endDate.set(displayEnd);\n this._displayValue.set(`${formatDate(displayStart)} to ${formatDate(displayEnd)}`);\n }\n\n close() {\n this._isOpen.set(false);\n this.presetPanelPresenter.reset();\n }\n}\n"],"names":["PRESET_ITEMS","TimeSelectorPresenter","Signal","browserTz","start","end","datesFromPreset","shiftForDisplay","PresetPanelPresenter","DateRangePanelPresenter","TimezoneFooterPresenter","item","onChange","tz","displayStart","displayEnd","realStart","unshiftFromDisplay","realEnd","formatDate"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tcn/ui-time-selector",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "React time selector component",
|
|
6
6
|
"author": "TCN",
|
|
@@ -37,8 +37,8 @@
|
|
|
37
37
|
"**/*.css"
|
|
38
38
|
],
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@tcn/
|
|
41
|
-
"@tcn/
|
|
40
|
+
"@tcn/icons": "2.4.0",
|
|
41
|
+
"@tcn/state": "1.3.4"
|
|
42
42
|
},
|
|
43
43
|
"peerDependencies": {
|
|
44
44
|
"react": "^18.2.0",
|
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
import type { Meta } from '@storybook/react-vite';
|
|
2
2
|
import { useState } from 'react';
|
|
3
3
|
import { TimeSelector } from '../components/time_selector/time_selector.js';
|
|
4
|
+
import { Button } from '@tcn/ui/actions';
|
|
5
|
+
|
|
6
|
+
function makeRange(hoursAgo: number): { start: Date; end: Date } {
|
|
7
|
+
const end = new Date();
|
|
8
|
+
const start = new Date(end.getTime() - hoursAgo * 60 * 60 * 1000);
|
|
9
|
+
return { start, end };
|
|
10
|
+
}
|
|
4
11
|
|
|
5
12
|
const meta: Meta<typeof TimeSelector> = {
|
|
6
13
|
title: 'TimeSelector',
|
|
@@ -57,6 +64,72 @@ export function WithTwoWeekStartLimit() {
|
|
|
57
64
|
);
|
|
58
65
|
}
|
|
59
66
|
|
|
67
|
+
export function WithControlledDates() {
|
|
68
|
+
const [startDate, setStartDate] = useState<Date | null>(null);
|
|
69
|
+
const [endDate, setEndDate] = useState<Date | null>(null);
|
|
70
|
+
const [reported, setReported] = useState<{ start: Date; end: Date } | null>(null);
|
|
71
|
+
|
|
72
|
+
function applyRange(hoursAgo: number) {
|
|
73
|
+
const { start, end } = makeRange(hoursAgo);
|
|
74
|
+
setStartDate(start);
|
|
75
|
+
setEndDate(end);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return (
|
|
79
|
+
<div
|
|
80
|
+
style={{ position: 'relative', minHeight: '100vh', padding: '16px', width: '100%' }}
|
|
81
|
+
>
|
|
82
|
+
<div style={{ display: 'flex', justifyContent: 'center' }}>
|
|
83
|
+
<TimeSelector
|
|
84
|
+
startDate={startDate}
|
|
85
|
+
endDate={endDate}
|
|
86
|
+
onChange={(s, e) => setReported({ start: s, end: e })}
|
|
87
|
+
/>
|
|
88
|
+
</div>
|
|
89
|
+
<div
|
|
90
|
+
style={{
|
|
91
|
+
display: 'flex',
|
|
92
|
+
gap: '8px',
|
|
93
|
+
marginTop: '12px',
|
|
94
|
+
justifyContent: 'center',
|
|
95
|
+
}}
|
|
96
|
+
>
|
|
97
|
+
<Button onClick={() => applyRange(1)}>Set last 1h (UTC)</Button>
|
|
98
|
+
<Button onClick={() => applyRange(6)}>Set last 6h (UTC)</Button>
|
|
99
|
+
<Button onClick={() => applyRange(24)}>Set last 24h (UTC)</Button>
|
|
100
|
+
<Button
|
|
101
|
+
onClick={() => {
|
|
102
|
+
setStartDate(null);
|
|
103
|
+
setEndDate(null);
|
|
104
|
+
}}
|
|
105
|
+
>
|
|
106
|
+
Clear
|
|
107
|
+
</Button>
|
|
108
|
+
</div>
|
|
109
|
+
<div
|
|
110
|
+
style={{
|
|
111
|
+
fontSize: '13px',
|
|
112
|
+
lineHeight: '1.6',
|
|
113
|
+
marginTop: '12px',
|
|
114
|
+
}}
|
|
115
|
+
>
|
|
116
|
+
<div>
|
|
117
|
+
<strong>Passed startDate:</strong> {startDate?.toISOString() ?? '—'}
|
|
118
|
+
</div>
|
|
119
|
+
<div>
|
|
120
|
+
<strong>Passed endDate:</strong> {endDate?.toISOString() ?? '—'}
|
|
121
|
+
</div>
|
|
122
|
+
<div>
|
|
123
|
+
<strong>onChange start:</strong> {reported?.start.toISOString() ?? '—'}
|
|
124
|
+
</div>
|
|
125
|
+
<div>
|
|
126
|
+
<strong>onChange end:</strong> {reported?.end.toISOString() ?? '—'}
|
|
127
|
+
</div>
|
|
128
|
+
</div>
|
|
129
|
+
</div>
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
|
|
60
133
|
export function Basic() {
|
|
61
134
|
const [start, setStart] = useState<Date | null>(null);
|
|
62
135
|
const [end, setEnd] = useState<Date | null>(null);
|
|
@@ -4,7 +4,7 @@ import { HStack, VStack } from '@tcn/ui/stacks';
|
|
|
4
4
|
import { BodyText } from '@tcn/ui/typography';
|
|
5
5
|
import { ChevronDownIcon } from '@tcn/icons/chevron_down_icon.js';
|
|
6
6
|
import { ChevronUpIcon } from '@tcn/icons/chevron_up_icon.js';
|
|
7
|
-
import { useRef, useState } from 'react';
|
|
7
|
+
import { useEffect, useRef, useState } from 'react';
|
|
8
8
|
import { TimeSelectorPresenter } from './time_selector_presenter.js';
|
|
9
9
|
import { PresetPanel } from '../preset_panel/preset_panel.js';
|
|
10
10
|
import { DateRangePanel } from '../date_range_panel/date_range_panel.js';
|
|
@@ -14,6 +14,8 @@ import styles from './time_selector.module.css';
|
|
|
14
14
|
export interface TimeSelectorOwnProps {
|
|
15
15
|
onChange?: (start: Date, end: Date) => void;
|
|
16
16
|
onTimezoneChange?: (timezone: string) => void;
|
|
17
|
+
startDate?: Date | null;
|
|
18
|
+
endDate?: Date | null;
|
|
17
19
|
startDateMin?: Date | null;
|
|
18
20
|
startDateMax?: Date | null;
|
|
19
21
|
endDateMin?: Date | null;
|
|
@@ -26,6 +28,8 @@ export type TimeSelectorProps = TimeSelectorOwnProps;
|
|
|
26
28
|
export function TimeSelector({
|
|
27
29
|
onChange,
|
|
28
30
|
onTimezoneChange,
|
|
31
|
+
startDate,
|
|
32
|
+
endDate,
|
|
29
33
|
startDateMin,
|
|
30
34
|
startDateMax,
|
|
31
35
|
endDateMin,
|
|
@@ -35,6 +39,12 @@ export function TimeSelector({
|
|
|
35
39
|
const [presenter] = useState(() => new TimeSelectorPresenter());
|
|
36
40
|
const anchorRef = useRef<HTMLDivElement>(null);
|
|
37
41
|
|
|
42
|
+
useEffect(() => {
|
|
43
|
+
if (startDate != null && endDate != null) {
|
|
44
|
+
presenter.setExternalDates(startDate, endDate);
|
|
45
|
+
}
|
|
46
|
+
}, [startDate, endDate, presenter]);
|
|
47
|
+
|
|
38
48
|
const isOpen = useSignalValue(presenter.broadcasts.isOpen);
|
|
39
49
|
const selectedPreset = useSignalValue(presenter.broadcasts.selectedPreset);
|
|
40
50
|
const displayValue = useSignalValue(presenter.broadcasts.displayValue);
|
|
@@ -109,6 +109,17 @@ export class TimeSelectorPresenter {
|
|
|
109
109
|
}
|
|
110
110
|
}
|
|
111
111
|
|
|
112
|
+
setExternalDates(start: Date, end: Date) {
|
|
113
|
+
const tz = this.timezoneFooterPresenter.getTimezone();
|
|
114
|
+
const displayStart = shiftForDisplay(start, tz);
|
|
115
|
+
const displayEnd = shiftForDisplay(end, tz);
|
|
116
|
+
|
|
117
|
+
this._selectedPreset.set(null);
|
|
118
|
+
this._startDate.set(displayStart);
|
|
119
|
+
this._endDate.set(displayEnd);
|
|
120
|
+
this._displayValue.set(`${formatDate(displayStart)} to ${formatDate(displayEnd)}`);
|
|
121
|
+
}
|
|
122
|
+
|
|
112
123
|
close() {
|
|
113
124
|
this._isOpen.set(false);
|
|
114
125
|
this.presetPanelPresenter.reset();
|