@playfast/reform-better-hub-ui-primitives 0.2.1 → 0.3.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.
@@ -1,81 +1,79 @@
1
- // Adapted from better-hub by Better Auth — https://github.com/better-auth/better-hub
2
- // (apps/web/src/components/ui/time-ago.tsx). Full credit to the Better Auth team.
1
+ import { DateTime } from 'effect'
2
+ import type * as React from 'react'
3
+ import { useState, useEffect } from 'react'
3
4
 
4
- import { DateTime } from "effect";
5
- import type * as React from "react";
6
- import { useState, useEffect } from 'react';
5
+ const MS_PER_SECOND = 1000
6
+ const SECONDS_PER_MINUTE = 60
7
+ const SECONDS_PER_HOUR = 3600
8
+ const SECONDS_PER_DAY = 86400
9
+ const SECONDS_PER_WEEK = 604800
10
+ const SECONDS_PER_MONTH = 2592000
11
+ const MONTHS_PER_YEAR = 12
12
+ const REFRESH_INTERVAL_MS = 60_000
7
13
 
8
- const MS_PER_SECOND = 1000;
9
- const SECONDS_PER_MINUTE = 60;
10
- const SECONDS_PER_HOUR = 3600;
11
- const SECONDS_PER_DAY = 86400;
12
- const SECONDS_PER_WEEK = 604800;
13
- const SECONDS_PER_MONTH = 2592000;
14
- const MONTHS_PER_YEAR = 12;
15
- const REFRESH_INTERVAL_MS = 60_000;
16
-
17
- // Inlined from better-hub's "@/lib/utils" (timeAgo) — only the piece used here.
18
14
  function timeAgo(date: string | Date): string {
19
- const now = DateTime.unsafeNow();
20
- const then = DateTime.unsafeMake(date);
21
- const seconds = Math.floor((DateTime.toEpochMillis(now) - DateTime.toEpochMillis(then)) / MS_PER_SECOND);
15
+ const now = DateTime.unsafeNow()
16
+ const then = DateTime.unsafeMake(date)
17
+ const seconds = Math.floor(
18
+ (DateTime.toEpochMillis(now) - DateTime.toEpochMillis(then)) / MS_PER_SECOND,
19
+ )
22
20
 
23
- if (seconds < SECONDS_PER_MINUTE) {
24
- return 'just now';
25
- }
26
- if (seconds < SECONDS_PER_HOUR) {
27
- return `${Math.floor(seconds / SECONDS_PER_MINUTE)}m ago`;
28
- }
29
- if (seconds < SECONDS_PER_DAY) {
30
- return `${Math.floor(seconds / SECONDS_PER_HOUR)}h ago`;
31
- }
32
- if (seconds < SECONDS_PER_WEEK) {
33
- return `${Math.floor(seconds / SECONDS_PER_DAY)}d ago`;
34
- }
35
- if (seconds < SECONDS_PER_MONTH) {
36
- return `${Math.floor(seconds / SECONDS_PER_WEEK)}w ago`;
37
- }
21
+ if (seconds < SECONDS_PER_MINUTE) {
22
+ return 'just now'
23
+ }
24
+ if (seconds < SECONDS_PER_HOUR) {
25
+ return `${Math.floor(seconds / SECONDS_PER_MINUTE)}m ago`
26
+ }
27
+ if (seconds < SECONDS_PER_DAY) {
28
+ return `${Math.floor(seconds / SECONDS_PER_HOUR)}h ago`
29
+ }
30
+ if (seconds < SECONDS_PER_WEEK) {
31
+ return `${Math.floor(seconds / SECONDS_PER_DAY)}d ago`
32
+ }
33
+ if (seconds < SECONDS_PER_MONTH) {
34
+ return `${Math.floor(seconds / SECONDS_PER_WEEK)}w ago`
35
+ }
38
36
 
39
- const months = Math.floor(seconds / SECONDS_PER_MONTH);
40
- if (months < MONTHS_PER_YEAR) {
41
- return `${months}mo ago`;
42
- }
37
+ const months = Math.floor(seconds / SECONDS_PER_MONTH)
38
+ if (months < MONTHS_PER_YEAR) {
39
+ return `${months}mo ago`
40
+ }
43
41
 
44
- const thenDate = DateTime.toDate(then);
45
- const sameYear = thenDate.getFullYear() === DateTime.toDate(now).getFullYear();
46
- if (sameYear) {
47
- return thenDate.toLocaleDateString('en-US', { month: 'short', day: 'numeric' });
48
- }
49
- return thenDate.toLocaleDateString('en-US', {
50
- month: 'short',
51
- day: 'numeric',
52
- year: 'numeric',
53
- });
42
+ const thenDate = DateTime.toDate(then)
43
+ const sameYear = thenDate.getFullYear() === DateTime.toDate(now).getFullYear()
44
+ if (sameYear) {
45
+ return thenDate.toLocaleDateString('en-US', { month: 'short', day: 'numeric' })
46
+ }
47
+ return thenDate.toLocaleDateString('en-US', {
48
+ month: 'short',
49
+ day: 'numeric',
50
+ year: 'numeric',
51
+ })
54
52
  }
