nitro-web 0.0.159 → 0.0.160
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.
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { useRef, useMemo, useEffect } from 'react'
|
|
2
2
|
import { isValid, format } from 'date-fns'
|
|
3
3
|
import { TZDate } from '@date-fns/tz'
|
|
4
|
-
import { twMerge } from 'nitro-web'
|
|
4
|
+
import { twMerge, date } from 'nitro-web'
|
|
5
5
|
import { dayButtonClassName } from '../element/calendar'
|
|
6
6
|
|
|
7
7
|
type Timestamp = null | number
|
|
@@ -10,12 +10,14 @@ export type TimePickerProps = {
|
|
|
10
10
|
onChange?: (value: Timestamp) => void
|
|
11
11
|
tz?: string
|
|
12
12
|
value?: Timestamp
|
|
13
|
-
|
|
13
|
+
// eslint-disable-next-line max-len
|
|
14
|
+
/** "Reactive" reference timestamp to copy the date from. Precedence order: `referenceTimestamp`, `value`, or today. Warning: This value needs to be updated after, or at the same time as `value`, otherwise the useffect will use the previous `value` */
|
|
14
15
|
referenceTimestamp?: Timestamp
|
|
16
|
+
/** Data for testing */
|
|
17
|
+
// _data?: { name: unknown }
|
|
15
18
|
}
|
|
16
19
|
|
|
17
20
|
export function TimePicker({ value, onChange, className, tz, referenceTimestamp }: TimePickerProps) {
|
|
18
|
-
const [internallyChanged, setInternallyChanged] = useState<Timestamp>()
|
|
19
21
|
const refs = {
|
|
20
22
|
hour: useRef<HTMLDivElement>(null),
|
|
21
23
|
minute: useRef<HTMLDivElement>(null),
|
|
@@ -34,31 +36,33 @@ export function TimePicker({ value, onChange, className, tz, referenceTimestamp
|
|
|
34
36
|
// Convert the value to an valid* date
|
|
35
37
|
const internalValue = useMemo(() => {
|
|
36
38
|
if (!value || !isValid(value)) return undefined
|
|
37
|
-
const
|
|
38
|
-
|
|
39
|
-
// Carry over the date from the referenceTimestamp, if provided
|
|
40
|
-
if (referenceTimestamp && isValid(referenceTimestamp)) {
|
|
41
|
-
const referenceDate = new TZDate(referenceTimestamp, tz)
|
|
42
|
-
const originalTime = date.getTime()
|
|
43
|
-
date.setDate(referenceDate.getDate())
|
|
44
|
-
date.setMonth(referenceDate.getMonth())
|
|
45
|
-
date.setFullYear(referenceDate.getFullYear())
|
|
46
|
-
// If the time has changed, update the value
|
|
47
|
-
if (originalTime !== date.getTime()) {
|
|
48
|
-
setInternallyChanged(date.getTime())
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
return date
|
|
39
|
+
const tzdate = new TZDate(value, tz)
|
|
40
|
+
return tzdate
|
|
53
41
|
}, [value, tz, referenceTimestamp])
|
|
54
42
|
|
|
55
|
-
//
|
|
43
|
+
// Carry over the date from the referenceTimestamp, if provided
|
|
56
44
|
useEffect(() => {
|
|
57
|
-
if (
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
45
|
+
if (!referenceTimestamp || !isValid(referenceTimestamp) || !internalValue) return
|
|
46
|
+
const referenceDate = new TZDate(referenceTimestamp, tz)
|
|
47
|
+
const newInternalValue = new TZDate(internalValue.getTime(), tz)
|
|
48
|
+
const [day, month, year] = [newInternalValue.getDate(), newInternalValue.getMonth(), newInternalValue.getFullYear()]
|
|
49
|
+
const [refDay, refMonth, refYear] = [referenceDate.getDate(), referenceDate.getMonth(), referenceDate.getFullYear()]
|
|
50
|
+
// const old = date(newInternalValue.getTime(), 'dd hh:mm aa', 'Pacific/Auckland')
|
|
51
|
+
|
|
52
|
+
if (day === refDay && month === refMonth && year === refYear) return
|
|
53
|
+
newInternalValue.setDate(refDay)
|
|
54
|
+
newInternalValue.setMonth(refMonth)
|
|
55
|
+
newInternalValue.setFullYear(refYear)
|
|
56
|
+
|
|
57
|
+
// if (_data && _data?.name === 'endTime') {
|
|
58
|
+
// console.log({
|
|
59
|
+
// old: old,
|
|
60
|
+
// new: date(newInternalValue.getTime(), 'dd hh:mm aa', 'Pacific/Auckland'),
|
|
61
|
+
// })
|
|
62
|
+
// }
|
|
63
|
+
|
|
64
|
+
onChange?.(newInternalValue?.getTime())
|
|
65
|
+
}, [referenceTimestamp])
|
|
62
66
|
|
|
63
67
|
// Get current values from date or use defaults
|
|
64
68
|
const hour = useMemo(() => internalValue ? parseInt(format(internalValue, 'h')) : undefined, [internalValue])
|
|
@@ -108,8 +108,7 @@ export function FieldDate({
|
|
|
108
108
|
switch (props.mode) {
|
|
109
109
|
case 'single':
|
|
110
110
|
case 'time': {
|
|
111
|
-
|
|
112
|
-
return [value && isValid(value) ? new Date(value).getTime() : null]
|
|
111
|
+
return [getStringValue(props.value, props.defaultValue)]
|
|
113
112
|
}
|
|
114
113
|
case 'multiple':
|
|
115
114
|
case 'range': {
|
|
@@ -127,6 +126,11 @@ export function FieldDate({
|
|
|
127
126
|
}
|
|
128
127
|
}
|
|
129
128
|
|
|
129
|
+
function getStringValue(value?: Timestamp, defaultValue?: Timestamp) {
|
|
130
|
+
const value2 = value ?? defaultValue
|
|
131
|
+
return value2 && isValid(value2) ? new Date(value2).getTime() : null
|
|
132
|
+
}
|
|
133
|
+
|
|
130
134
|
function getInputValue(value: Timestamp[]) {
|
|
131
135
|
return value.map(o => date(o, pattern, tz)).join(props.mode == 'range' ? ' - ' : ', ')
|
|
132
136
|
}
|
|
@@ -173,7 +177,7 @@ export function FieldDate({
|
|
|
173
177
|
function onNowClick() {
|
|
174
178
|
// Use the browser's local time and parse it into the timezone
|
|
175
179
|
const [hours, minutes, seconds] = [new Date().getHours(), new Date().getMinutes(), new Date().getSeconds()]
|
|
176
|
-
const nowInTz = parseDateString(`${hours}:${minutes}:${seconds}`, '
|
|
180
|
+
const nowInTz = parseDateString(`${hours}:${minutes}:${seconds}`, 'HH:mm:ss', tz)
|
|
177
181
|
onChange(nowInTz)
|
|
178
182
|
}
|
|
179
183
|
|
|
@@ -203,9 +207,15 @@ export function FieldDate({
|
|
|
203
207
|
}
|
|
204
208
|
{
|
|
205
209
|
(props.mode == 'time' || (!!showTime && props.mode == 'single')) &&
|
|
206
|
-
<TimePicker
|
|
210
|
+
<TimePicker
|
|
211
|
+
// The `value` needs to be updated before or at the same time as `referenceTimestamp`, otherwise the
|
|
212
|
+
// useffect in the timepicker will use the previous `value`
|
|
213
|
+
value={getStringValue(props.value, props.defaultValue)}
|
|
214
|
+
onChange={onChange<Timestamp>}
|
|
207
215
|
className={`border-l border-gray-100 ${props.mode == 'single' ? 'min-h-[0]' : ''}`}
|
|
208
|
-
referenceTimestamp={referenceTimestamp}
|
|
216
|
+
referenceTimestamp={referenceTimestamp}
|
|
217
|
+
tz={tz}
|
|
218
|
+
// _data={{ name: props.name }}
|
|
209
219
|
/>
|
|
210
220
|
}
|
|
211
221
|
</div>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nitro-web",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.160",
|
|
4
4
|
"repository": "github:boycce/nitro-web",
|
|
5
5
|
"homepage": "https://boycce.github.io/nitro-web/",
|
|
6
6
|
"description": "Nitro is a battle-tested, modular base project to turbocharge your projects, styled using Tailwind 🚀",
|