@nationaldesignstudio/react 0.6.0 → 0.7.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.
- package/dist/accordion/index.d.ts +95 -0
- package/dist/accordion/index.js +143 -0
- package/dist/accordion/index.js.map +1 -0
- package/dist/background/index.d.ts +149 -0
- package/dist/background/index.js +200 -0
- package/dist/background/index.js.map +1 -0
- package/dist/banner/index.d.ts +101 -0
- package/dist/banner/index.js +81 -0
- package/dist/banner/index.js.map +1 -0
- package/dist/blurred-video-backdrop/index.d.ts +233 -0
- package/dist/blurred-video-backdrop/index.js +266 -0
- package/dist/blurred-video-backdrop/index.js.map +1 -0
- package/dist/button/index.d.ts +180 -0
- package/dist/button/index.js +169 -0
- package/dist/button/index.js.map +1 -0
- package/dist/button-B2g5fH9b.d.ts +152 -0
- package/dist/card/index.d.ts +406 -0
- package/dist/card/index.js +219 -0
- package/dist/card/index.js.map +1 -0
- package/dist/card-grid/index.d.ts +90 -0
- package/dist/card-grid/index.js +74 -0
- package/dist/card-grid/index.js.map +1 -0
- package/dist/component-registry.md +136 -2
- package/dist/dev-toolbar/index.d.ts +8 -0
- package/dist/dev-toolbar/index.js +206 -0
- package/dist/dev-toolbar/index.js.map +1 -0
- package/dist/dialog/index.d.ts +268 -0
- package/dist/dialog/index.js +288 -0
- package/dist/dialog/index.js.map +1 -0
- package/dist/faq-section/index.d.ts +47 -0
- package/dist/faq-section/index.js +152 -0
- package/dist/faq-section/index.js.map +1 -0
- package/dist/grid-overlay/index.d.ts +10 -0
- package/dist/grid-overlay/index.js +38 -0
- package/dist/grid-overlay/index.js.map +1 -0
- package/dist/hero/index.d.ts +462 -0
- package/dist/hero/index.js +494 -0
- package/dist/hero/index.js.map +1 -0
- package/dist/hooks/index.d.ts +150 -0
- package/dist/hooks/index.js +339 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/index.d.ts +46 -5339
- package/dist/index.js +157 -4080
- package/dist/index.js.map +1 -1
- package/dist/input/index.d.ts +404 -0
- package/dist/input/index.js +393 -0
- package/dist/input/index.js.map +1 -0
- package/dist/navbar/index.d.ts +68 -0
- package/dist/navbar/index.js +227 -0
- package/dist/navbar/index.js.map +1 -0
- package/dist/ndstudio-footer/index.d.ts +32 -0
- package/dist/ndstudio-footer/index.js +35 -0
- package/dist/ndstudio-footer/index.js.map +1 -0
- package/dist/pager-control/index.d.ts +173 -0
- package/dist/pager-control/index.js +267 -0
- package/dist/pager-control/index.js.map +1 -0
- package/dist/popover/index.d.ts +200 -0
- package/dist/popover/index.js +290 -0
- package/dist/popover/index.js.map +1 -0
- package/dist/prose/index.d.ts +39 -0
- package/dist/prose/index.js +56 -0
- package/dist/prose/index.js.map +1 -0
- package/dist/quote-block/index.d.ts +156 -0
- package/dist/quote-block/index.js +321 -0
- package/dist/quote-block/index.js.map +1 -0
- package/dist/river/index.d.ts +100 -0
- package/dist/river/index.js +107 -0
- package/dist/river/index.js.map +1 -0
- package/dist/select/index.d.ts +188 -0
- package/dist/select/index.js +295 -0
- package/dist/select/index.js.map +1 -0
- package/dist/theme/index.d.ts +149 -0
- package/dist/theme/index.js +211 -0
- package/dist/theme/index.js.map +1 -0
- package/dist/theme-CzBPUlh_.d.ts +332 -0
- package/dist/tooltip/index.d.ts +166 -0
- package/dist/tooltip/index.js +200 -0
- package/dist/tooltip/index.js.map +1 -0
- package/dist/tout/index.d.ts +157 -0
- package/dist/tout/index.js +315 -0
- package/dist/tout/index.js.map +1 -0
- package/dist/two-column-section/index.d.ts +122 -0
- package/dist/two-column-section/index.js +121 -0
- package/dist/two-column-section/index.js.map +1 -0
- package/dist/us-gov-banner/index.d.ts +141 -0
- package/dist/us-gov-banner/index.js +74 -0
- package/dist/us-gov-banner/index.js.map +1 -0
- package/dist/use-captions-AkKlJhov.d.ts +71 -0
- package/dist/utils/index.d.ts +7 -0
- package/dist/utils/index.js +12 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/video-dialog/index.d.ts +106 -0
- package/dist/video-dialog/index.js +1305 -0
- package/dist/video-dialog/index.js.map +1 -0
- package/dist/video-player/index.d.ts +115 -0
- package/dist/video-player/index.js +879 -0
- package/dist/video-player/index.js.map +1 -0
- package/dist/video-player-qxf-BURH.d.ts +236 -0
- package/dist/video-with-backdrop/index.d.ts +267 -0
- package/dist/video-with-backdrop/index.js +1284 -0
- package/dist/video-with-backdrop/index.js.map +1 -0
- package/package.json +13 -2
- package/src/components/organisms/us-gov-banner/us-gov-banner.tsx +5 -27
- package/src/theme/hooks.ts +2 -0
- package/src/theme/index.ts +2 -0
- package/src/theme/theme-provider.tsx +2 -0
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import * as tailwind_variants from 'tailwind-variants';
|
|
2
|
+
import { VariantProps } from 'tailwind-variants';
|
|
3
|
+
import * as tailwind_variants_dist_config_js from 'tailwind-variants/dist/config.js';
|
|
4
|
+
import * as React from 'react';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Banner component based on Figma BaseKit / Banners
|
|
8
|
+
*
|
|
9
|
+
* Used to surface short, important updates or a single key action
|
|
10
|
+
* without disrupting the main page content.
|
|
11
|
+
*
|
|
12
|
+
* Responsive behavior using 24-column grid:
|
|
13
|
+
* - Mobile (sm): Stacked layout, 20px horizontal / 32px vertical padding
|
|
14
|
+
* - Tablet (md): Horizontal layout, 56px padding
|
|
15
|
+
* - Desktop (lg): Horizontal layout, 72px padding
|
|
16
|
+
*
|
|
17
|
+
* Must be placed inside a `grid-container`. Uses `col-full` to span all columns.
|
|
18
|
+
*/
|
|
19
|
+
declare const bannerVariants: tailwind_variants.TVReturnType<{
|
|
20
|
+
colorScheme: {
|
|
21
|
+
light: string;
|
|
22
|
+
dark: string;
|
|
23
|
+
};
|
|
24
|
+
}, undefined, string[], tailwind_variants_dist_config_js.TVConfig<{
|
|
25
|
+
colorScheme: {
|
|
26
|
+
light: string;
|
|
27
|
+
dark: string;
|
|
28
|
+
};
|
|
29
|
+
}, {
|
|
30
|
+
colorScheme: {
|
|
31
|
+
light: string;
|
|
32
|
+
dark: string;
|
|
33
|
+
};
|
|
34
|
+
}>, {
|
|
35
|
+
colorScheme: {
|
|
36
|
+
light: string;
|
|
37
|
+
dark: string;
|
|
38
|
+
};
|
|
39
|
+
}, undefined, tailwind_variants.TVReturnType<{
|
|
40
|
+
colorScheme: {
|
|
41
|
+
light: string;
|
|
42
|
+
dark: string;
|
|
43
|
+
};
|
|
44
|
+
}, undefined, string[], tailwind_variants_dist_config_js.TVConfig<{
|
|
45
|
+
colorScheme: {
|
|
46
|
+
light: string;
|
|
47
|
+
dark: string;
|
|
48
|
+
};
|
|
49
|
+
}, {
|
|
50
|
+
colorScheme: {
|
|
51
|
+
light: string;
|
|
52
|
+
dark: string;
|
|
53
|
+
};
|
|
54
|
+
}>, unknown, unknown, undefined>>;
|
|
55
|
+
interface BannerProps extends React.HTMLAttributes<HTMLElement>, VariantProps<typeof bannerVariants> {
|
|
56
|
+
/**
|
|
57
|
+
* The heading text displayed in the banner
|
|
58
|
+
*/
|
|
59
|
+
heading: string;
|
|
60
|
+
/**
|
|
61
|
+
* The description text displayed below the heading
|
|
62
|
+
*/
|
|
63
|
+
description: string;
|
|
64
|
+
/**
|
|
65
|
+
* Optional action element (typically a Button component)
|
|
66
|
+
*/
|
|
67
|
+
action?: React.ReactNode;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Banner component for surfacing important updates or CTAs.
|
|
71
|
+
*
|
|
72
|
+
* Uses the 24-column grid system - must be placed inside a `grid-container`.
|
|
73
|
+
* Spans full width with `col-full`.
|
|
74
|
+
*
|
|
75
|
+
* Responsive across breakpoints:
|
|
76
|
+
* - Mobile: Stacked layout with smaller padding
|
|
77
|
+
* - Tablet: Horizontal layout with medium padding
|
|
78
|
+
* - Desktop: Horizontal layout with larger padding
|
|
79
|
+
*
|
|
80
|
+
* @example
|
|
81
|
+
* ```tsx
|
|
82
|
+
* <div className="grid-container">
|
|
83
|
+
* <Banner
|
|
84
|
+
* heading="Important Update"
|
|
85
|
+
* description="Check out our new features."
|
|
86
|
+
* action={<Button>Learn More</Button>}
|
|
87
|
+
* />
|
|
88
|
+
* </div>
|
|
89
|
+
*
|
|
90
|
+
* // Dark colorScheme
|
|
91
|
+
* <Banner
|
|
92
|
+
* colorScheme="dark"
|
|
93
|
+
* heading="Still Have Questions?"
|
|
94
|
+
* description="Contact us at support@example.com"
|
|
95
|
+
* action={<Button variant="secondary">Email Us</Button>}
|
|
96
|
+
* />
|
|
97
|
+
* ```
|
|
98
|
+
*/
|
|
99
|
+
declare const Banner: React.ForwardRefExoticComponent<BannerProps & React.RefAttributes<HTMLElement>>;
|
|
100
|
+
|
|
101
|
+
export { Banner, type BannerProps, bannerVariants };
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { tv, cnBase } from 'tailwind-variants';
|
|
3
|
+
import { clsx } from 'clsx';
|
|
4
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
5
|
+
|
|
6
|
+
// src/components/sections/banner/banner.tsx
|
|
7
|
+
function cn(...inputs) {
|
|
8
|
+
return cnBase(clsx(inputs));
|
|
9
|
+
}
|
|
10
|
+
var bannerVariants = tv({
|
|
11
|
+
base: [
|
|
12
|
+
// Grid alignment - full width
|
|
13
|
+
"col-full",
|
|
14
|
+
// Responsive padding: mobile -> tablet -> desktop
|
|
15
|
+
// Uses primitive spacing tokens
|
|
16
|
+
"px-20 py-32",
|
|
17
|
+
"md:p-56",
|
|
18
|
+
"lg:px-72 lg:pb-72 lg:pt-0"
|
|
19
|
+
],
|
|
20
|
+
variants: {
|
|
21
|
+
colorScheme: {
|
|
22
|
+
light: "bg-gray-50",
|
|
23
|
+
dark: "bg-gray-1200"
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
defaultVariants: {
|
|
27
|
+
colorScheme: "light"
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
var Banner = React.forwardRef(
|
|
31
|
+
({ className, colorScheme, heading, description, action, ...props }, ref) => {
|
|
32
|
+
return /* @__PURE__ */ jsx(
|
|
33
|
+
"section",
|
|
34
|
+
{
|
|
35
|
+
ref,
|
|
36
|
+
className: bannerVariants({ colorScheme, class: className }),
|
|
37
|
+
...props,
|
|
38
|
+
children: /* @__PURE__ */ jsxs(
|
|
39
|
+
"div",
|
|
40
|
+
{
|
|
41
|
+
className: cn(
|
|
42
|
+
// Uses primitive spacing tokens
|
|
43
|
+
"flex flex-col md:flex-row gap-20 items-start md:items-center md:justify-between",
|
|
44
|
+
colorScheme === "dark" && "border-t border-gray-700 py-36"
|
|
45
|
+
),
|
|
46
|
+
children: [
|
|
47
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-6 items-start", children: [
|
|
48
|
+
/* @__PURE__ */ jsx(
|
|
49
|
+
"h2",
|
|
50
|
+
{
|
|
51
|
+
className: cn(
|
|
52
|
+
"typography-subheading-small",
|
|
53
|
+
colorScheme === "dark" ? "text-gray-100" : "text-gray-900"
|
|
54
|
+
),
|
|
55
|
+
children: heading
|
|
56
|
+
}
|
|
57
|
+
),
|
|
58
|
+
/* @__PURE__ */ jsx(
|
|
59
|
+
"p",
|
|
60
|
+
{
|
|
61
|
+
className: cn(
|
|
62
|
+
"typography-body-small",
|
|
63
|
+
colorScheme === "dark" ? "text-gray-500" : "text-gray-800"
|
|
64
|
+
),
|
|
65
|
+
children: description
|
|
66
|
+
}
|
|
67
|
+
)
|
|
68
|
+
] }),
|
|
69
|
+
action
|
|
70
|
+
]
|
|
71
|
+
}
|
|
72
|
+
)
|
|
73
|
+
}
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
);
|
|
77
|
+
Banner.displayName = "Banner";
|
|
78
|
+
|
|
79
|
+
export { Banner, bannerVariants };
|
|
80
|
+
//# sourceMappingURL=index.js.map
|
|
81
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/lib/utils.ts","../../src/components/sections/banner/banner.tsx"],"names":["twMerge"],"mappings":";;;;;;AAKO,SAAS,MAAM,MAAA,EAAsB;AAC3C,EAAA,OAAOA,MAAA,CAAQ,IAAA,CAAK,MAAM,CAAC,CAAA;AAC5B;ACUA,IAAM,iBAAiB,EAAA,CAAG;AAAA,EACzB,IAAA,EAAM;AAAA;AAAA,IAEL,UAAA;AAAA;AAAA;AAAA,IAGA,aAAA;AAAA,IACA,SAAA;AAAA,IACA;AAAA,GACD;AAAA,EACA,QAAA,EAAU;AAAA,IACT,WAAA,EAAa;AAAA,MACZ,KAAA,EAAO,YAAA;AAAA,MACP,IAAA,EAAM;AAAA;AACP,GACD;AAAA,EACA,eAAA,EAAiB;AAAA,IAChB,WAAA,EAAa;AAAA;AAEf,CAAC;AAiDD,IAAM,MAAA,GAAe,KAAA,CAAA,UAAA;AAAA,EACpB,CAAC,EAAE,SAAA,EAAW,WAAA,EAAa,OAAA,EAAS,aAAa,MAAA,EAAQ,GAAG,KAAA,EAAM,EAAG,GAAA,KAAQ;AAC5E,IAAA,uBACC,GAAA;AAAA,MAAC,SAAA;AAAA,MAAA;AAAA,QACA,GAAA;AAAA,QACA,WAAW,cAAA,CAAe,EAAE,WAAA,EAAa,KAAA,EAAO,WAAW,CAAA;AAAA,QAC1D,GAAG,KAAA;AAAA,QAGJ,QAAA,kBAAA,IAAA;AAAA,UAAC,KAAA;AAAA,UAAA;AAAA,YACA,SAAA,EAAW,EAAA;AAAA;AAAA,cAEV,iFAAA;AAAA,cACA,gBAAgB,MAAA,IAAU;AAAA,aAC3B;AAAA,YAGA,QAAA,EAAA;AAAA,8BAAA,IAAA,CAAC,KAAA,EAAA,EAAI,WAAU,iCAAA,EACd,QAAA,EAAA;AAAA,gCAAA,GAAA;AAAA,kBAAC,IAAA;AAAA,kBAAA;AAAA,oBACA,SAAA,EAAW,EAAA;AAAA,sBACV,6BAAA;AAAA,sBACA,WAAA,KAAgB,SAAS,eAAA,GAAkB;AAAA,qBAC5C;AAAA,oBAEC,QAAA,EAAA;AAAA;AAAA,iBACF;AAAA,gCACA,GAAA;AAAA,kBAAC,GAAA;AAAA,kBAAA;AAAA,oBACA,SAAA,EAAW,EAAA;AAAA,sBACV,uBAAA;AAAA,sBACA,WAAA,KAAgB,SAAS,eAAA,GAAkB;AAAA,qBAC5C;AAAA,oBAEC,QAAA,EAAA;AAAA;AAAA;AACF,eAAA,EACD,CAAA;AAAA,cAEC;AAAA;AAAA;AAAA;AACF;AAAA,KACD;AAAA,EAEF;AACD;AACA,MAAA,CAAO,WAAA,GAAc,QAAA","file":"index.js","sourcesContent":["import { type ClassValue, clsx } from \"clsx\";\nimport { cnBase as twMerge } from \"tailwind-variants\";\n\nexport { twMerge };\n\nexport function cn(...inputs: ClassValue[]) {\n\treturn twMerge(clsx(inputs));\n}\n","import * as React from \"react\";\nimport { tv, type VariantProps } from \"tailwind-variants\";\nimport { cn } from \"@/lib/utils\";\n\n/**\n * Banner component based on Figma BaseKit / Banners\n *\n * Used to surface short, important updates or a single key action\n * without disrupting the main page content.\n *\n * Responsive behavior using 24-column grid:\n * - Mobile (sm): Stacked layout, 20px horizontal / 32px vertical padding\n * - Tablet (md): Horizontal layout, 56px padding\n * - Desktop (lg): Horizontal layout, 72px padding\n *\n * Must be placed inside a `grid-container`. Uses `col-full` to span all columns.\n */\nconst bannerVariants = tv({\n\tbase: [\n\t\t// Grid alignment - full width\n\t\t\"col-full\",\n\t\t// Responsive padding: mobile -> tablet -> desktop\n\t\t// Uses primitive spacing tokens\n\t\t\"px-20 py-32\",\n\t\t\"md:p-56\",\n\t\t\"lg:px-72 lg:pb-72 lg:pt-0\",\n\t],\n\tvariants: {\n\t\tcolorScheme: {\n\t\t\tlight: \"bg-gray-50\",\n\t\t\tdark: \"bg-gray-1200\",\n\t\t},\n\t},\n\tdefaultVariants: {\n\t\tcolorScheme: \"light\",\n\t},\n});\n\nexport interface BannerProps\n\textends React.HTMLAttributes<HTMLElement>,\n\t\tVariantProps<typeof bannerVariants> {\n\t/**\n\t * The heading text displayed in the banner\n\t */\n\theading: string;\n\t/**\n\t * The description text displayed below the heading\n\t */\n\tdescription: string;\n\t/**\n\t * Optional action element (typically a Button component)\n\t */\n\taction?: React.ReactNode;\n}\n\n/**\n * Banner component for surfacing important updates or CTAs.\n *\n * Uses the 24-column grid system - must be placed inside a `grid-container`.\n * Spans full width with `col-full`.\n *\n * Responsive across breakpoints:\n * - Mobile: Stacked layout with smaller padding\n * - Tablet: Horizontal layout with medium padding\n * - Desktop: Horizontal layout with larger padding\n *\n * @example\n * ```tsx\n * <div className=\"grid-container\">\n * <Banner\n * heading=\"Important Update\"\n * description=\"Check out our new features.\"\n * action={<Button>Learn More</Button>}\n * />\n * </div>\n *\n * // Dark colorScheme\n * <Banner\n * colorScheme=\"dark\"\n * heading=\"Still Have Questions?\"\n * description=\"Contact us at support@example.com\"\n * action={<Button variant=\"secondary\">Email Us</Button>}\n * />\n * ```\n */\nconst Banner = React.forwardRef<HTMLElement, BannerProps>(\n\t({ className, colorScheme, heading, description, action, ...props }, ref) => {\n\t\treturn (\n\t\t\t<section\n\t\t\t\tref={ref}\n\t\t\t\tclassName={bannerVariants({ colorScheme, class: className })}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t{/* Inner container with border-top for dark colorScheme */}\n\t\t\t\t<div\n\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t// Uses primitive spacing tokens\n\t\t\t\t\t\t\"flex flex-col md:flex-row gap-20 items-start md:items-center md:justify-between\",\n\t\t\t\t\t\tcolorScheme === \"dark\" && \"border-t border-gray-700 py-36\",\n\t\t\t\t\t)}\n\t\t\t\t>\n\t\t\t\t\t{/* Copy section */}\n\t\t\t\t\t<div className=\"flex flex-col gap-6 items-start\">\n\t\t\t\t\t\t<h2\n\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\"typography-subheading-small\",\n\t\t\t\t\t\t\t\tcolorScheme === \"dark\" ? \"text-gray-100\" : \"text-gray-900\",\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{heading}\n\t\t\t\t\t\t</h2>\n\t\t\t\t\t\t<p\n\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\"typography-body-small\",\n\t\t\t\t\t\t\t\tcolorScheme === \"dark\" ? \"text-gray-500\" : \"text-gray-800\",\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{description}\n\t\t\t\t\t\t</p>\n\t\t\t\t\t</div>\n\t\t\t\t\t{/* Action slot */}\n\t\t\t\t\t{action}\n\t\t\t\t</div>\n\t\t\t</section>\n\t\t);\n\t},\n);\nBanner.displayName = \"Banner\";\n\nexport { Banner, bannerVariants };\n"]}
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
import * as tailwind_variants from 'tailwind-variants';
|
|
2
|
+
import { VariantProps } from 'tailwind-variants';
|
|
3
|
+
import * as tailwind_variants_dist_config_js from 'tailwind-variants/dist/config.js';
|
|
4
|
+
import * as React from 'react';
|
|
5
|
+
|
|
6
|
+
type BlurIntensity = "low" | "medium" | "high" | "extreme";
|
|
7
|
+
type OverlayType = "none" | "vignette" | "top-bottom";
|
|
8
|
+
/**
|
|
9
|
+
* Blurred video backdrop wrapper variants.
|
|
10
|
+
*
|
|
11
|
+
* The wrapper extends beyond its bounds (inset: -120px) to cover
|
|
12
|
+
* blur artifacts at the edges.
|
|
13
|
+
*/
|
|
14
|
+
declare const blurredVideoBackdropVariants: tailwind_variants.TVReturnType<{
|
|
15
|
+
/**
|
|
16
|
+
* Blur intensity level.
|
|
17
|
+
* Higher values provide more diffused backgrounds.
|
|
18
|
+
*/
|
|
19
|
+
blur: {
|
|
20
|
+
low: string;
|
|
21
|
+
medium: string;
|
|
22
|
+
high: string;
|
|
23
|
+
extreme: string;
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Gradient overlay for visual depth.
|
|
27
|
+
*/
|
|
28
|
+
overlay: {
|
|
29
|
+
none: string;
|
|
30
|
+
vignette: string;
|
|
31
|
+
"top-bottom": string;
|
|
32
|
+
};
|
|
33
|
+
}, undefined, string[], tailwind_variants_dist_config_js.TVConfig<{
|
|
34
|
+
/**
|
|
35
|
+
* Blur intensity level.
|
|
36
|
+
* Higher values provide more diffused backgrounds.
|
|
37
|
+
*/
|
|
38
|
+
blur: {
|
|
39
|
+
low: string;
|
|
40
|
+
medium: string;
|
|
41
|
+
high: string;
|
|
42
|
+
extreme: string;
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* Gradient overlay for visual depth.
|
|
46
|
+
*/
|
|
47
|
+
overlay: {
|
|
48
|
+
none: string;
|
|
49
|
+
vignette: string;
|
|
50
|
+
"top-bottom": string;
|
|
51
|
+
};
|
|
52
|
+
}, {
|
|
53
|
+
/**
|
|
54
|
+
* Blur intensity level.
|
|
55
|
+
* Higher values provide more diffused backgrounds.
|
|
56
|
+
*/
|
|
57
|
+
blur: {
|
|
58
|
+
low: string;
|
|
59
|
+
medium: string;
|
|
60
|
+
high: string;
|
|
61
|
+
extreme: string;
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* Gradient overlay for visual depth.
|
|
65
|
+
*/
|
|
66
|
+
overlay: {
|
|
67
|
+
none: string;
|
|
68
|
+
vignette: string;
|
|
69
|
+
"top-bottom": string;
|
|
70
|
+
};
|
|
71
|
+
}>, {
|
|
72
|
+
/**
|
|
73
|
+
* Blur intensity level.
|
|
74
|
+
* Higher values provide more diffused backgrounds.
|
|
75
|
+
*/
|
|
76
|
+
blur: {
|
|
77
|
+
low: string;
|
|
78
|
+
medium: string;
|
|
79
|
+
high: string;
|
|
80
|
+
extreme: string;
|
|
81
|
+
};
|
|
82
|
+
/**
|
|
83
|
+
* Gradient overlay for visual depth.
|
|
84
|
+
*/
|
|
85
|
+
overlay: {
|
|
86
|
+
none: string;
|
|
87
|
+
vignette: string;
|
|
88
|
+
"top-bottom": string;
|
|
89
|
+
};
|
|
90
|
+
}, undefined, tailwind_variants.TVReturnType<{
|
|
91
|
+
/**
|
|
92
|
+
* Blur intensity level.
|
|
93
|
+
* Higher values provide more diffused backgrounds.
|
|
94
|
+
*/
|
|
95
|
+
blur: {
|
|
96
|
+
low: string;
|
|
97
|
+
medium: string;
|
|
98
|
+
high: string;
|
|
99
|
+
extreme: string;
|
|
100
|
+
};
|
|
101
|
+
/**
|
|
102
|
+
* Gradient overlay for visual depth.
|
|
103
|
+
*/
|
|
104
|
+
overlay: {
|
|
105
|
+
none: string;
|
|
106
|
+
vignette: string;
|
|
107
|
+
"top-bottom": string;
|
|
108
|
+
};
|
|
109
|
+
}, undefined, string[], tailwind_variants_dist_config_js.TVConfig<{
|
|
110
|
+
/**
|
|
111
|
+
* Blur intensity level.
|
|
112
|
+
* Higher values provide more diffused backgrounds.
|
|
113
|
+
*/
|
|
114
|
+
blur: {
|
|
115
|
+
low: string;
|
|
116
|
+
medium: string;
|
|
117
|
+
high: string;
|
|
118
|
+
extreme: string;
|
|
119
|
+
};
|
|
120
|
+
/**
|
|
121
|
+
* Gradient overlay for visual depth.
|
|
122
|
+
*/
|
|
123
|
+
overlay: {
|
|
124
|
+
none: string;
|
|
125
|
+
vignette: string;
|
|
126
|
+
"top-bottom": string;
|
|
127
|
+
};
|
|
128
|
+
}, {
|
|
129
|
+
/**
|
|
130
|
+
* Blur intensity level.
|
|
131
|
+
* Higher values provide more diffused backgrounds.
|
|
132
|
+
*/
|
|
133
|
+
blur: {
|
|
134
|
+
low: string;
|
|
135
|
+
medium: string;
|
|
136
|
+
high: string;
|
|
137
|
+
extreme: string;
|
|
138
|
+
};
|
|
139
|
+
/**
|
|
140
|
+
* Gradient overlay for visual depth.
|
|
141
|
+
*/
|
|
142
|
+
overlay: {
|
|
143
|
+
none: string;
|
|
144
|
+
vignette: string;
|
|
145
|
+
"top-bottom": string;
|
|
146
|
+
};
|
|
147
|
+
}>, unknown, unknown, undefined>>;
|
|
148
|
+
/**
|
|
149
|
+
* Canvas element styles.
|
|
150
|
+
*/
|
|
151
|
+
declare const canvasVariants: tailwind_variants.TVReturnType<{} | {} | {}, undefined, string[], tailwind_variants_dist_config_js.TVConfig<unknown, {} | {}>, {} | {}, undefined, tailwind_variants.TVReturnType<unknown, undefined, string[], tailwind_variants_dist_config_js.TVConfig<unknown, {} | {}>, unknown, unknown, undefined>>;
|
|
152
|
+
/**
|
|
153
|
+
* Gradient overlay base styles.
|
|
154
|
+
* Gradient backgrounds are applied via inline styles to avoid arbitrary values.
|
|
155
|
+
*/
|
|
156
|
+
declare const gradientOverlayVariants: tailwind_variants.TVReturnType<{} | {} | {}, undefined, string[], tailwind_variants_dist_config_js.TVConfig<unknown, {} | {}>, {} | {}, undefined, tailwind_variants.TVReturnType<unknown, undefined, string[], tailwind_variants_dist_config_js.TVConfig<unknown, {} | {}>, unknown, unknown, undefined>>;
|
|
157
|
+
declare const BLUR_AMOUNTS: Record<BlurIntensity, number>;
|
|
158
|
+
interface UseCanvasBlurOptions {
|
|
159
|
+
/** Ref to the source video element */
|
|
160
|
+
videoRef: React.RefObject<HTMLVideoElement | null>;
|
|
161
|
+
/** Blur amount in pixels */
|
|
162
|
+
blurAmount: number;
|
|
163
|
+
/** Whether rendering is enabled */
|
|
164
|
+
enabled?: boolean;
|
|
165
|
+
/** Target FPS (lower = better performance, default: 30) */
|
|
166
|
+
targetFps?: number;
|
|
167
|
+
/** Canvas scale factor (lower = better performance, default: 0.5) */
|
|
168
|
+
scale?: number;
|
|
169
|
+
}
|
|
170
|
+
interface UseCanvasBlurReturn {
|
|
171
|
+
/** Ref to attach to the canvas element */
|
|
172
|
+
canvasRef: React.RefObject<HTMLCanvasElement | null>;
|
|
173
|
+
/** Whether the canvas is currently rendering */
|
|
174
|
+
isRendering: boolean;
|
|
175
|
+
/** Performance metrics */
|
|
176
|
+
metrics: {
|
|
177
|
+
fps: number;
|
|
178
|
+
frameTime: number;
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Hook for rendering a blurred video to canvas.
|
|
183
|
+
*
|
|
184
|
+
* Performance optimizations:
|
|
185
|
+
* - Renders at reduced resolution (scale factor)
|
|
186
|
+
* - Throttled to target FPS
|
|
187
|
+
* - Uses CSS scale to fill container
|
|
188
|
+
* - Single video decoder (no sync needed)
|
|
189
|
+
*/
|
|
190
|
+
declare function useCanvasBlur({ videoRef, blurAmount, enabled, targetFps, scale, }: UseCanvasBlurOptions): UseCanvasBlurReturn;
|
|
191
|
+
interface BlurredVideoBackdropProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "children">, VariantProps<typeof blurredVideoBackdropVariants> {
|
|
192
|
+
/** Ref to the primary video element to create backdrop from (required) */
|
|
193
|
+
videoRef: React.RefObject<HTMLVideoElement | null>;
|
|
194
|
+
/** Opacity of the backdrop (0-1, default: 0.6) */
|
|
195
|
+
opacity?: number;
|
|
196
|
+
/** Extension amount in pixels to cover blur artifacts (default: 120) */
|
|
197
|
+
extension?: number;
|
|
198
|
+
/** Target FPS for canvas rendering (default: 30) */
|
|
199
|
+
targetFps?: number;
|
|
200
|
+
/** Canvas scale factor - lower = better performance (default: 0.5) */
|
|
201
|
+
scale?: number;
|
|
202
|
+
/** Whether to show debug metrics */
|
|
203
|
+
showMetrics?: boolean;
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* BlurredVideoBackdrop - A high-performance blurred video backdrop using canvas.
|
|
207
|
+
*
|
|
208
|
+
* Renders a blurred copy of a video element to create an ambient backdrop effect.
|
|
209
|
+
* Uses canvas rendering for optimal performance - no video sync needed.
|
|
210
|
+
*
|
|
211
|
+
* Performance features:
|
|
212
|
+
* - Single video decoder (draws from existing video element)
|
|
213
|
+
* - Reduced resolution rendering (configurable scale)
|
|
214
|
+
* - Throttled frame rate (configurable FPS)
|
|
215
|
+
* - GPU-accelerated canvas scaling
|
|
216
|
+
*
|
|
217
|
+
* @example
|
|
218
|
+
* ```tsx
|
|
219
|
+
* const videoRef = useRef<HTMLVideoElement>(null);
|
|
220
|
+
*
|
|
221
|
+
* <div className="relative">
|
|
222
|
+
* <BlurredVideoBackdrop
|
|
223
|
+
* videoRef={videoRef}
|
|
224
|
+
* blur="high"
|
|
225
|
+
* overlay="vignette"
|
|
226
|
+
* />
|
|
227
|
+
* <VideoPlayer videoRef={videoRef} src="/video.mp4" />
|
|
228
|
+
* </div>
|
|
229
|
+
* ```
|
|
230
|
+
*/
|
|
231
|
+
declare const BlurredVideoBackdrop: React.ForwardRefExoticComponent<BlurredVideoBackdropProps & React.RefAttributes<HTMLDivElement>>;
|
|
232
|
+
|
|
233
|
+
export { BLUR_AMOUNTS, type BlurIntensity, BlurredVideoBackdrop, type BlurredVideoBackdropProps, type OverlayType, type UseCanvasBlurOptions, type UseCanvasBlurReturn, blurredVideoBackdropVariants, canvasVariants, gradientOverlayVariants, useCanvasBlur };
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import { tv, cnBase } from 'tailwind-variants';
|
|
4
|
+
import { clsx } from 'clsx';
|
|
5
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
6
|
+
|
|
7
|
+
// src/components/atoms/blurred-video-backdrop/blurred-video-backdrop.tsx
|
|
8
|
+
function cn(...inputs) {
|
|
9
|
+
return cnBase(clsx(inputs));
|
|
10
|
+
}
|
|
11
|
+
var blurredVideoBackdropVariants = tv({
|
|
12
|
+
base: [
|
|
13
|
+
"absolute",
|
|
14
|
+
"pointer-events-none",
|
|
15
|
+
"select-none",
|
|
16
|
+
"will-change-contents",
|
|
17
|
+
"transform-gpu"
|
|
18
|
+
],
|
|
19
|
+
variants: {
|
|
20
|
+
/**
|
|
21
|
+
* Blur intensity level.
|
|
22
|
+
* Higher values provide more diffused backgrounds.
|
|
23
|
+
*/
|
|
24
|
+
blur: {
|
|
25
|
+
low: "",
|
|
26
|
+
medium: "",
|
|
27
|
+
high: "",
|
|
28
|
+
extreme: ""
|
|
29
|
+
},
|
|
30
|
+
/**
|
|
31
|
+
* Gradient overlay for visual depth.
|
|
32
|
+
*/
|
|
33
|
+
overlay: {
|
|
34
|
+
none: "",
|
|
35
|
+
vignette: "",
|
|
36
|
+
"top-bottom": ""
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
defaultVariants: {
|
|
40
|
+
blur: "high",
|
|
41
|
+
overlay: "none"
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
var canvasVariants = tv({
|
|
45
|
+
base: ["w-full", "h-full", "object-cover"]
|
|
46
|
+
});
|
|
47
|
+
var gradientOverlayVariants = tv({
|
|
48
|
+
base: ["absolute", "inset-0", "pointer-events-none"]
|
|
49
|
+
});
|
|
50
|
+
var OVERLAY_GRADIENTS = {
|
|
51
|
+
vignette: "radial-gradient(ellipse at center, transparent 40%, rgba(0, 0, 0, 0.4) 100%)",
|
|
52
|
+
"top-bottom": "linear-gradient(180deg, rgba(0, 0, 0, 0.4) 0%, transparent 30%, transparent 70%, rgba(0, 0, 0, 0.4) 100%)"
|
|
53
|
+
};
|
|
54
|
+
var BLUR_AMOUNTS = {
|
|
55
|
+
low: 40,
|
|
56
|
+
medium: 80,
|
|
57
|
+
high: 100,
|
|
58
|
+
extreme: 120
|
|
59
|
+
};
|
|
60
|
+
function useCanvasBlur({
|
|
61
|
+
videoRef,
|
|
62
|
+
blurAmount,
|
|
63
|
+
enabled = true,
|
|
64
|
+
targetFps = 30,
|
|
65
|
+
scale = 0.5
|
|
66
|
+
}) {
|
|
67
|
+
const canvasRef = React.useRef(null);
|
|
68
|
+
const ctxRef = React.useRef(null);
|
|
69
|
+
const [isRendering, setIsRendering] = React.useState(false);
|
|
70
|
+
const [metrics, setMetrics] = React.useState({ fps: 0, frameTime: 0 });
|
|
71
|
+
const [videoReady, setVideoReady] = React.useState(false);
|
|
72
|
+
const lastFrameTimeRef = React.useRef(0);
|
|
73
|
+
const frameCountRef = React.useRef(0);
|
|
74
|
+
const fpsIntervalRef = React.useRef(0);
|
|
75
|
+
const frameInterval = 1e3 / targetFps;
|
|
76
|
+
React.useEffect(() => {
|
|
77
|
+
if (!enabled) return;
|
|
78
|
+
const checkRef = () => {
|
|
79
|
+
if (videoRef.current && canvasRef.current) {
|
|
80
|
+
setVideoReady(true);
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
checkRef();
|
|
84
|
+
const frameId = requestAnimationFrame(checkRef);
|
|
85
|
+
const timeoutId = setTimeout(checkRef, 100);
|
|
86
|
+
const timeoutId2 = setTimeout(checkRef, 500);
|
|
87
|
+
return () => {
|
|
88
|
+
cancelAnimationFrame(frameId);
|
|
89
|
+
clearTimeout(timeoutId);
|
|
90
|
+
clearTimeout(timeoutId2);
|
|
91
|
+
};
|
|
92
|
+
}, [enabled, videoRef]);
|
|
93
|
+
React.useEffect(() => {
|
|
94
|
+
if (!enabled || !videoReady) return;
|
|
95
|
+
const video = videoRef.current;
|
|
96
|
+
const canvas = canvasRef.current;
|
|
97
|
+
if (!video || !canvas) return;
|
|
98
|
+
const ctx = canvas.getContext("2d", {
|
|
99
|
+
alpha: false,
|
|
100
|
+
desynchronized: true
|
|
101
|
+
// Reduces latency
|
|
102
|
+
});
|
|
103
|
+
if (!ctx) return;
|
|
104
|
+
ctxRef.current = ctx;
|
|
105
|
+
let animationFrameId;
|
|
106
|
+
let isActive = true;
|
|
107
|
+
const updateCanvasSize = () => {
|
|
108
|
+
if (video.videoWidth && video.videoHeight) {
|
|
109
|
+
canvas.width = Math.floor(video.videoWidth * scale);
|
|
110
|
+
canvas.height = Math.floor(video.videoHeight * scale);
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
const render = (timestamp) => {
|
|
114
|
+
if (!isActive || !video || !ctx) return;
|
|
115
|
+
const elapsed = timestamp - lastFrameTimeRef.current;
|
|
116
|
+
if (elapsed >= frameInterval) {
|
|
117
|
+
const frameStart = performance.now();
|
|
118
|
+
if (canvas.width === 0 || canvas.height === 0) {
|
|
119
|
+
updateCanvasSize();
|
|
120
|
+
}
|
|
121
|
+
if (video.readyState >= 2 && !video.paused) {
|
|
122
|
+
ctx.filter = `blur(${blurAmount * scale}px)`;
|
|
123
|
+
ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
|
|
124
|
+
setIsRendering(true);
|
|
125
|
+
}
|
|
126
|
+
const frameTime = performance.now() - frameStart;
|
|
127
|
+
frameCountRef.current++;
|
|
128
|
+
if (timestamp - fpsIntervalRef.current >= 1e3) {
|
|
129
|
+
setMetrics({
|
|
130
|
+
fps: frameCountRef.current,
|
|
131
|
+
frameTime: Math.round(frameTime * 100) / 100
|
|
132
|
+
});
|
|
133
|
+
frameCountRef.current = 0;
|
|
134
|
+
fpsIntervalRef.current = timestamp;
|
|
135
|
+
}
|
|
136
|
+
lastFrameTimeRef.current = timestamp - elapsed % frameInterval;
|
|
137
|
+
}
|
|
138
|
+
animationFrameId = requestAnimationFrame(render);
|
|
139
|
+
};
|
|
140
|
+
const handleLoadedMetadata = () => {
|
|
141
|
+
updateCanvasSize();
|
|
142
|
+
};
|
|
143
|
+
const handlePlay = () => {
|
|
144
|
+
if (isActive) {
|
|
145
|
+
animationFrameId = requestAnimationFrame(render);
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
const handlePause = () => {
|
|
149
|
+
setIsRendering(false);
|
|
150
|
+
};
|
|
151
|
+
video.addEventListener("loadedmetadata", handleLoadedMetadata);
|
|
152
|
+
video.addEventListener("play", handlePlay);
|
|
153
|
+
video.addEventListener("pause", handlePause);
|
|
154
|
+
if (video.readyState >= 1) {
|
|
155
|
+
updateCanvasSize();
|
|
156
|
+
}
|
|
157
|
+
if (!video.paused) {
|
|
158
|
+
animationFrameId = requestAnimationFrame(render);
|
|
159
|
+
}
|
|
160
|
+
return () => {
|
|
161
|
+
isActive = false;
|
|
162
|
+
cancelAnimationFrame(animationFrameId);
|
|
163
|
+
video.removeEventListener("loadedmetadata", handleLoadedMetadata);
|
|
164
|
+
video.removeEventListener("play", handlePlay);
|
|
165
|
+
video.removeEventListener("pause", handlePause);
|
|
166
|
+
setIsRendering(false);
|
|
167
|
+
};
|
|
168
|
+
}, [enabled, videoReady, videoRef, blurAmount, frameInterval, scale]);
|
|
169
|
+
return {
|
|
170
|
+
canvasRef,
|
|
171
|
+
isRendering,
|
|
172
|
+
metrics
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
var BlurredVideoBackdrop = React.forwardRef(
|
|
176
|
+
({
|
|
177
|
+
className,
|
|
178
|
+
videoRef,
|
|
179
|
+
blur = "high",
|
|
180
|
+
overlay = "none",
|
|
181
|
+
opacity = 0.6,
|
|
182
|
+
extension = 120,
|
|
183
|
+
targetFps = 30,
|
|
184
|
+
scale = 0.5,
|
|
185
|
+
showMetrics = false,
|
|
186
|
+
style,
|
|
187
|
+
...props
|
|
188
|
+
}, ref) => {
|
|
189
|
+
const blurAmount = BLUR_AMOUNTS[blur ?? "high"];
|
|
190
|
+
const { canvasRef, isRendering, metrics } = useCanvasBlur({
|
|
191
|
+
videoRef,
|
|
192
|
+
blurAmount,
|
|
193
|
+
enabled: true,
|
|
194
|
+
targetFps,
|
|
195
|
+
scale
|
|
196
|
+
});
|
|
197
|
+
return /* @__PURE__ */ jsxs(
|
|
198
|
+
"div",
|
|
199
|
+
{
|
|
200
|
+
ref,
|
|
201
|
+
className: cn(
|
|
202
|
+
blurredVideoBackdropVariants({ blur, overlay }),
|
|
203
|
+
className
|
|
204
|
+
),
|
|
205
|
+
style: {
|
|
206
|
+
inset: `-${extension}px`,
|
|
207
|
+
opacity,
|
|
208
|
+
contain: "layout style paint",
|
|
209
|
+
...style
|
|
210
|
+
},
|
|
211
|
+
"data-blur": blur ?? "high",
|
|
212
|
+
"data-overlay": overlay ?? "none",
|
|
213
|
+
"data-rendering": isRendering,
|
|
214
|
+
"aria-hidden": "true",
|
|
215
|
+
...props,
|
|
216
|
+
children: [
|
|
217
|
+
/* @__PURE__ */ jsx(
|
|
218
|
+
"canvas",
|
|
219
|
+
{
|
|
220
|
+
ref: canvasRef,
|
|
221
|
+
className: cn(
|
|
222
|
+
canvasVariants(),
|
|
223
|
+
// Scale up the low-res canvas to fill container
|
|
224
|
+
"scale-[2]",
|
|
225
|
+
// Inverse of 0.5 scale factor
|
|
226
|
+
"origin-center"
|
|
227
|
+
),
|
|
228
|
+
style: {
|
|
229
|
+
// Additional CSS blur for smoother appearance
|
|
230
|
+
filter: `blur(${blurAmount * 0.3}px)`
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
),
|
|
234
|
+
overlay && overlay !== "none" && /* @__PURE__ */ jsx(
|
|
235
|
+
"div",
|
|
236
|
+
{
|
|
237
|
+
className: gradientOverlayVariants(),
|
|
238
|
+
style: { background: OVERLAY_GRADIENTS[overlay] }
|
|
239
|
+
}
|
|
240
|
+
),
|
|
241
|
+
showMetrics && /* @__PURE__ */ jsxs("div", { className: "absolute bottom-8 left-8 z-10 bg-black/80 text-white typography-caption px-8 py-4 rounded-4 font-mono", children: [
|
|
242
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
243
|
+
"FPS: ",
|
|
244
|
+
metrics.fps
|
|
245
|
+
] }),
|
|
246
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
247
|
+
"Frame: ",
|
|
248
|
+
metrics.frameTime,
|
|
249
|
+
"ms"
|
|
250
|
+
] }),
|
|
251
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
252
|
+
"Scale: ",
|
|
253
|
+
scale,
|
|
254
|
+
"x"
|
|
255
|
+
] })
|
|
256
|
+
] })
|
|
257
|
+
]
|
|
258
|
+
}
|
|
259
|
+
);
|
|
260
|
+
}
|
|
261
|
+
);
|
|
262
|
+
BlurredVideoBackdrop.displayName = "BlurredVideoBackdrop";
|
|
263
|
+
|
|
264
|
+
export { BLUR_AMOUNTS, BlurredVideoBackdrop, blurredVideoBackdropVariants, canvasVariants, gradientOverlayVariants, useCanvasBlur };
|
|
265
|
+
//# sourceMappingURL=index.js.map
|
|
266
|
+
//# sourceMappingURL=index.js.map
|