@srcroot/ui 0.0.61 → 0.0.63

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.
package/dist/index.js CHANGED
@@ -850,7 +850,7 @@ var REGISTRY = {
850
850
  description: "Mac-style floating dock",
851
851
  category: "Navigation",
852
852
  dependencies: [],
853
- registryDependencies: ["framer-motion"]
853
+ registryDependencies: []
854
854
  },
855
855
  marquee: {
856
856
  file: "ui/marquee.tsx",
@@ -863,14 +863,14 @@ var REGISTRY = {
863
863
  description: "Button to scroll to top",
864
864
  category: "Navigation",
865
865
  dependencies: ["button"],
866
- registryDependencies: ["framer-motion"]
866
+ registryDependencies: []
867
867
  },
868
868
  "scroll-animation": {
869
869
  file: "ui/scroll-animation.tsx",
870
870
  description: "Scroll-triggered animations",
871
871
  category: "Layout",
872
872
  dependencies: [],
873
- registryDependencies: ["framer-motion"]
873
+ registryDependencies: ["gsap", "@gsap/react"]
874
874
  },
875
875
  whatsapp: {
876
876
  file: "ui/whatsapp.tsx",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@srcroot/ui",
3
- "version": "0.0.61",
3
+ "version": "0.0.63",
4
4
  "description": "A UI library with polymorphic, accessible React components",
5
5
  "author": "Shifaul Islam",
6
6
  "license": "MIT",
@@ -1,36 +1,38 @@
1
- import Script from 'next/script';
2
- import type { FC } from 'react';
1
+ "use client";
2
+
3
+ import Script from "next/script";
4
+ import type { FC } from "react";
3
5
 
4
6
  interface GoogleAnalyticsProps {
5
- gaIds: string[];
7
+ gaIds: string[];
6
8
  }
7
9
 
8
10
  const GoogleAnalytics: FC<GoogleAnalyticsProps> = ({ gaIds }) => {
9
- if (gaIds.length === 0) {
10
- return null;
11
- }
11
+ if (gaIds.length === 0) {
12
+ return null;
13
+ }
12
14
 
13
- return (
14
- <>
15
- <Script
16
- id="ga4-script"
17
- strategy="afterInteractive"
18
- src={`https://www.googletagmanager.com/gtag/js?id=${gaIds[0]}`}
19
- />
20
- <Script
21
- id="ga4-init"
22
- strategy="afterInteractive"
23
- dangerouslySetInnerHTML={{
24
- __html: `
15
+ return (
16
+ <>
17
+ <Script
18
+ id="ga4-script"
19
+ strategy="afterInteractive"
20
+ src={`https://www.googletagmanager.com/gtag/js?id=${gaIds[0]}`}
21
+ />
22
+ <Script
23
+ id="ga4-init"
24
+ strategy="afterInteractive"
25
+ dangerouslySetInnerHTML={{
26
+ __html: `
25
27
  window.dataLayer = window.dataLayer || [];
26
28
  function gtag(){dataLayer.push(arguments);}
27
29
  gtag('js', new Date());
28
- ${gaIds.map((id) => `gtag('config', '${id}', { page_path: window.location.pathname });`).join('\n')}
30
+ ${gaIds.map((id) => `gtag('config', '${id}', { page_path: window.location.pathname });`).join("\n")}
29
31
  `,
30
- }}
31
- />
32
- </>
33
- );
32
+ }}
33
+ />
34
+ </>
35
+ );
34
36
  };
35
37
 
36
38
  export default GoogleAnalytics;
@@ -1,62 +1,67 @@
1
- import Script from 'next/script';
2
- import type { FC, ReactNode } from 'react';
1
+ "use client";
2
+
3
+ import Script from "next/script";
4
+ import type { FC, ReactNode } from "react";
3
5
 
4
6
  interface GTMContainer {
5
- gtmId: string;
6
- tagServerUrl?: string;
7
+ gtmId: string;
8
+ tagServerUrl?: string;
7
9
  }
8
10
 
9
11
  interface GoogleTagManagerProps {
10
- containers: GTMContainer[];
12
+ containers: GTMContainer[];
11
13
  }
12
14
 
13
15
  const GoogleTagManager: FC<GoogleTagManagerProps> = ({ containers }) => {
14
- const defaultServer = 'https://www.googletagmanager.com';
15
-
16
- // Group containers by tagServer to avoid duplicate script loads
17
- const scriptsMap = containers.reduce((map, container) => {
18
- const server = container.tagServerUrl || defaultServer;
19
- if (!map.has(server)) {
20
- map.set(server, []);
21
- }
22
- map.get(server)!.push(container.gtmId);
23
- return map;
24
- }, new Map<string, string[]>());
25
-
26
- const scriptElements: ReactNode[] = Array.from(scriptsMap.entries()).map(([server, ids]) => (
27
- <Script
28
- key={server}
29
- id={`gtm-script-${server}`}
30
- strategy="afterInteractive"
31
- dangerouslySetInnerHTML={{
32
- __html: `
16
+ const defaultServer = "https://www.googletagmanager.com";
17
+
18
+ // Group containers by tagServer to avoid duplicate script loads
19
+ const scriptsMap = containers.reduce((map, container) => {
20
+ const server = container.tagServerUrl || defaultServer;
21
+ if (!map.has(server)) {
22
+ map.set(server, []);
23
+ }
24
+ map.get(server)!.push(container.gtmId);
25
+ return map;
26
+ }, new Map<string, string[]>());
27
+
28
+ const scriptElements: ReactNode[] = Array.from(scriptsMap.entries()).map(
29
+ ([server, ids]) => (
30
+ <Script
31
+ key={server}
32
+ id={`gtm-script-${server}`}
33
+ strategy="afterInteractive"
34
+ dangerouslySetInnerHTML={{
35
+ __html: `
33
36
  ${ids
34
- .map(
35
- id => `(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],j=d.createElement(s);j.async=true;j.src="${server}/gtm.js?"+i;f.parentNode.insertBefore(j,f);})(window,document,'script','dataLayer','${id}');`
36
- )
37
- .join('')}
37
+ .map(
38
+ (id) =>
39
+ `(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],j=d.createElement(s);j.async=true;j.src="${server}/gtm.js?"+i;f.parentNode.insertBefore(j,f);})(window,document,'script','dataLayer','${id}');`,
40
+ )
41
+ .join("")}
38
42
  `,
39
- }}
40
- />
41
- ));
42
-
43
- return (
44
- <>
45
- {scriptElements}
46
-
47
- <noscript>
48
- {containers.map(({ gtmId, tagServerUrl = defaultServer }) => (
49
- <iframe
50
- key={gtmId}
51
- src={`${tagServerUrl}/ns.html?id=${gtmId}`}
52
- height="0"
53
- width="0"
54
- style={{ display: 'none', visibility: 'hidden' }}
55
- />
56
- ))}
57
- </noscript>
58
- </>
59
- );
43
+ }}
44
+ />
45
+ ),
46
+ );
47
+
48
+ return (
49
+ <>
50
+ {scriptElements}
51
+
52
+ <noscript>
53
+ {containers.map(({ gtmId, tagServerUrl = defaultServer }) => (
54
+ <iframe
55
+ key={gtmId}
56
+ src={`${tagServerUrl}/ns.html?id=${gtmId}`}
57
+ height="0"
58
+ width="0"
59
+ style={{ display: "none", visibility: "hidden" }}
60
+ />
61
+ ))}
62
+ </noscript>
63
+ </>
64
+ );
60
65
  };
61
66
 
62
67
  export default GoogleTagManager;
@@ -1,18 +1,20 @@
1
- import Script from 'next/script';
2
- import type { FC } from 'react';
1
+ "use client";
2
+
3
+ import Script from "next/script";
4
+ import type { FC } from "react";
3
5
 
4
6
  interface MetaPixelProps {
5
- pixelIds: string[]; // ← array now
7
+ pixelIds: string[]; // ← array now
6
8
  }
7
9
 
8
10
  const MetaPixel: FC<MetaPixelProps> = ({ pixelIds }) => {
9
- return (
10
- <>
11
- <Script
12
- id="fb-script-multi"
13
- strategy="afterInteractive"
14
- dangerouslySetInnerHTML={{
15
- __html: `
11
+ return (
12
+ <>
13
+ <Script
14
+ id="fb-script-multi"
15
+ strategy="afterInteractive"
16
+ dangerouslySetInnerHTML={{
17
+ __html: `
16
18
  !function(f,b,e,v,n,t,s)
17
19
  {if(f.fbq)return;n=f.fbq=function(){n.callMethod?
18
20
  n.callMethod.apply(n,arguments):n.queue.push(arguments)};
@@ -21,24 +23,26 @@ const MetaPixel: FC<MetaPixelProps> = ({ pixelIds }) => {
21
23
  t.src=v;s=b.getElementsByTagName(e)[0];
22
24
  s.parentNode.insertBefore(t,s)}(window, document,'script',
23
25
  'https://connect.facebook.net/en_US/fbevents.js');
24
- ${pixelIds.map(id => `fbq('init', '${id}');`).join('\n')}
26
+ ${pixelIds.map((id) => `fbq('init', '${id}');`).join("\n")}
25
27
  fbq('track', 'PageView');
26
28
  `,
27
- }}
28
- />
29
+ }}
30
+ />
29
31
 
30
- {/* One noscript tag per pixel */}
31
- {pixelIds.map(id => (
32
- <noscript key={id}>
33
- <img
34
- height="1" width="1" style={{ display: 'none' }}
35
- src={`https://www.facebook.com/tr?id=${id}&ev=PageView&noscript=1`}
36
- alt=""
37
- />
38
- </noscript>
39
- ))}
40
- </>
41
- );
32
+ {/* One noscript tag per pixel */}
33
+ {pixelIds.map((id) => (
34
+ <noscript key={id}>
35
+ <img
36
+ height="1"
37
+ width="1"
38
+ style={{ display: "none" }}
39
+ src={`https://www.facebook.com/tr?id=${id}&ev=PageView&noscript=1`}
40
+ alt=""
41
+ />
42
+ </noscript>
43
+ ))}
44
+ </>
45
+ );
42
46
  };
43
47
 
44
48
  export default MetaPixel;
@@ -1,31 +1,33 @@
1
- import Script from 'next/script';
2
- import type { FC } from 'react';
1
+ "use client";
2
+
3
+ import Script from "next/script";
4
+ import type { FC } from "react";
3
5
 
4
6
  interface MicrosoftClarityProps {
5
- clarityIds: string[];
7
+ clarityIds: string[];
6
8
  }
7
9
 
8
10
  const MicrosoftClarity: FC<MicrosoftClarityProps> = ({ clarityIds }) => {
9
- return (
10
- <>
11
- {clarityIds.map((id) => (
12
- <Script
13
- key={id}
14
- id={`microsoft-clarity-init-${id}`}
15
- strategy="afterInteractive"
16
- dangerouslySetInnerHTML={{
17
- __html: `
11
+ return (
12
+ <>
13
+ {clarityIds.map((id) => (
14
+ <Script
15
+ key={id}
16
+ id={`microsoft-clarity-init-${id}`}
17
+ strategy="afterInteractive"
18
+ dangerouslySetInnerHTML={{
19
+ __html: `
18
20
  (function(c,l,a,r,i,t,y){
19
21
  c[a]=c[a]||function(){(c[a].q=c[a].q||[]).push(arguments)};
20
22
  t=l.createElement(r);t.async=1;t.src="https://www.clarity.ms/tag/"+i;
21
23
  y=l.getElementsByTagName(r)[0];y.parentNode.insertBefore(t,y);
22
24
  })(window, document, "clarity", "script", "${id}");
23
25
  `,
24
- }}
25
- />
26
- ))}
27
- </>
28
- );
26
+ }}
27
+ />
28
+ ))}
29
+ </>
30
+ );
29
31
  };
30
32
 
31
33
  export default MicrosoftClarity;
@@ -1,17 +1,19 @@
1
- import Script from 'next/script';
2
- import type { FC } from 'react';
1
+ "use client";
2
+
3
+ import Script from "next/script";
4
+ import type { FC } from "react";
3
5
 
4
6
  interface TikTokPixelProps {
5
- pixelIds: string[]; // ← array
7
+ pixelIds: string[]; // ← array
6
8
  }
7
9
 
8
10
  const TikTokPixel: FC<TikTokPixelProps> = ({ pixelIds }) => {
9
- return (
10
- <Script
11
- id="tiktok-script-multi"
12
- strategy="afterInteractive"
13
- dangerouslySetInnerHTML={{
14
- __html: `
11
+ return (
12
+ <Script
13
+ id="tiktok-script-multi"
14
+ strategy="afterInteractive"
15
+ dangerouslySetInnerHTML={{
16
+ __html: `
15
17
  !function (w, d, t) {
16
18
  w.TiktokAnalyticsObject=t;var ttq=w[t]=w[t]||[];
17
19
  ttq.methods=["page","track","identify","instances","debug","on","off","once","ready","alias","group","enableCookie","disableCookie","holdConsent","revokeConsent","grantConsent"],
@@ -22,13 +24,13 @@ const TikTokPixel: FC<TikTokPixelProps> = ({ pixelIds }) => {
22
24
  ttq._i=ttq._i||{},ttq._i[e]=[],ttq._i[e]._u=r,ttq._t=ttq._t||{},ttq._t[e]=+new Date,ttq._o=ttq._o||{},ttq._o[e]=n||{};
23
25
  var s=document.createElement("script");s.type="text/javascript",s.async=!0,s.src=r+"?sdkid="+e+"&lib="+t;
24
26
  var p=document.getElementsByTagName("script")[0];p.parentNode.insertBefore(s,p)};
25
- ${pixelIds.map(id => `ttq.load('${id}');`).join('\n')}
27
+ ${pixelIds.map((id) => `ttq.load('${id}');`).join("\n")}
26
28
  ttq.page();
27
29
  }(window, document, 'ttq');
28
30
  `,
29
- }}
30
- />
31
- );
31
+ }}
32
+ />
33
+ );
32
34
  };
33
35
 
34
36
  export default TikTokPixel;
@@ -1,32 +1,34 @@
1
- import * as React from "react"
2
- import { cva, type VariantProps } from "class-variance-authority"
3
- import { cn } from "@/lib/utils"
1
+ "use client";
2
+
3
+ import * as React from "react";
4
+ import { cva, type VariantProps } from "class-variance-authority";
5
+ import { cn } from "@/lib/utils";
4
6
 
5
7
  const alertVariants = cva(
6
- "relative w-full rounded-lg border px-4 py-3 text-sm [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground [&>svg~*]:pl-7",
7
- {
8
- variants: {
9
- variant: {
10
- default: "bg-background text-foreground",
11
- destructive:
12
- "border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive",
13
- },
14
- },
15
- defaultVariants: {
16
- variant: "default",
17
- },
18
- }
19
- )
8
+ "relative w-full rounded-lg border px-4 py-3 text-sm [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground [&>svg~*]:pl-7",
9
+ {
10
+ variants: {
11
+ variant: {
12
+ default: "bg-background text-foreground",
13
+ destructive:
14
+ "border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive",
15
+ },
16
+ },
17
+ defaultVariants: {
18
+ variant: "default",
19
+ },
20
+ },
21
+ );
20
22
 
21
23
  /**
22
24
  * Alert component for inline feedback
23
- *
25
+ *
24
26
  * @example
25
27
  * <Alert>
26
28
  * <AlertTitle>Note</AlertTitle>
27
29
  * <AlertDescription>This is an informational message.</AlertDescription>
28
30
  * </Alert>
29
- *
31
+ *
30
32
  * @example
31
33
  * <Alert variant="destructive">
32
34
  * <AlertTitle>Error</AlertTitle>
@@ -34,40 +36,40 @@ const alertVariants = cva(
34
36
  * </Alert>
35
37
  */
36
38
  const Alert = React.forwardRef<
37
- HTMLDivElement,
38
- React.HTMLAttributes<HTMLDivElement> & VariantProps<typeof alertVariants>
39
+ HTMLDivElement,
40
+ React.HTMLAttributes<HTMLDivElement> & VariantProps<typeof alertVariants>
39
41
  >(({ className, variant, ...props }, ref) => (
40
- <div
41
- ref={ref}
42
- role="alert"
43
- className={cn(alertVariants({ variant }), className)}
44
- {...props}
45
- />
46
- ))
47
- Alert.displayName = "Alert"
42
+ <div
43
+ ref={ref}
44
+ role="alert"
45
+ className={cn(alertVariants({ variant }), className)}
46
+ {...props}
47
+ />
48
+ ));
49
+ Alert.displayName = "Alert";
48
50
 
49
51
  const AlertTitle = React.forwardRef<
50
- HTMLParagraphElement,
51
- React.HTMLAttributes<HTMLHeadingElement>
52
+ HTMLParagraphElement,
53
+ React.HTMLAttributes<HTMLHeadingElement>
52
54
  >(({ className, ...props }, ref) => (
53
- <h5
54
- ref={ref}
55
- className={cn("mb-1 font-medium leading-none tracking-tight", className)}
56
- {...props}
57
- />
58
- ))
59
- AlertTitle.displayName = "AlertTitle"
55
+ <h5
56
+ ref={ref}
57
+ className={cn("mb-1 font-medium leading-none tracking-tight", className)}
58
+ {...props}
59
+ />
60
+ ));
61
+ AlertTitle.displayName = "AlertTitle";
60
62
 