55
53
 
56
54
  interface TimeAgoPropsExternalApi {
57
- date: string | Date;
58
- className?: string;
55
+ date: string | Date
56
+ className?: string
59
57
  }
60
58
 
61
59
  export function TimeAgo({ date, className }: TimeAgoPropsExternalApi): React.JSX.Element {
62
- const [text, setText] = useState(() => timeAgo(date));
60
+ const [text, setText] = useState(() => timeAgo(date))
63
61
 
64
- useEffect(() => {
65
- setText(timeAgo(date));
66
- // oxlint-disable-next-line reform-rules/no-set-timeout-interval -- browser-timer seam: periodic relative-time refresh for React, no Effect runtime here
67
- const interval = setInterval(() => setText(timeAgo(date)), REFRESH_INTERVAL_MS);
68
- return () => clearInterval(interval);
69
- }, [date]);
62
+ useEffect(() => {
63
+ setText(timeAgo(date))
64
+ // oxlint-disable-next-line reform-rules/no-set-timeout-interval -- browser-timer seam: periodic relative-time refresh for React, no Effect runtime here
65
+ const interval = setInterval(() => setText(timeAgo(date)), REFRESH_INTERVAL_MS)
66
+ return () => clearInterval(interval)
67
+ }, [date])
70
68
 
71
- return (
72
- <time
73
- dateTime={typeof date === 'string' ? date : date.toISOString()}
74
- title={DateTime.toDate(DateTime.unsafeMake(date)).toLocaleString()}
75
- className={className}
76
- suppressHydrationWarning
77
- >
78
- {text}
79
- </time>
80
- );
69
+ return (
70
+ <time
71
+ dateTime={typeof date === 'string' ? date : date.toISOString()}
72
+ title={DateTime.toDate(DateTime.unsafeMake(date)).toLocaleString()}
73
+ className={className}
74
+ suppressHydrationWarning
75
+ >
76
+ {text}
77
+ </time>
78
+ )
81
79
  }
@@ -1,64 +1,67 @@
1
- // Adapted from better-hub by Better Auth — https://github.com/better-auth/better-hub
2
- // (apps/web/src/components/ui/tooltip.tsx). Full credit to the Better Auth team.
3
-
4
- import * as TooltipPrimitive from "@radix-ui/react-tooltip";
5
- import type * as React from "react";
6
- import { cn } from "../foundation/cn";
1
+ import * as TooltipPrimitive from '@radix-ui/react-tooltip'
2
+ import type * as React from 'react'
3
+ import { cn } from '../foundation/cn'
7
4
 
8
5
  function TooltipProvider({
9
- delayDuration = 300,
10
- ...props
6
+ delayDuration = 300,
7
+ ...props
11
8
  }: React.ComponentProps<typeof TooltipPrimitive.Provider>): React.JSX.Element {
12
- return (
13
- <TooltipPrimitive.Provider
14
- data-slot="tooltip-provider"
15
- delayDuration={delayDuration}
16
- {...props}
17
- />
18
- );
9
+ return (
10
+ <TooltipPrimitive.Provider
11
+ data-slot="tooltip-provider"
12
+ delayDuration={delayDuration}
13
+ {...props}
14
+ />
15
+ )
19
16
  }
20
17
 
