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
- /** "Reactive" reference timestamp to use for the time picker's date. Precedence order: `referenceTimestamp`, `value`, or today */
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 date = new TZDate(value, tz)
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
- // Update the value when the changedValue changes
43
+ // Carry over the date from the referenceTimestamp, if provided
56
44
  useEffect(() => {
57
- if (internallyChanged && isValid(internallyChanged)) {
58
- onChange?.(internallyChanged)
59
- setInternallyChanged(undefined)
60
- }
61
- }, [internallyChanged])
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
- const value = props?.value ?? props?.defaultValue
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}`, 'hh:mm:ss', tz, referenceTimestamp)
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 value={internalValue?.[0]} onChange={onChange<Timestamp>}
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} tz={tz}
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.159",
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 🚀",