🚀 Socket Launch Week Day 5:Introducing Repository Access Permissions and Custom Roles.Learn more
Sign In

temporal-react-hook

Package Overview
Dependencies
Maintainers
1
Versions
39
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

temporal-react-hook - npm Package Compare versions

Comparing version
1.6.12
to
1.6.13
+30
-9
CHANGELOG.md

@@ -10,7 +10,20 @@ # Changelog

## [1.6.11] - 2025-06-03
## [1.6.13] - 2025-06-09
### Added
- `useIsSame` hook now accepts an optional `timeZone` parameter for time zone-aware comparisons.
- `DemoUseIsSame` component updated to include a time zone selector in the UI.
- `DemoUseIsThisWeek` component updated for UI consistency (removed date buttons, added datetime-local input) and integrated time zone selector.
- Enhanced error handling in `useTemporalAdd` hook
- Comprehensive validation for date and duration inputs
- Clear error messages with examples and valid options
- Type checking for duration values
### Changed
- Updated `DemoUseTemporalAdd` component
- Added inputs for all duration units (years, months, days, hours, minutes, seconds)
- Improved documentation with examples of combining multiple duration units
- Enhanced UI layout and styling for better user experience
## [1.6.12] - 2025-06-04
### Added
- Dynamic formatting support in `useTemporalFormat` hook

@@ -20,9 +33,17 @@ - Format dates based on temporal distance (recent, today, this week, etc.)

- Maintains backward compatibility with existing preset formats
- UI consistency and styling improvements to `DemoUseTemporalFormat`
- Updated layout classes for consistent styling
- Replaced locale selection buttons with dropdown
- Added dynamic formatting mode with example
- Improved code block formatting
### Fixed
- Fixed date conversion issues between Temporal and JavaScript Date objects
- Improved handling of PlainDate objects in useTemporalFormat
### Changed
- Removed direct Temporal API usage from demo components
- Updated documentation with dynamic formatting examples
## [1.6.11] - 2025-06-03
### Added
- `useIsSame` hook now accepts an optional `timeZone` parameter for time zone-aware comparisons.
- `DemoUseIsSame` component updated to include a time zone selector in the UI.
- `DemoUseIsThisWeek` component updated for UI consistency (removed date buttons, added datetime-local input) and integrated time zone selector.
### Changed
- Removed direct `@js-temporal/polyfill` imports from `DemoUseIsSame` and `DemoUseIsThisWeek` demo components for cleaner code.

@@ -29,0 +50,0 @@ - `DemoUseTemporalFormat` component updated for UI consistency (layout classes, locale dropdown) and improved user experience.

@@ -8,3 +8,3 @@ import { useState } from "react";

const [baseDate, setBaseDate] = useState(currentDateTime);
const [amount, setAmount] = useState({ days: 1 });
const [amount, setAmount] = useState({ years: 0, months: 0, days: 1, hours: 0, minutes: 0, seconds: 0 });
const add = useTemporalAdd();

@@ -16,19 +16,87 @@ const result = add(baseDate, amount);

<h3>useTemporalAdd</h3>
<div className="demo-row">
<b>Base Date:</b> <span className="demo-value">{baseDate.toString()}</span>
<button className="demo-select-btn" onClick={() => setBaseDate(currentDateTime)}>Now</button>
<div className="demo-config-panel">
<div className="demo-config-row">
<b>Base Date:</b>
<span className="demo-value">{baseDate.toString()}</span>
<button onClick={() => setBaseDate(currentDateTime)}>Now</button>
<button onClick={() => setBaseDate(baseDate.add({ days: 1 }))}>+1 day</button>
<button onClick={() => setBaseDate(baseDate.subtract({ days: 1 }))}>-1 day</button>
</div>
</div>
<div className="demo-row">
<b>Days to Add:</b>
<input
type="number"
min={0}
value={amount.days}
onChange={e => setAmount({ days: Math.max(0, Number(e.target.value)) })}
className="demo-input-compact"
/>
<div className="demo-config-panel">
<div className="demo-config-row">
<b>Duration:</b>
<div style={{ display: 'flex', gap: '1rem', flexWrap: 'wrap' }}>
<label style={{ display: 'flex', alignItems: 'center', gap: '0.5rem' }}>
<span>Years:</span>
<input
type="number"
min={0}
value={amount.years}
onChange={e => setAmount({ ...amount, years: Math.max(0, Number(e.target.value)) })}
className="demo-input-compact"
/>
</label>
<label style={{ display: 'flex', alignItems: 'center', gap: '0.5rem' }}>
<span>Months:</span>
<input
type="number"
min={0}
value={amount.months}
onChange={e => setAmount({ ...amount, months: Math.max(0, Number(e.target.value)) })}
className="demo-input-compact"
/>
</label>
<label style={{ display: 'flex', alignItems: 'center', gap: '0.5rem' }}>
<span>Days:</span>
<input
type="number"
min={0}
value={amount.days}
onChange={e => setAmount({ ...amount, days: Math.max(0, Number(e.target.value)) })}
className="demo-input-compact"
/>
</label>
<label style={{ display: 'flex', alignItems: 'center', gap: '0.5rem' }}>
<span>Hours:</span>
<input
type="number"
min={0}
value={amount.hours}
onChange={e => setAmount({ ...amount, hours: Math.max(0, Number(e.target.value)) })}
className="demo-input-compact"
/>
</label>
<label style={{ display: 'flex', alignItems: 'center', gap: '0.5rem' }}>
<span>Minutes:</span>
<input
type="number"
min={0}
value={amount.minutes}
onChange={e => setAmount({ ...amount, minutes: Math.max(0, Number(e.target.value)) })}
className="demo-input-compact"
/>
</label>
<label style={{ display: 'flex', alignItems: 'center', gap: '0.5rem' }}>
<span>Seconds:</span>
<input
type="number"
min={0}
value={amount.seconds}
onChange={e => setAmount({ ...amount, seconds: Math.max(0, Number(e.target.value)) })}
className="demo-input-compact"
/>
</label>
</div>
</div>
</div>
<div className="demo-row">
<b>Result:</b> <span className="demo-value">{result.toString()}</span>
<div className="demo-config-panel">
<div className="demo-config-row">
<b>Result:</b>
<span className="demo-value">{result.toString()}</span>
</div>
</div>
<div className="demo-info-card">