21
- function Tooltip({ ...props }: React.ComponentProps<typeof TooltipPrimitive.Root>): React.JSX.Element {
22
- return <TooltipPrimitive.Root data-slot="tooltip" {...props} />;
18
+ function Tooltip({
19
+ ...props
20
+ }: React.ComponentProps<typeof TooltipPrimitive.Root>): React.JSX.Element {
21
+ return <TooltipPrimitive.Root data-slot="tooltip" {...props} />
23
22
  }
24
23
 
25
- function TooltipTrigger({ ...props }: React.ComponentProps<typeof TooltipPrimitive.Trigger>): React.JSX.Element {
26
- return <TooltipPrimitive.Trigger data-slot="tooltip-trigger" {...props} />;
24
+ function TooltipTrigger({
25
+ ...props
26
+ }: React.ComponentProps<typeof TooltipPrimitive.Trigger>): React.JSX.Element {
27
+ return <TooltipPrimitive.Trigger data-slot="tooltip-trigger" {...props} />
27
28
  }
28
29
 
29
- function TooltipPortal({ ...props }: React.ComponentProps<typeof TooltipPrimitive.Portal>): React.JSX.Element {
30
- return <TooltipPrimitive.Portal data-slot="tooltip-portal" {...props} />;
30
+ function TooltipPortal({
31
+ ...props
32
+ }: React.ComponentProps<typeof TooltipPrimitive.Portal>): React.JSX.Element {
33
+ return <TooltipPrimitive.Portal data-slot="tooltip-portal" {...props} />
31
34
  }
32
35
 
33
36
  function TooltipContent({
34
- className,
35
- sideOffset = 4,
36
- ...props
37
+ className,
38
+ sideOffset = 4,
39
+ ...props
37
40
  }: React.ComponentProps<typeof TooltipPrimitive.Content>): React.JSX.Element {
38
- return (
39
- <TooltipPrimitive.Content
40
- data-slot="tooltip-content"
41
- sideOffset={sideOffset}
42
- className={cn(
43
- "bg-background text-popover-foreground animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 overflow-hidden rounded-md border px-3 py-1.5 text-sm shadow-md",
44
- className,
45
- )}
46
- {...props}
47
- />
48
- );
41
+ return (
42
+ <TooltipPrimitive.Content
43
+ data-slot="tooltip-content"
44
+ sideOffset={sideOffset}
45
+ className={cn(
46
+ 'bg-background text-popover-foreground animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 overflow-hidden rounded-md border px-3 py-1.5 text-sm shadow-md',
47
+ className,
48
+ )}
49
+ {...props}
50
+ />
51
+ )
49
52
  }
50
53
 
51
54
  function TooltipArrow({
52
- className,
53
- ...props
55
+ className,
56
+ ...props
54
57
  }: React.ComponentProps<typeof TooltipPrimitive.Arrow>): React.JSX.Element {
55
- return (
56
- <TooltipPrimitive.Arrow
57
- data-slot="tooltip-arrow"
58
- className={cn("fill-background", className)}
59
- {...props}
60
- />
61
- );
58
+ return (
59
+ <TooltipPrimitive.Arrow
60
+ data-slot="tooltip-arrow"
61
+ className={cn('fill-background', className)}
62
+ {...props}
63
+ />
64
+ )
62
65
  }
63
66
 
64
- export { Tooltip, TooltipArrow, TooltipContent, TooltipPortal, TooltipProvider, TooltipTrigger };
67
+ export { Tooltip, TooltipArrow, TooltipContent, TooltipPortal, TooltipProvider, TooltipTrigger }
@@ -1,9 +1,5 @@
1
1
  import { type ClassValue, clsx } from 'clsx'
2
2
  import { twMerge } from 'tailwind-merge'
3
3
 
4
- /**
5
- * Merge class names with Tailwind-aware de-duplication.
6
- * Adapted from better-hub (apps/web/src/lib/utils.ts). See ../../README.md.
7
- */
8
4
  // oxlint-disable-next-line reform-rules/min-var-name -- `cn` is the canonical shadcn/Tailwind class-merge helper, a public export consumed across the monorepo
9
5
  export const cn = (...inputs: ClassValue[]): string => twMerge(clsx(inputs))
@@ -82,10 +82,12 @@
82
82
 
83
83
  /* Default theme: Midnight (dark) */
84
84
  :root {
85
- --font-geist-sans: 'Geist', ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont,
86
- 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
87
- --font-geist-mono: 'Geist Mono', ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas,
88
- 'Liberation Mono', monospace;
85
+ --font-geist-sans:
86
+ 'Geist', ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
87
+ 'Helvetica Neue', Arial, sans-serif;
88
+ --font-geist-mono:
89
+ 'Geist Mono', ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, 'Liberation Mono',
90
+ monospace;
89
91
  --radius-sm: 0.25rem;
90
92
  --radius-md: 0.5rem;
91
93
  --radius-lg: 0.75rem;
package/src/index.ts CHANGED
@@ -1,25 +1,22 @@
1
- // This package's primitives are adapted from better-hub by Better Auth
2
- // (https://github.com/better-auth/better-hub) — full credit to the original
3
- // authors. See README.md for details.
1
+ export * from './components/agent-icon'
2
+ export * from './components/autocomplete'
3
+ export * from './components/badge'
4
+ export * from './components/button'
5
+ export * from './components/combobox'
6
+ export * from './components/command'
7
+ export * from './components/dialog'
8
+ export * from './components/dropdown-menu'
9
+ export * from './components/github-background'
10
+ export * from './components/halftone-background'
11
+ export * from './components/input'
12
+ export * from './components/input-group'
13
+ export * from './components/live-duration'
14
+ export * from './components/logo'
15
+ export * from './components/popover'
16
+ export * from './components/resize-handle'
17
+ export * from './components/sheet'
18
+ export * from './components/textarea'
19
+ export * from './components/time-ago'
20
+ export * from './components/tooltip'
4
21
 
5
- export * from './components/agent-icon';
6
- export * from './components/badge';
7
- export * from './components/button';
8
- export * from './components/combobox';
9
- export * from './components/command';
10
- export * from './components/dialog';
11
- export * from './components/dropdown-menu';
12
- export * from './components/github-background';
13
- export * from './components/halftone-background';
14
- export * from './components/input';
15
- export * from './components/input-group';
16
- export * from './components/live-duration';
17
- export * from './components/logo';
18
- export * from './components/popover';
19
- export * from './components/resize-handle';
20
- export * from './components/sheet';
21
- export * from './components/textarea';
22
- export * from './components/time-ago';
23
- export * from './components/tooltip';
24
-
25
- export { cn } from './foundation/cn';
22
+ export { cn } from './foundation/cn'