UNPKG

@gfazioli/mantine-clock

Version:

React Clock components and hooks for Mantine with timezone support, countdown timers, customization options, and real-time updates.

1 lines 145 kB
{"version":3,"file":"Clock.cjs","sources":["../../src/Clock.tsx"],"sourcesContent":["import dayjs from 'dayjs';\nimport timezone from 'dayjs/plugin/timezone';\nimport utc from 'dayjs/plugin/utc';\nimport React, { useEffect, useRef, useState } from 'react';\nimport {\n Box,\n BoxProps,\n createVarsResolver,\n Factory,\n factory,\n getSize,\n GetStylesApi,\n MantineColor,\n MantineSize,\n parseThemeColor,\n px,\n StylesApiProps,\n Text,\n TextProps,\n useProps,\n useStyles,\n} from '@mantine/core';\nimport classes from './Clock.module.css';\n\n// Extend dayjs with timezone support\ndayjs.extend(utc);\ndayjs.extend(timezone);\n\n// Common timezone strings for better IntelliSense\nexport type Timezone =\n | 'UTC'\n | 'America/New_York'\n | 'America/Los_Angeles'\n | 'America/Chicago'\n | 'America/Denver'\n | 'America/Toronto'\n | 'America/Vancouver'\n | 'America/Sao_Paulo'\n | 'America/Mexico_City'\n | 'Europe/London'\n | 'Europe/Berlin'\n | 'Europe/Paris'\n | 'Europe/Rome'\n | 'Europe/Madrid'\n | 'Europe/Amsterdam'\n | 'Europe/Stockholm'\n | 'Europe/Moscow'\n | 'Asia/Tokyo'\n | 'Asia/Shanghai'\n | 'Asia/Singapore'\n | 'Asia/Hong_Kong'\n | 'Asia/Seoul'\n | 'Asia/Kolkata'\n | 'Asia/Dubai'\n | 'Australia/Sydney'\n | 'Australia/Melbourne'\n | 'Pacific/Auckland'\n | string; // Allow any timezone string\n\nexport type ClockStylesNames =\n | 'root'\n | 'clockContainer'\n | 'glassWrapper'\n | 'clockFace'\n | 'hourMarks'\n | 'hourTick'\n | 'minuteTick'\n | 'number'\n | 'primaryNumber'\n | 'secondaryNumber'\n | 'arcsLayer'\n | 'hand'\n | 'hourHand'\n | 'minuteHand'\n | 'secondHandContainer'\n | 'secondHand'\n | 'secondHandCounterweight'\n | 'centerBlur'\n | 'centerDot';\n\nexport type ClockCssVariables = {\n root:\n | '--clock-size'\n | '--clock-color'\n | '--clock-hour-ticks-color'\n | '--clock-hour-ticks-opacity'\n | '--clock-minute-ticks-color'\n | '--clock-minute-ticks-opacity'\n | '--clock-second-hand-color'\n | '--clock-minute-hand-color'\n | '--clock-hour-hand-color'\n | '--clock-seconds-arc-color'\n | '--clock-minutes-arc-color'\n | '--clock-hours-arc-color'\n | '--clock-primary-numbers-color'\n | '--clock-primary-numbers-opacity'\n | '--clock-secondary-numbers-color'\n | '--clock-secondary-numbers-opacity';\n};\n\nexport interface ClockBaseProps {\n /** Color of the clock face (MantineColor or CSS color) */\n color?: MantineColor;\n\n /** Mantine color for the hour ticks */\n hourTicksColor?: MantineColor;\n\n /** Opacity for the hour ticks (0 = hidden, 1 = fully visible) */\n hourTicksOpacity?: number;\n\n /** Mantine color for the minute ticks */\n minuteTicksColor?: MantineColor;\n\n /** Opacity for the minute ticks (0 = hidden, 1 = fully visible) */\n minuteTicksOpacity?: number;\n\n /** Mantine color for the primary hour numbers (12, 3, 6, 9) */\n primaryNumbersColor?: MantineColor;\n\n /** Opacity for the primary hour numbers (0 = hidden, 1 = fully visible) */\n primaryNumbersOpacity?: number;\n\n /** Mantine color for the secondary hour numbers (1, 2, 4, 5, 7, 8, 10, 11) */\n secondaryNumbersColor?: MantineColor;\n\n /** Opacity for the secondary hour numbers (0 = hidden, 1 = fully visible) */\n secondaryNumbersOpacity?: number;\n\n /** Second hand movement behavior */\n secondHandBehavior?: 'tick' | 'smooth' | 'tick-half' | 'tick-high-freq';\n\n /** Mantine color for the seconds hand */\n secondHandColor?: MantineColor;\n\n /** Opacity for the seconds hand (0 = hidden, 1 = fully visible) */\n secondHandOpacity?: number;\n\n /** Length of the second hand as a percentage of clock radius (0.2 to 0.8) */\n secondHandLength?: number;\n\n /** Thickness of the second hand as a percentage of clock size (0.005 to 0.05) */\n secondHandSize?: number;\n\n /** Mantine color for the minutes hand */\n minuteHandColor?: MantineColor;\n\n /** Opacity for the minutes hand (0 = hidden, 1 = fully visible) */\n minuteHandOpacity?: number;\n\n /** Thickness of the minute hand as a percentage of clock size (0.01 to 0.1) */\n minuteHandSize?: number;\n\n /** Length of the minute hand as a percentage of clock radius (0.2 to 0.8) */\n minuteHandLength?: number;\n\n /** Size of the clock in pixels (default: 400px) */\n size?: MantineSize | number | (string & {});\n\n /** Thickness of the hour hand as a percentage of clock size (0.01 to 0.1) */\n hourHandSize?: number;\n\n /** Length of the hour hand as a percentage of clock radius (0.2 to 0.8) */\n hourHandLength?: number;\n\n /** Mantine color for the hours hand */\n hourHandColor?: MantineColor;\n\n /** Opacity for the hours hand (0 = hidden, 1 = fully visible) */\n hourHandOpacity?: number;\n\n /** Distance of the hour numbers from the center as a percentage of the radius (0.5 = 50%, 0.83 = default) */\n hourNumbersDistance?: number;\n\n /** Props for primary hour numbers (12, 3, 6, 9) Text component */\n primaryNumbersProps?: TextProps;\n\n /** Props for secondary hour numbers (1, 2, 4, 5, 7, 8, 10, 11) Text component */\n secondaryNumbersProps?: TextProps;\n\n /** Timezone for displaying time in different countries (e.g., 'America/New_York', 'Europe/London', 'Asia/Tokyo') */\n timezone?: Timezone;\n\n /** Whether the clock should update in real time (default: `true`) */\n running?: boolean;\n\n /** Time value to display. Can be a string (\"10:30\", \"18:15:07\"), Date, or dayjs object. When running=true, this sets the starting time. When running=false and no value is provided, displays the current time. */\n value?: string | Date | dayjs.Dayjs;\n}\n\nexport interface ClockArcsProps {\n /** Toggle seconds arc visibility (preferred) */\n withSecondsArc?: boolean;\n /** Start time for seconds arc (e.g., \"12:00:00\") */\n secondsArcFrom?: string | Date;\n /** Direction for seconds arc */\n secondsArcDirection?: 'clockwise' | 'counterClockwise';\n /** Color for seconds arc */\n secondsArcColor?: MantineColor;\n /** Opacity for seconds arc (0 = hidden, 1 = fully visible) */\n secondsArcOpacity?: number;\n\n /** Toggle minutes arc visibility (preferred) */\n withMinutesArc?: boolean;\n /** Start time for minutes arc (e.g., \"12:00\") */\n minutesArcFrom?: string | Date;\n /** Direction for minutes arc */\n minutesArcDirection?: 'clockwise' | 'counterClockwise';\n /** Color for minutes arc */\n minutesArcColor?: MantineColor;\n /** Opacity for minutes arc (0 = hidden, 1 = fully visible) */\n minutesArcOpacity?: number;\n\n /** Toggle hours arc visibility (preferred) */\n withHoursArc?: boolean;\n /** Start time for hours arc (e.g., \"12:00\") */\n hoursArcFrom?: string | Date;\n /** Direction for hours arc */\n hoursArcDirection?: 'clockwise' | 'counterClockwise';\n /** Color for hours arc */\n hoursArcColor?: MantineColor;\n /** Opacity for hours arc (0 = hidden, 1 = fully visible) */\n hoursArcOpacity?: number;\n}\n\nexport interface ClockProps\n extends BoxProps, ClockBaseProps, ClockArcsProps, StylesApiProps<ClockFactory> {}\n\nexport type ClockFactory = Factory<{\n props: ClockProps;\n ref: HTMLDivElement;\n stylesNames: ClockStylesNames;\n vars: ClockCssVariables;\n}>;\n\nexport const defaultProps: Partial<ClockProps> = {\n size: 400,\n hourHandSize: 0.017,\n minuteHandSize: 0.011,\n secondHandSize: 0.006,\n hourHandLength: 0.4,\n minuteHandLength: 0.57,\n secondHandLength: 0.68,\n secondHandOpacity: 1,\n minuteHandOpacity: 1,\n hourHandOpacity: 1,\n running: true,\n};\n\nconst defaultClockSizes = {\n xs: 100,\n sm: 200,\n md: 400,\n lg: 480,\n xl: 512,\n};\n\nconst varsResolver = createVarsResolver<ClockFactory>(\n (\n theme,\n {\n size,\n color,\n hourTicksColor,\n hourTicksOpacity,\n minuteTicksColor,\n minuteTicksOpacity,\n primaryNumbersColor,\n primaryNumbersOpacity,\n secondaryNumbersColor,\n secondaryNumbersOpacity,\n secondHandColor,\n minuteHandColor,\n hourHandColor,\n secondsArcColor,\n minutesArcColor,\n hoursArcColor,\n }\n ) => {\n const sizeValue = size || 'md';\n const clockSize =\n typeof sizeValue === 'string' && sizeValue in defaultClockSizes\n ? defaultClockSizes[sizeValue as keyof typeof defaultClockSizes]\n : sizeValue || defaultProps.size!;\n\n const effectiveSize = Math.round(px(getSize(clockSize, 'clock-size')) as number);\n\n return {\n root: {\n '--clock-size': `${effectiveSize}px`,\n '--clock-color': parseThemeColor({\n color: color || '',\n theme,\n }).value,\n '--clock-hour-ticks-color': parseThemeColor({\n color: hourTicksColor || '',\n theme,\n }).value,\n\n '--clock-hour-ticks-opacity': (Math.round((hourTicksOpacity || 1) * 100) / 100).toString(),\n '--clock-minute-ticks-color': parseThemeColor({\n color: minuteTicksColor || '',\n theme,\n }).value,\n '--clock-minute-ticks-opacity': (\n Math.round((minuteTicksOpacity || 1) * 100) / 100\n ).toString(),\n '--clock-primary-numbers-color': parseThemeColor({\n color: primaryNumbersColor || '',\n theme,\n }).value,\n '--clock-primary-numbers-opacity': (\n Math.round((primaryNumbersOpacity || 1) * 100) / 100\n ).toString(),\n '--clock-secondary-numbers-color': parseThemeColor({\n color: secondaryNumbersColor || '',\n theme,\n }).value,\n '--clock-secondary-numbers-opacity': (\n Math.round((secondaryNumbersOpacity || 1) * 100) / 100\n ).toString(),\n '--clock-second-hand-color': parseThemeColor({\n color: secondHandColor || '',\n theme,\n }).value,\n '--clock-minute-hand-color': parseThemeColor({\n color: minuteHandColor || '',\n theme,\n }).value,\n '--clock-hour-hand-color': parseThemeColor({\n color: hourHandColor || '',\n theme,\n }).value,\n '--clock-seconds-arc-color': parseThemeColor({\n color: secondsArcColor || secondHandColor || '',\n theme,\n }).value,\n '--clock-minutes-arc-color': parseThemeColor({\n color: minutesArcColor || minuteHandColor || '',\n theme,\n }).value,\n '--clock-hours-arc-color': parseThemeColor({\n color: hoursArcColor || hourHandColor || '',\n theme,\n }).value,\n },\n };\n }\n);\n\n/**\n * Parse various time value formats into a Date object\n */\nconst parseTimeValue = (value: string | Date | dayjs.Dayjs | undefined): Date | null => {\n if (!value) {\n return null;\n }\n\n if (value instanceof Date) {\n return value;\n }\n\n if (dayjs.isDayjs(value)) {\n return value.toDate();\n }\n\n if (typeof value === 'string') {\n // Handle time string formats like \"10:30\", \"18:15:07\", etc.\n const timeRegex = /^(\\d{1,2}):(\\d{1,2})(?::(\\d{1,2}))?$/;\n const match = value.match(timeRegex);\n\n if (match) {\n const hours = parseInt(match[1], 10);\n const minutes = parseInt(match[2], 10);\n const seconds = parseInt(match[3] || '0', 10);\n\n const date = new Date();\n date.setHours(hours, minutes, seconds, 0);\n return date;\n }\n\n // Try to parse as a full date string\n const parsed = new Date(value);\n if (!isNaN(parsed.getTime())) {\n return parsed;\n }\n }\n\n return null;\n};\n\ninterface RealClockProps extends ClockBaseProps, ClockArcsProps {\n time: Date;\n getStyles: GetStylesApi<ClockFactory>;\n effectiveSize: number;\n}\n\n/**\n * RealClock component\n */\nconst RealClock: React.FC<RealClockProps> = (props) => {\n const {\n time,\n timezone,\n getStyles,\n effectiveSize,\n hourHandSize,\n minuteHandSize,\n secondHandSize,\n hourHandLength,\n minuteHandLength,\n secondHandLength,\n secondHandBehavior,\n secondHandOpacity,\n minuteHandOpacity,\n hourHandOpacity,\n hourTicksOpacity,\n minuteTicksOpacity,\n primaryNumbersOpacity,\n secondaryNumbersOpacity,\n hourNumbersDistance = 0.75, // Default distance for hour numbers\n primaryNumbersProps,\n secondaryNumbersProps,\n withSecondsArc,\n secondsArcFrom,\n secondsArcDirection = 'clockwise',\n withMinutesArc,\n minutesArcFrom,\n minutesArcDirection = 'clockwise',\n withHoursArc,\n hoursArcFrom,\n hoursArcDirection = 'clockwise',\n secondsArcOpacity,\n minutesArcOpacity,\n hoursArcOpacity,\n } = props;\n\n // Use dayjs to handle timezone conversion\n const timezoneTime = timezone && timezone !== '' ? dayjs(time).tz(timezone) : dayjs(time);\n\n const hours = timezoneTime.hour() % 12;\n const minutes = timezoneTime.minute();\n const seconds = timezoneTime.second();\n const milliseconds = timezoneTime.millisecond();\n\n // Calculate angles for clock hands (12 o'clock = 0 degrees)\n const hourAngle = hours * 30 + minutes * 0.5; // 30 degrees per hour + minute adjustment\n const minuteAngle = minutes * 6; // 6 degrees per minute\n\n // Calculate second hand angle based on behavior\n let secondAngle = 0;\n\n switch (secondHandBehavior) {\n case 'tick':\n secondAngle = seconds * 6;\n break;\n case 'tick-half':\n secondAngle = (seconds + Math.floor(milliseconds / 500) * 0.5) * 6;\n break;\n case 'tick-high-freq':\n secondAngle = (seconds + Math.floor(milliseconds / 125) * 0.125) * 6;\n break;\n case 'smooth':\n default:\n secondAngle = (seconds + milliseconds / 1000) * 6;\n break;\n }\n\n // Use effective size for all calculations to maintain proportions\n const size = effectiveSize;\n const clockRadius = Math.round(size / 2);\n const numberRadius = Math.round(clockRadius * hourNumbersDistance);\n const calculatedHourHandLength = Math.round(\n clockRadius * (hourHandLength ?? defaultProps.hourHandLength!)\n );\n const calculatedMinuteHandLength = Math.round(\n clockRadius * (minuteHandLength ?? defaultProps.minuteHandLength!)\n );\n const calculatedSecondHandLength = Math.round(\n clockRadius * (secondHandLength ?? defaultProps.secondHandLength!)\n );\n\n const centerSize = Math.round(size * 0.034); // Center dot size\n const tickOffset = Math.round(size * 0.028); // Distance from edge for ticks\n\n // Helpers to compute angles and SVG path for sectors\n const toClockAngle = (deg: number) => ((deg % 360) + 360) % 360; // normalize\n\n const secAngleFromDate = (d: Date | null | undefined) => {\n if (!d) {\n return 0;\n }\n const dt = timezone && timezone !== '' ? dayjs(d).tz(timezone) : dayjs(d);\n const s = dt.second();\n const ms = dt.millisecond();\n return toClockAngle((s + ms / 1000) * 6);\n };\n\n const minAngleFromDate = (d: Date | null | undefined) => {\n if (!d) {\n return 0;\n }\n const dt = timezone && timezone !== '' ? dayjs(d).tz(timezone) : dayjs(d);\n const m = dt.minute();\n return toClockAngle(m * 6);\n };\n\n const hourAngleFromDate = (d: Date | null | undefined) => {\n if (!d) {\n return 0;\n }\n const dt = timezone && timezone !== '' ? dayjs(d).tz(timezone) : dayjs(d);\n const h = dt.hour() % 12;\n const m = dt.minute();\n return toClockAngle(h * 30 + m * 0.5);\n };\n\n const describeSector = (\n cx: number,\n cy: number,\n r: number,\n startDeg: number,\n endDeg: number,\n direction: 'clockwise' | 'counterClockwise'\n ) => {\n const start = toClockAngle(startDeg);\n const end = toClockAngle(endDeg);\n\n // Compute sweep and large-arc-flag based on direction\n let delta = 0;\n if (direction === 'clockwise') {\n delta = end - start;\n if (delta < 0) {\n delta += 360;\n }\n } else {\n delta = start - end;\n if (delta < 0) {\n delta += 360;\n }\n }\n // Use >= to avoid flipping around 180deg due to floating point noise\n const largeArc = delta >= 180 ? 1 : 0;\n const sweep = direction === 'clockwise' ? 1 : 0;\n\n const aStart = (start * Math.PI) / 180;\n const aEnd = (end * Math.PI) / 180;\n // Avoid rounding to integers to prevent jitter; keep subpixel precision\n const x1 = cx + r * Math.sin(aStart);\n const y1 = cy - r * Math.cos(aStart);\n const x2 = cx + r * Math.sin(aEnd);\n const y2 = cy - r * Math.cos(aEnd);\n\n // Format numbers to a reasonable precision to keep DOM diffs small\n const fmt = (n: number) => (Number.isFinite(n) ? n.toFixed(3) : '0');\n\n // Build sector path: center -> start point -> arc -> center\n return `M ${fmt(cx)} ${fmt(cy)} L ${fmt(x1)} ${fmt(y1)} A ${fmt(r)} ${fmt(r)} 0 ${largeArc} ${sweep} ${fmt(x2)} ${fmt(y2)} Z`;\n };\n\n const showSecArc = withSecondsArc === true && (secondsArcOpacity ?? 1) !== 0;\n const showMinArc = withMinutesArc === true && (minutesArcOpacity ?? 1) !== 0;\n const showHrArc = withHoursArc === true && (hoursArcOpacity ?? 1) !== 0;\n\n return (\n <Box {...getStyles('clockContainer')}>\n {/* Glass wrapper with shadow */}\n <Box {...getStyles('glassWrapper')}>\n {/* Clock face */}\n <Box {...getStyles('clockFace')}>\n {/* Arcs layer (rendered above face, below hands) */}\n {(showSecArc || showMinArc || showHrArc) && (\n <svg\n {...getStyles('arcsLayer', { style: { width: size, height: size } })}\n viewBox={`0 0 ${size} ${size}`}\n >\n {showHrArc && (\n <path\n d={describeSector(\n clockRadius,\n clockRadius,\n calculatedHourHandLength,\n hourAngleFromDate(parseTimeValue(hoursArcFrom) ?? null),\n hourAngle,\n hoursArcDirection\n )}\n fill=\"var(--clock-hours-arc-color-resolved)\"\n fillOpacity={Math.round((hoursArcOpacity ?? 1) * 100) / 100}\n />\n )}\n {showMinArc && (\n <path\n d={describeSector(\n clockRadius,\n clockRadius,\n calculatedMinuteHandLength,\n minAngleFromDate(parseTimeValue(minutesArcFrom) ?? null),\n minuteAngle,\n minutesArcDirection\n )}\n fill=\"var(--clock-minutes-arc-color-resolved)\"\n fillOpacity={Math.round((minutesArcOpacity ?? 1) * 100) / 100}\n />\n )}\n {showSecArc && (\n <path\n d={describeSector(\n clockRadius,\n clockRadius,\n calculatedSecondHandLength,\n secAngleFromDate(parseTimeValue(secondsArcFrom) ?? null),\n secondAngle,\n secondsArcDirection\n )}\n fill=\"var(--clock-seconds-arc-color-resolved)\"\n fillOpacity={Math.round((secondsArcOpacity ?? 1) * 100) / 100}\n />\n )}\n </svg>\n )}\n {/* Hour marks container */}\n <Box {...getStyles('hourMarks')}>\n {/* Hour ticks */}\n {hourTicksOpacity !== 0 &&\n Array.from({ length: 12 }, (_, i) => (\n <Box\n key={`hour-tick-${i}`}\n {...getStyles('hourTick', {\n style: {\n top: tickOffset,\n left: '50%',\n transformOrigin: `50% ${clockRadius - tickOffset}px`,\n transform: `translateX(-50%) rotate(${i * 30}deg)`,\n },\n })}\n />\n ))}\n\n {/* Minute ticks */}\n {minuteTicksOpacity !== 0 &&\n Array.from({ length: 60 }, (_, i) => {\n // Skip positions where hour ticks are (every 5 minutes)\n if (i % 5 === 0) {\n return null;\n }\n\n return (\n <Box\n key={`minute-tick-${i}`}\n {...getStyles('minuteTick', {\n style: {\n top: tickOffset,\n left: '50%',\n transformOrigin: `50% ${clockRadius - tickOffset}px`,\n transform: `translateX(-50%) rotate(${i * 6}deg)`,\n },\n })}\n />\n );\n })}\n\n {/* Hour numbers - Primary (12, 3, 6, 9) */}\n {primaryNumbersOpacity !== 0 &&\n [12, 3, 6, 9].map((num) => {\n // Calculate position based on hour number\n const i = num === 12 ? 0 : num;\n const angle = (i * 30 - 90) * (Math.PI / 180); // -90 to start from top (12 o'clock)\n const x = Math.round(clockRadius + Math.cos(angle) * numberRadius);\n const y = Math.round(clockRadius + Math.sin(angle) * numberRadius);\n\n return (\n <Text\n key={`primary-number-${num}`}\n {...primaryNumbersProps}\n {...getStyles('primaryNumber', {\n className: getStyles('number').className,\n style: {\n left: x,\n top: y,\n },\n })}\n >\n {num}\n </Text>\n );\n })}\n\n {/* Hour numbers - Secondary (1, 2, 4, 5, 7, 8, 10, 11) */}\n {secondaryNumbersOpacity !== 0 &&\n [1, 2, 4, 5, 7, 8, 10, 11].map((num) => {\n // Calculate position based on hour number\n const i = num;\n const angle = (i * 30 - 90) * (Math.PI / 180); // -90 to start from top (12 o'clock)\n const x = Math.round(clockRadius + Math.cos(angle) * numberRadius);\n const y = Math.round(clockRadius + Math.sin(angle) * numberRadius);\n\n return (\n <Text\n key={`secondary-number-${num}`}\n {...secondaryNumbersProps}\n {...getStyles('secondaryNumber', {\n className: getStyles('number').className,\n style: {\n left: x,\n top: y,\n },\n })}\n >\n {num}\n </Text>\n );\n })}\n </Box>\n\n {/* Hour hand */}\n {(hourHandOpacity ?? defaultProps.hourHandOpacity!) !== 0 && (\n <Box\n // {...getStyles('hand')}\n {...getStyles('hand', {\n className: getStyles('hourHand').className,\n style: {\n width:\n Math.round(size * (hourHandSize ?? defaultProps.hourHandSize!) * 100) / 100,\n height: calculatedHourHandLength,\n opacity:\n Math.round((hourHandOpacity ?? defaultProps.hourHandOpacity!) * 100) / 100,\n bottom: clockRadius,\n left: clockRadius,\n marginLeft:\n Math.round((-(size * (hourHandSize ?? defaultProps.hourHandSize!)) / 2) * 100) /\n 100,\n borderRadius: `${Math.round(size * (hourHandSize ?? defaultProps.hourHandSize!) * 100) / 100}px`,\n transform: `rotate(${Math.round(hourAngle * 100) / 100}deg)`,\n },\n })}\n />\n )}\n\n {/* Minute hand */}\n {(minuteHandOpacity ?? defaultProps.minuteHandOpacity!) !== 0 && (\n <Box\n {...getStyles('hand', {\n className: getStyles('minuteHand').className,\n style: {\n width:\n Math.round(size * (minuteHandSize ?? defaultProps.minuteHandSize!) * 100) / 100,\n height: calculatedMinuteHandLength,\n opacity:\n Math.round((minuteHandOpacity ?? defaultProps.minuteHandOpacity!) * 100) / 100,\n bottom: clockRadius,\n left: clockRadius,\n marginLeft:\n Math.round(\n (-(size * (minuteHandSize ?? defaultProps.minuteHandSize!)) / 2) * 100\n ) / 100,\n borderRadius: `${Math.round(size * (minuteHandSize ?? defaultProps.minuteHandSize!) * 100) / 100}px`,\n transform: `rotate(${Math.round(minuteAngle * 100) / 100}deg)`,\n },\n })}\n />\n )}\n\n {/* Second hand container */}\n {(secondHandOpacity ?? defaultProps.secondHandOpacity!) !== 0 && (\n <Box\n {...getStyles('secondHandContainer', {\n style: {\n width:\n Math.round(size * (secondHandSize ?? defaultProps.secondHandSize!) * 100) / 100,\n height: calculatedSecondHandLength,\n top: clockRadius - calculatedSecondHandLength,\n left: clockRadius,\n marginLeft:\n Math.round(\n (-(size * (secondHandSize ?? defaultProps.secondHandSize!)) / 2) * 100\n ) / 100,\n transformOrigin: `${Math.round(((size * (secondHandSize ?? defaultProps.secondHandSize!)) / 2) * 100) / 100}px ${calculatedSecondHandLength}px`,\n transform: `rotate(${Math.round(secondAngle * 100) / 100}deg)`,\n },\n })}\n >\n {/* Second hand */}\n <Box\n {...getStyles('secondHand', {\n style: {\n width:\n Math.round(size * (secondHandSize ?? defaultProps.secondHandSize!) * 100) /\n 100,\n height: calculatedSecondHandLength,\n opacity:\n Math.round((secondHandOpacity ?? defaultProps.secondHandOpacity!) * 100) /\n 100,\n },\n })}\n />\n\n {/* Second hand counterweight */}\n <Box\n {...getStyles('secondHandCounterweight', {\n style: {\n width: Math.round(size * 0.006 * 3 * 100) / 100,\n opacity:\n Math.round((secondHandOpacity ?? defaultProps.secondHandOpacity!) * 100) /\n 100,\n left: Math.round(\n (size * (secondHandSize ?? defaultProps.secondHandSize!)) / 2 -\n (size * 0.006 * 3) / 2\n ),\n },\n })}\n />\n </Box>\n )}\n\n {/* Center blur */}\n <Box {...getStyles('centerBlur')} />\n\n {/* Center dot */}\n <Box\n {...getStyles('centerDot', {\n style: {\n width: centerSize,\n height: centerSize,\n opacity:\n Math.round((secondHandOpacity ?? defaultProps.secondHandOpacity!) * 100) / 100,\n top: Math.round(clockRadius - centerSize / 2),\n left: Math.round(clockRadius - centerSize / 2),\n },\n })}\n />\n </Box>\n </Box>\n </Box>\n );\n};\n\nexport const Clock = factory<ClockFactory>((_props, ref) => {\n const props = useProps('Clock', defaultProps, _props);\n const [time, setTime] = useState(new Date());\n const [hasMounted, setHasMounted] = useState(false);\n const intervalRef = useRef<NodeJS.Timeout | null>(null);\n const startTimeRef = useRef<Date | null>(null);\n const realStartTimeRef = useRef<Date | null>(null);\n\n const {\n // Clock-specific props that should not be passed to DOM\n size,\n color,\n hourTicksColor,\n hourTicksOpacity,\n minuteTicksColor,\n minuteTicksOpacity,\n primaryNumbersColor,\n primaryNumbersOpacity,\n secondaryNumbersColor,\n secondaryNumbersOpacity,\n secondHandBehavior,\n secondHandColor,\n secondHandOpacity,\n secondHandLength,\n secondHandSize,\n minuteHandColor,\n minuteHandOpacity,\n minuteHandSize,\n minuteHandLength,\n hourHandColor,\n hourHandOpacity,\n hourHandSize,\n hourHandLength,\n hourTicksOpacity: _hourTicksOpacity,\n minuteTicksOpacity: _minuteTicksOpacity,\n hourNumbersDistance,\n primaryNumbersProps,\n secondaryNumbersProps,\n timezone,\n running,\n value,\n withSecondsArc,\n secondsArcFrom,\n secondsArcDirection,\n secondsArcColor,\n secondsArcOpacity,\n withMinutesArc,\n minutesArcFrom,\n minutesArcDirection,\n minutesArcColor,\n minutesArcOpacity,\n withHoursArc,\n hoursArcFrom,\n hoursArcDirection,\n hoursArcColor,\n hoursArcOpacity,\n // Styles API props\n classNames,\n style,\n styles,\n unstyled,\n vars,\n className,\n ...others\n } = props;\n\n const getStyles = useStyles<ClockFactory>({\n name: 'Clock',\n props,\n classes,\n className,\n style,\n classNames,\n styles,\n unstyled,\n vars,\n varsResolver,\n });\n\n const effectiveSize = Math.round(\n px(\n getSize(\n typeof size === 'string' && size in defaultClockSizes\n ? defaultClockSizes[size as keyof typeof defaultClockSizes]\n : size || defaultProps.size!,\n 'clock-size'\n )\n ) as number\n );\n\n useEffect(() => {\n setHasMounted(true);\n }, []);\n\n // Calculate the effective time to display\n const getEffectiveTime = (): Date => {\n const parsedValue = parseTimeValue(value);\n\n if (!running) {\n // Static mode: show the parsed value or default to current time\n if (parsedValue) {\n return parsedValue;\n }\n // Use current time instead of fixed 12:00:00\n return time;\n }\n\n // Running mode\n if (parsedValue && startTimeRef.current && realStartTimeRef.current) {\n // Calculate elapsed time since we started\n const now = new Date();\n const elapsed = now.getTime() - realStartTimeRef.current.getTime();\n return new Date(startTimeRef.current.getTime() + elapsed);\n }\n\n // Default: real time\n return time;\n };\n\n useEffect(() => {\n // Clear existing interval\n if (intervalRef.current) {\n clearInterval(intervalRef.current);\n intervalRef.current = null;\n }\n\n // If not running, don't start any interval\n if (!running) {\n return;\n }\n\n // Set up time tracking for custom start time\n const parsedValue = parseTimeValue(value);\n if (parsedValue) {\n startTimeRef.current = parsedValue;\n realStartTimeRef.current = new Date();\n } else {\n startTimeRef.current = null;\n realStartTimeRef.current = null;\n }\n\n let interval = 1000;\n switch (secondHandBehavior) {\n case 'smooth':\n interval = 16;\n break;\n case 'tick-half':\n interval = 500;\n break;\n case 'tick-high-freq':\n interval = 125;\n break;\n case 'tick':\n default:\n interval = 1000;\n break;\n }\n\n const updateTime = () => {\n setTime(new Date());\n };\n\n updateTime();\n intervalRef.current = setInterval(updateTime, interval);\n\n return () => {\n if (intervalRef.current) {\n clearInterval(intervalRef.current);\n }\n };\n }, [running, value, secondHandBehavior, secondHandOpacity]);\n\n // Prevent hydration mismatch by not rendering dynamic content during SSR\n if (!hasMounted) {\n return (\n <Box {...getStyles('root')} ref={ref} {...others}>\n {/* Render static clock structure during SSR */}\n <Box {...getStyles('clockContainer')}>\n <Box {...getStyles('glassWrapper')}>\n <Box {...getStyles('clockFace')}>\n {/* Static hour marks and numbers only */}\n <Box {...getStyles('hourMarks')}>\n {/* Hour ticks */}\n {(hourTicksOpacity || 1) !== 0 &&\n Array.from({ length: 12 }, (_, i) => (\n <Box\n key={`hour-tick-${i}`}\n {...getStyles('hourTick', {\n style: {\n top: Math.round(effectiveSize * 0.028),\n left: '50%',\n transformOrigin: `50% ${Math.round(effectiveSize / 2) - Math.round(effectiveSize * 0.028)}px`,\n transform: `translateX(-50%) rotate(${i * 30}deg)`,\n },\n })}\n />\n ))}\n\n {/* Minute ticks */}\n {(minuteTicksOpacity || 1) !== 0 &&\n Array.from({ length: 60 }, (_, i) => {\n if (i % 5 === 0) {\n return null;\n }\n return (\n <Box\n key={`minute-tick-${i}`}\n {...getStyles('minuteTick', {\n style: {\n top: Math.round(effectiveSize * 0.028),\n left: '50%',\n transformOrigin: `50% ${Math.round(effectiveSize / 2) - Math.round(effectiveSize * 0.028)}px`,\n transform: `translateX(-50%) rotate(${i * 6}deg)`,\n },\n })}\n />\n );\n })}\n\n {/* Hour numbers - Primary (12, 3, 6, 9) */}\n {(primaryNumbersOpacity || 1) !== 0 &&\n [12, 3, 6, 9].map((num) => {\n const i = num === 12 ? 0 : num;\n const angle = (i * 30 - 90) * (Math.PI / 180);\n const clockRadius = Math.round(effectiveSize / 2);\n const numberRadius = Math.round(clockRadius * (hourNumbersDistance || 0.75));\n const x = Math.round(clockRadius + Math.cos(angle) * numberRadius);\n const y = Math.round(clockRadius + Math.sin(angle) * numberRadius);\n\n return (\n <Text\n key={`primary-number-${num}`}\n {...primaryNumbersProps}\n {...getStyles('primaryNumber', {\n className: getStyles('number').className,\n style: {\n left: x,\n top: y,\n },\n })}\n >\n {num}\n </Text>\n );\n })}\n\n {/* Hour numbers - Secondary (1, 2, 4, 5, 7, 8, 10, 11) */}\n {(secondaryNumbersOpacity || 1) !== 0 &&\n [1, 2, 4, 5, 7, 8, 10, 11].map((num) => {\n const i = num;\n const angle = (i * 30 - 90) * (Math.PI / 180);\n const clockRadius = Math.round(effectiveSize / 2);\n const numberRadius = Math.round(clockRadius * (hourNumbersDistance || 0.75));\n const x = Math.round(clockRadius + Math.cos(angle) * numberRadius);\n const y = Math.round(clockRadius + Math.sin(angle) * numberRadius);\n\n return (\n <Text\n key={`secondary-number-${num}`}\n {...secondaryNumbersProps}\n {...getStyles('secondaryNumber', {\n className: getStyles('number').className,\n style: {\n left: x,\n top: y,\n },\n })}\n >\n {num}\n </Text>\n );\n })}\n </Box>\n </Box>\n </Box>\n </Box>\n </Box>\n );\n }\n\n const effectiveTime = getEffectiveTime();\n\n return (\n <Box {...getStyles('root')} ref={ref} {...others}>\n <RealClock\n time={effectiveTime}\n getStyles={getStyles}\n effectiveSize={effectiveSize}\n {...props}\n />\n </Box>\n );\n});\n\nClock.classes = classes;\nClock.displayName = 'Clock';\n"],"names":["timezone","createVarsResolver","px","getSize","parseThemeColor","Box","Text","factory","useProps","useState","useRef","useStyles","classes","useEffect"],"mappings":"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