61
63
  const AlertDescription = React.forwardRef<
62
- HTMLParagraphElement,
63
- React.HTMLAttributes<HTMLParagraphElement>
64
+ HTMLParagraphElement,
65
+ React.HTMLAttributes<HTMLParagraphElement>
64
66
  >(({ className, ...props }, ref) => (
65
- <div
66
- ref={ref}
67
- className={cn("text-sm [&_p]:leading-relaxed", className)}
68
- {...props}
69
- />
70
- ))
71
- AlertDescription.displayName = "AlertDescription"
67
+ <div
68
+ ref={ref}
69
+ className={cn("text-sm [&_p]:leading-relaxed", className)}
70
+ {...props}
71
+ />
72
+ ));
73
+ AlertDescription.displayName = "AlertDescription";
72
74
 
73
- export { Alert, AlertTitle, AlertDescription }
75
+ export { Alert, AlertTitle, AlertDescription };
@@ -1,23 +1,25 @@
1
- import * as React from "react"
2
- import { cn } from "@/lib/utils"
1
+ "use client";
2
+
3
+ import * as React from "react";
4
+ import { cn } from "@/lib/utils";
3
5
 
4
6
  interface AspectRatioProps extends React.HTMLAttributes<HTMLDivElement> {
5
- /**
6
- * The aspect ratio (width / height)
7
- * @default 1
8
- */
9
- ratio?: number
7
+ /**
8
+ * The aspect ratio (width / height)
9
+ * @default 1
10
+ */
11
+ ratio?: number;
10
12
  }
