@clicktap/ui 0.32.0 → 0.33.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.
@@ -0,0 +1,13 @@
1
+ import { TimeProps } from './Time.types';
2
+ /**
3
+ * Renders an instant as a localized, timezone-aware `<time>` element.
4
+ *
5
+ * The displayed string is formatted in the **server** timezone from `TimezoneProvider` by
6
+ * default; pass `local` to render it in the viewer's timezone instead. Because the resolved
7
+ * timezone comes from context (identical on server and client) and `Intl.DateTimeFormat` is
8
+ * deterministic, server and first client render produce the same string — no hydration
9
+ * mismatch. The machine-readable `dateTime` attribute always carries the unambiguous UTC
10
+ * instant regardless of the displayed zone.
11
+ */
12
+ export declare function Time({ locale, fallback, children, local, showZone, timeZone: timeZoneOverride, timeZoneName, ...options }: TimeProps): import("react/jsx-runtime").JSX.Element;
13
+ export default Time;
@@ -0,0 +1 @@
1
+ "use client";import{jsx as o,Fragment as m}from"react/jsx-runtime";import{useTimezone as v}from"../Timezone/TimezoneContext.js";import"react";function w({locale:r="en-US",fallback:n="-",children:e,local:a=!1,showZone:s=!1,timeZone:f,timeZoneName:u,...d}){const{timezone:i,viewerTimezone:l}=v();if(e==null)return o(m,{children:n});const t=new Date(e);if(Number.isNaN(t.valueOf()))return o(m,{children:n});const c=f??(a?l??i:i),T=new Intl.DateTimeFormat(r,{...d,timeZone:c,timeZoneName:u??(s?"short":void 0)}).format(t);return o("time",{dateTime:t.toISOString(),children:T})}export{w as Time,w as default};
@@ -0,0 +1,21 @@
1
+ import { ReactNode } from 'react';
2
+ export type TimeProps = Intl.DateTimeFormatOptions & {
3
+ /** BCP 47 locale used for formatting. Defaults to `en-US`. */
4
+ locale?: string;
5
+ /** Rendered when `children` is missing or not a valid date. Defaults to `-`. */
6
+ fallback?: ReactNode;
7
+ /** The instant to render — ISO string, `Date`, or epoch milliseconds. */
8
+ children?: string | Date | number;
9
+ /**
10
+ * Opt this output into the viewer's local ("client") timezone instead of the configured
11
+ * default ("server") timezone. Falls back to the server timezone when the viewer's zone is
12
+ * not yet known (no cookie), so first-render output stays hydration-safe. Defaults to
13
+ * `false` (server time).
14
+ */
15
+ local?: boolean;
16
+ /**
17
+ * Append the timezone abbreviation (e.g. "EST") to the output. Shorthand for
18
+ * `timeZoneName: 'short'`; an explicit `timeZoneName` always wins.
19
+ */
20
+ showZone?: boolean;
21
+ };
@@ -0,0 +1,2 @@
1
+ export { Time } from './Time';
2
+ export type { TimeProps } from './Time.types';
@@ -0,0 +1 @@
1
+ import{Time as t}from"./Time.js";import"react/jsx-runtime";import"../Timezone/TimezoneContext.js";import"react";export{t as Time};
@@ -0,0 +1,25 @@
1
+ import { ReactNode } from 'react';
2
+ export type TimezoneConfig = {
3
+ /**
4
+ * The configured default ("server") timezone — an IANA identifier resolved on the server
5
+ * (the `display/default_timezone` setting, or the PHP default when unset) and passed down
6
+ * so server and client render identical date/time output. This is the default zone every
7
+ * `<Time>` renders in.
8
+ */
9
+ timezone: string;
10
+ /**
11
+ * The viewer's ("client") timezone, when known — typically derived server-side from a
12
+ * cookie set by `TimezoneCookieSync`. Only used by outputs that opt in via the `local`
13
+ * prop. Undefined until the cookie is present (first visit), in which case `local` outputs
14
+ * fall back to `timezone`, keeping rendering hydration-safe.
15
+ */
16
+ viewerTimezone?: string;
17
+ };
18
+ type TimezoneProviderProps = {
19
+ children: ReactNode;
20
+ timezone: string;
21
+ viewerTimezone?: string;
22
+ };
23
+ export declare function TimezoneProvider({ children, timezone, viewerTimezone, }: TimezoneProviderProps): import("react/jsx-runtime").JSX.Element;
24
+ export declare function useTimezone(): TimezoneConfig;
25
+ export {};
@@ -0,0 +1 @@
1
+ "use client";import{jsx as r}from"react/jsx-runtime";import{createContext as i,useContext as m}from"react";const e=i({timezone:"UTC"});function s({children:o,timezone:t,viewerTimezone:n}){return r(e.Provider,{value:{timezone:t,viewerTimezone:n},children:o})}function x(){return m(e)}export{s as TimezoneProvider,x as useTimezone};
@@ -0,0 +1,17 @@
1
+ /** Cookie name carrying the viewer's IANA timezone for server-side `local`-mode rendering. */
2
+ export declare const TIMEZONE_COOKIE_NAME = "displayTimezone";
3
+ type TimezoneCookieSyncProps = {
4
+ /** Cookie lifetime in seconds. Defaults to one year. */
5
+ maxAgeSeconds?: number;
6
+ };
7
+ /**
8
+ * Writes the viewer's detected timezone to a cookie **after hydration** (in an effect only —
9
+ * never during render), so the *next* server render can resolve `local`-mode timestamps in
10
+ * the viewer's zone deterministically. Renders nothing.
11
+ *
12
+ * Setting the cookie only in an effect is deliberate: the current render must not re-resolve
13
+ * the timezone from the browser, or it would diverge from the server output and reintroduce
14
+ * the hydration mismatch this whole mechanism exists to avoid.
15
+ */
16
+ export declare function TimezoneCookieSync({ maxAgeSeconds, }?: TimezoneCookieSyncProps): null;
17
+ export {};
@@ -0,0 +1 @@
1
+ "use client";import{useEffect as o}from"react";const n="displayTimezone",i=3600*24*365;function m({maxAgeSeconds:e=i}={}){return o(()=>{try{const t=Intl.DateTimeFormat().resolvedOptions().timeZone;t&&(document.cookie=`${n}=${encodeURIComponent(t)};path=/;max-age=${e};samesite=lax`)}catch{}},[e]),null}export{n as TIMEZONE_COOKIE_NAME,m as TimezoneCookieSync};
@@ -0,0 +1,2 @@
1
+ export { TimezoneProvider, useTimezone, type TimezoneConfig, } from './TimezoneContext';
2
+ export { TimezoneCookieSync, TIMEZONE_COOKIE_NAME } from './TimezoneCookieSync';
@@ -0,0 +1 @@
1
+ import{TimezoneProvider as m,useTimezone as n}from"./TimezoneContext.js";import{TIMEZONE_COOKIE_NAME as t,TimezoneCookieSync as E}from"./TimezoneCookieSync.js";import"react/jsx-runtime";import"react";export{t as TIMEZONE_COOKIE_NAME,E as TimezoneCookieSync,m as TimezoneProvider,n as useTimezone};
package/index.d.ts ADDED
@@ -0,0 +1,12 @@
1
+ export * from './components/Avatar';
2
+ export * from './components/Badge';
3
+ export * from './components/Button';
4
+ export * from './components/Divider';
5
+ export * from './components/Link';
6
+ export * from './components/Meter';
7
+ export * from './components/Switch';
8
+ export * from './components/Time';
9
+ export * from './components/TimeInput';
10
+ export * from './components/Timezone';
11
+ export * from './components/ToggleButton';
12
+ export * from './components/Tooltip';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clicktap/ui",
3
- "version": "0.32.0",
3
+ "version": "0.33.0",
4
4
  "private": false,
5
5
  "author": "Clicktap",
6
6
  "description": "A library of React UI components and low-level hooks.",