@@ -41,3 +109,3 @@ <div className="demo-description">

<span>
<strong>Syntax:</strong> useTemporalAdd()<br/>
<strong>Syntax:</strong> useTemporalAdd(date, amount)<br/>
<strong>Parameters:</strong><br/>

@@ -47,10 +115,19 @@ - date: Temporal.PlainDateTime — The base date/time<br/>

<strong>Returns:</strong> Temporal.PlainDateTime — The new date/time after addition<br/>
<strong>Example:</strong><br/>
<code>
import &#123; useTemporalAdd, useTemporalDateTime &#125; from 'temporal-react-hook';<br/>
<br/>
const add = useTemporalAdd();<br/>
const now = useTemporalDateTime();<br/>
const tomorrow = add(now, &#123; days: 1 &#125;);<br/>
// tomorrow is now plus one day<br/>
<strong>Example:</strong>
<code className="example-code">
<pre style={{ margin: 0 }}>{`import { useTemporalAdd, useTemporalDateTime } from 'temporal-react-hook';
const add = useTemporalAdd();
const now = useTemporalDateTime();
// Add multiple duration units at once
const futureDate = add(now, {
years: 1, // Add 1 year
months: 6, // and 6 months
days: 15, // and 15 days
hours: 3, // and 3 hours
minutes: 30 // and 30 minutes
});
// Or just add days
const tomorrow = add(now, { days: 1 });`}</pre>
</code>

@@ -57,0 +134,0 @@ </span>

@@ -1,2 +0,2 @@

import { useState } from 'react';
import { useState } from "react";
import useTemporalFormat from '../../src/useTemporalFormat';

@@ -3,0 +3,0 @@ import useTemporalDateTime from '../../src/useTemporalDateTime';

{
"name": "temporal-react-hook",
"version": "1.6.12",
"version": "1.6.13",
"description": "A React library that provides hooks for handling date and time operations using the Temporal API",

@@ -5,0 +5,0 @@ "main": "index.js",

@@ -7,8 +7,58 @@ import { useCallback } from "react";

* Returns a function to add a specified amount of seconds, minutes, hours, days, weeks, months, or years to a Temporal.PlainDateTime.
* Example: const add = useTemporalAdd(); add(date, { days: 1, hours: 2 })
*
* @example
* ```typescript
* const add = useTemporalAdd();
*
* // Add multiple duration units
* const futureDate = add(now, {
* years: 1, // Add 1 year
* months: 6, // and 6 months
* days: 15, // and 15 days
* hours: 3 // and 3 hours
* });
* ```
*/
export default function useTemporalAdd() {
return useCallback((date: Temporal.PlainDateTime, amount: Partial<Temporal.DurationLike>) => {
return date.add(amount);
// Validate date input
if (!date) {
throw new Error('Date is required. Please provide a valid Temporal.PlainDateTime object.');
}
if (!(date instanceof Temporal.PlainDateTime)) {
throw new Error('Invalid date type. Expected Temporal.PlainDateTime but received: ' +
((date as any)?.constructor?.name || typeof date));
}
// Validate amount input
if (!amount || typeof amount !== 'object') {
throw new Error('Duration amount is required. Please provide an object with duration values ' +
'(e.g., { days: 1, hours: 2 })');
}
// Validate duration values
const validKeys = ['years', 'months', 'weeks', 'days', 'hours', 'minutes', 'seconds', 'milliseconds', 'microseconds', 'nanoseconds'];
const invalidKeys = Object.keys(amount).filter(key => !validKeys.includes(key));
if (invalidKeys.length > 0) {
throw new Error(`Invalid duration units found: ${invalidKeys.join(', ')}. ` +
`Valid units are: ${validKeys.join(', ')}`);
}
// Validate duration values are numbers
for (const [key, value] of Object.entries(amount)) {
if (typeof value !== 'number') {
throw new Error(`Invalid value for ${key}: ${value}. Duration values must be numbers.`);
}
}
try {
return date.add(amount);
} catch (error) {
const err = error as Error;
throw new Error(`Failed to add duration: ${err.message}. ` +
'Please check that your duration values are within valid ranges.');
}
}, []);
}