11
13
 
12
14
  /**
13
15
  * AspectRatio component to maintain consistent dimensions
14
- *
16
+ *
15
17
  * @example
16
18
  * // 16:9 video aspect ratio
17
19
  * <AspectRatio ratio={16 / 9}>
18
20
  * <img src="..." className="object-cover w-full h-full" />
19
21
  * </AspectRatio>
20
- *
22
+ *
21
23
  * @example
22
24
  * // Square
23
25
  * <AspectRatio ratio={1}>
@@ -25,20 +27,20 @@ interface AspectRatioProps extends React.HTMLAttributes<HTMLDivElement> {
25
27
  * </AspectRatio>
26
28
  */
27
29
  const AspectRatio = React.forwardRef<HTMLDivElement, AspectRatioProps>(
28
- ({ className, ratio = 1, style, children, ...props }, ref) => (
29
- <div
30
- ref={ref}
31
- className={cn("relative w-full", className)}
32
- style={{
33
- paddingBottom: `${100 / ratio}%`,
34
- ...style,
35
- }}
36
- {...props}
37
- >
38
- <div className="absolute inset-0">{children}</div>
39
- </div>
40
- )
41
- )
42
- AspectRatio.displayName = "AspectRatio"
30
+ ({ className, ratio = 1, style, children, ...props }, ref) => (
31
+ <div
32
+ ref={ref}
33
+ className={cn("relative w-full", className)}
34
+ style={{
35
+ paddingBottom: `${100 / ratio}%`,
36
+ ...style,
37
+ }}
38
+ {...props}
39
+ >
40
+ <div className="absolute inset-0">{children}</div>
41
+ </div>
42
+ ),
43
+ );
44
+ AspectRatio.displayName = "AspectRatio";
43
45
 
44
- export { AspectRatio }
46
+ export { AspectRatio };