@bccampus/ui-components 0.1.0 → 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.
- package/dist/banner.d.ts +16 -0
- package/dist/banner.js +42 -0
- package/dist/button.d.ts +5 -4
- package/dist/button.js +24 -18
- package/dist/caption.js +7 -7
- package/dist/card.d.ts +15 -9
- package/dist/card.js +64 -86
- package/dist/createLucideIcon-CzehbSja.js +94 -0
- package/dist/horizontal-list.d.ts +9 -2
- package/dist/horizontal-list.js +46 -114
- package/dist/icon-generator.d.ts +2 -1
- package/dist/icon-generator.js +183 -150
- package/dist/index-CQhYMnjT.js +34 -0
- package/dist/index-U7DVCmS_.js +76 -0
- package/dist/input.d.ts +7 -0
- package/dist/input.js +18 -0
- package/dist/masked-image-generator.d.ts +1 -0
- package/dist/masked-image-generator.js +18 -18
- package/dist/navigation-menu.d.ts +27 -0
- package/dist/navigation-menu.js +1139 -0
- package/dist/overlay.d.ts +13 -0
- package/dist/overlay.js +27 -0
- package/dist/page-header.d.ts +9 -0
- package/dist/page-header.js +944 -0
- package/dist/page-section.d.ts +14 -0
- package/dist/page-section.js +31 -0
- package/dist/page.d.ts +7 -0
- package/dist/page.js +8 -0
- package/dist/search-input.d.ts +7 -0
- package/dist/search-input.js +23 -0
- package/dist/tag.d.ts +2 -2
- package/dist/tag.js +7 -7
- package/dist/ui-components.d.ts +112 -29
- package/dist/ui-components.js +51 -26
- package/package.json +49 -15
- package/src/assets/images/image_06.jpg +0 -0
- package/src/components/ui/banner.tsx +48 -0
- package/src/components/ui/button.tsx +53 -47
- package/src/components/ui/card.tsx +131 -147
- package/src/components/ui/horizontal-list.tsx +75 -50
- package/src/components/ui/icon-generator/generate-tiles.tsx +243 -243
- package/src/components/ui/icon-generator/icon-generator.tsx +84 -51
- package/src/components/ui/icon-generator/masked-image-generator.tsx +38 -38
- package/src/components/ui/icon-generator/types.ts +53 -52
- package/src/components/ui/index.ts +12 -4
- package/src/components/ui/input.tsx +17 -0
- package/src/components/ui/navigation-menu.tsx +165 -0
- package/src/components/ui/overlay.tsx +29 -0
- package/src/components/ui/page-header.tsx +24 -0
- package/src/components/ui/page-section.tsx +33 -0
- package/src/components/ui/page.tsx +11 -0
- package/src/components/ui/search-input.tsx +16 -0
- package/src/components/ui/tag.tsx +39 -39
- package/src/components/ui/typography/caption.tsx +32 -32
- package/src/styles/all.css +4 -4
- package/src/styles/colors.css +9 -10
- package/src/styles/index.css +7 -7
- package/src/styles/theme.css +57 -3
- package/src/styles/typography.css +473 -479
- package/tsconfig.app.json +37 -37
- package/vite.config.ts +53 -44
- package/vite.ladle.config.ts +17 -0
- package/dist/@bccampus-ui-components-0.1.0.tgz +0 -0
- package/dist/index-DcqAdr0d.js +0 -102
- package/dist/jsx-runtime-BzflLqGi.js +0 -282
- package/dist/mockServiceWorker.js +0 -348
- package/public/mockServiceWorker.js +0 -348
- package/src/assets/images/bg_pattern_01.png +0 -0
- package/src/assets/images/bg_pattern_02.png +0 -0
- package/src/assets/images/bg_pattern_03.png +0 -0
- package/src/assets/images/bg_pattern_04.png +0 -0
|
@@ -1,38 +1,38 @@
|
|
|
1
|
-
import { useId, useMemo } from "react";
|
|
2
|
-
import type { MaskedImageGeneratorProps } from "./types";
|
|
3
|
-
|
|
4
|
-
import { IconGenerator } from "./icon-generator";
|
|
5
|
-
|
|
6
|
-
const MaskedImageFit = { cover: "slice", contain: "meet", fill: "none" };
|
|
7
|
-
const MaskedImagePosition = { top: "xMidYMin", center: "xMidYMid", bottom: "xMidYMax" };
|
|
8
|
-
|
|
9
|
-
function MaskedImageGenerator({
|
|
10
|
-
src,
|
|
11
|
-
imageFit = "cover",
|
|
12
|
-
imagePosition = "top",
|
|
13
|
-
maskType = "alpha",
|
|
14
|
-
...props
|
|
15
|
-
}: MaskedImageGeneratorProps) {
|
|
16
|
-
const id = useId();
|
|
17
|
-
|
|
18
|
-
const aspectRatio = useMemo(
|
|
19
|
-
() => (imageFit !== "fill" ? `${MaskedImagePosition[imagePosition]} ${MaskedImageFit[imageFit]}` : "none"),
|
|
20
|
-
[imageFit, imagePosition]
|
|
21
|
-
);
|
|
22
|
-
|
|
23
|
-
return (
|
|
24
|
-
<IconGenerator
|
|
25
|
-
{...props}
|
|
26
|
-
renderChildren={(paths) => (
|
|
27
|
-
<>
|
|
28
|
-
<mask id={`svg-mask${id}`} mask-type={maskType}>
|
|
29
|
-
{paths}
|
|
30
|
-
</mask>
|
|
31
|
-
<image href={src} width="100%" height="100%" mask={`url(#svg-mask${id})`} preserveAspectRatio={aspectRatio} />
|
|
32
|
-
</>
|
|
33
|
-
)}
|
|
34
|
-
/>
|
|
35
|
-
);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
export { MaskedImageGenerator };
|
|
1
|
+
import { useId, useMemo } from "react";
|
|
2
|
+
import type { MaskedImageGeneratorProps } from "./types";
|
|
3
|
+
|
|
4
|
+
import { IconGenerator } from "./icon-generator";
|
|
5
|
+
|
|
6
|
+
const MaskedImageFit = { cover: "slice", contain: "meet", fill: "none" };
|
|
7
|
+
const MaskedImagePosition = { top: "xMidYMin", center: "xMidYMid", bottom: "xMidYMax" };
|
|
8
|
+
|
|
9
|
+
function MaskedImageGenerator({
|
|
10
|
+
src,
|
|
11
|
+
imageFit = "cover",
|
|
12
|
+
imagePosition = "top",
|
|
13
|
+
maskType = "alpha",
|
|
14
|
+
...props
|
|
15
|
+
}: MaskedImageGeneratorProps) {
|
|
16
|
+
const id = useId();
|
|
17
|
+
|
|
18
|
+
const aspectRatio = useMemo(
|
|
19
|
+
() => (imageFit !== "fill" ? `${MaskedImagePosition[imagePosition]} ${MaskedImageFit[imageFit]}` : "none"),
|
|
20
|
+
[imageFit, imagePosition]
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
return (
|
|
24
|
+
<IconGenerator
|
|
25
|
+
{...props}
|
|
26
|
+
renderChildren={(paths) => (
|
|
27
|
+
<>
|
|
28
|
+
<mask id={`svg-mask${id}`} mask-type={maskType}>
|
|
29
|
+
{paths}
|
|
30
|
+
</mask>
|
|
31
|
+
<image href={src} width="100%" height="100%" mask={`url(#svg-mask${id})`} preserveAspectRatio={aspectRatio} />
|
|
32
|
+
</>
|
|
33
|
+
)}
|
|
34
|
+
/>
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export { MaskedImageGenerator };
|
|
@@ -1,53 +1,54 @@
|
|
|
1
|
-
import type { JSX } from "react";
|
|
2
|
-
|
|
3
|
-
export const TileShape = {
|
|
4
|
-
Blank: 0,
|
|
5
|
-
Rand: 1,
|
|
6
|
-
Mosaic: 2,
|
|
7
|
-
MosaicCircle: 3,
|
|
8
|
-
MosaicDiamond: 4,
|
|
9
|
-
Square: 6,
|
|
10
|
-
Circle: 7,
|
|
11
|
-
Diamond: 8,
|
|
12
|
-
Hexagon: 9,
|
|
13
|
-
RandBasic: 10,
|
|
14
|
-
TriangleSE: 11,
|
|
15
|
-
TriangleSW: 12,
|
|
16
|
-
TriangleNW: 13,
|
|
17
|
-
TriangleNE: 14,
|
|
18
|
-
TriangleRand: 15,
|
|
19
|
-
CaretN: 16,
|
|
20
|
-
CaretE: 17,
|
|
21
|
-
CaretS: 18,
|
|
22
|
-
CaretW: 19,
|
|
23
|
-
CaretRand: 20,
|
|
24
|
-
PieSE: 21,
|
|
25
|
-
PieSW: 22,
|
|
26
|
-
PieNW: 23,
|
|
27
|
-
PieNE: 24,
|
|
28
|
-
PieRand: 25,
|
|
29
|
-
} as const;
|
|
30
|
-
|
|
31
|
-
export type TileShape = (typeof TileShape)[keyof typeof TileShape];
|
|
32
|
-
|
|
33
|
-
export interface TileConfig {
|
|
34
|
-
shape: TileShape;
|
|
35
|
-
scale?: number;
|
|
36
|
-
className?: string;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export interface IconGeneratorProps extends Omit<React.ComponentProps<"svg">, "children" | "width" | "height" | "overflow"> {
|
|
40
|
-
pattern?: (TileShape | TileConfig)[][];
|
|
41
|
-
tileSize?: number;
|
|
42
|
-
tileClassName?: string;
|
|
43
|
-
tileBgClassName?: string;
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
1
|
+
import type { JSX } from "react";
|
|
2
|
+
|
|
3
|
+
export const TileShape = {
|
|
4
|
+
Blank: 0,
|
|
5
|
+
Rand: 1,
|
|
6
|
+
Mosaic: 2,
|
|
7
|
+
MosaicCircle: 3,
|
|
8
|
+
MosaicDiamond: 4,
|
|
9
|
+
Square: 6,
|
|
10
|
+
Circle: 7,
|
|
11
|
+
Diamond: 8,
|
|
12
|
+
Hexagon: 9,
|
|
13
|
+
RandBasic: 10,
|
|
14
|
+
TriangleSE: 11,
|
|
15
|
+
TriangleSW: 12,
|
|
16
|
+
TriangleNW: 13,
|
|
17
|
+
TriangleNE: 14,
|
|
18
|
+
TriangleRand: 15,
|
|
19
|
+
CaretN: 16,
|
|
20
|
+
CaretE: 17,
|
|
21
|
+
CaretS: 18,
|
|
22
|
+
CaretW: 19,
|
|
23
|
+
CaretRand: 20,
|
|
24
|
+
PieSE: 21,
|
|
25
|
+
PieSW: 22,
|
|
26
|
+
PieNW: 23,
|
|
27
|
+
PieNE: 24,
|
|
28
|
+
PieRand: 25,
|
|
29
|
+
} as const;
|
|
30
|
+
|
|
31
|
+
export type TileShape = (typeof TileShape)[keyof typeof TileShape];
|
|
32
|
+
|
|
33
|
+
export interface TileConfig {
|
|
34
|
+
shape: TileShape;
|
|
35
|
+
scale?: number;
|
|
36
|
+
className?: string;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export interface IconGeneratorProps extends Omit<React.ComponentProps<"svg">, "children" | "width" | "height" | "overflow"> {
|
|
40
|
+
pattern?: (TileShape | TileConfig)[][];
|
|
41
|
+
tileSize?: number;
|
|
42
|
+
tileClassName?: string;
|
|
43
|
+
tileBgClassName?: string;
|
|
44
|
+
fit?: "none" | "fill" | "width" | "height"
|
|
45
|
+
|
|
46
|
+
renderChildren?: (paths: (JSX.Element | null)[], width: number, height: number) => React.ReactNode;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export interface MaskedImageGeneratorProps extends IconGeneratorProps {
|
|
50
|
+
src: string;
|
|
51
|
+
imageFit?: "cover" | "contain" | "fill";
|
|
52
|
+
imagePosition?: "top" | "center" | "bottom";
|
|
53
|
+
maskType?: "alpha" | "luminance";
|
|
53
54
|
}
|
|
@@ -1,7 +1,15 @@
|
|
|
1
|
-
export * from './
|
|
1
|
+
export * from './icon-generator/icon-generator.tsx'
|
|
2
|
+
export * from './icon-generator/masked-image-generator.tsx'
|
|
2
3
|
export * from './typography/caption.tsx'
|
|
4
|
+
export * from './banner.tsx'
|
|
5
|
+
export * from './button.tsx'
|
|
3
6
|
export * from './card.tsx'
|
|
4
|
-
export * from './tag.tsx'
|
|
5
7
|
export * from './horizontal-list.tsx'
|
|
6
|
-
export * from './
|
|
7
|
-
export * from './
|
|
8
|
+
export * from './input.tsx'
|
|
9
|
+
export * from './navigation-menu.tsx'
|
|
10
|
+
export * from './overlay.tsx'
|
|
11
|
+
export * from './page-header.tsx'
|
|
12
|
+
export * from './page-section.tsx'
|
|
13
|
+
export * from './page.tsx'
|
|
14
|
+
export * from './search-input.tsx'
|
|
15
|
+
export * from './tag.tsx'
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { cn } from "@/lib/utils";
|
|
2
|
+
export type InputProps = React.ComponentProps<"input">;
|
|
3
|
+
|
|
4
|
+
function Input({ className, ...props }: InputProps) {
|
|
5
|
+
return (
|
|
6
|
+
<input
|
|
7
|
+
className={cn(
|
|
8
|
+
"w-full p-2 pr-8 text-brand-1 placeholder:text-brand-1 rounded-sm bg-complement-1-50 outline-none focus-visible:border-ring focus-visible:ring-ring focus-visible:ring-2",
|
|
9
|
+
className
|
|
10
|
+
)}
|
|
11
|
+
name="search"
|
|
12
|
+
{...props}
|
|
13
|
+
/>
|
|
14
|
+
);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export { Input };
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import * as NavigationMenuPrimitive from "@radix-ui/react-navigation-menu";
|
|
2
|
+
import { ChevronDownIcon } from "lucide-react";
|
|
3
|
+
|
|
4
|
+
import { cn } from "@/lib/utils";
|
|
5
|
+
import { buttonVariants } from "./button";
|
|
6
|
+
|
|
7
|
+
function NavigationMenu({
|
|
8
|
+
className,
|
|
9
|
+
children,
|
|
10
|
+
noViewport = false,
|
|
11
|
+
mega = false,
|
|
12
|
+
...props
|
|
13
|
+
}: React.ComponentProps<typeof NavigationMenuPrimitive.Root> & {
|
|
14
|
+
noViewport?: boolean;
|
|
15
|
+
mega?: boolean;
|
|
16
|
+
}) {
|
|
17
|
+
return (
|
|
18
|
+
<NavigationMenuPrimitive.Root
|
|
19
|
+
data-slot="navigation-menu"
|
|
20
|
+
data-mega={mega}
|
|
21
|
+
data-viewport={!noViewport || mega}
|
|
22
|
+
className={cn(
|
|
23
|
+
"group/navigation-menu flex max-w-max flex-1 items-center justify-center",
|
|
24
|
+
{ relative: !mega },
|
|
25
|
+
className
|
|
26
|
+
)}
|
|
27
|
+
{...props}
|
|
28
|
+
>
|
|
29
|
+
{children}
|
|
30
|
+
{(!noViewport || mega) && <NavigationMenuViewport mega={mega} />}
|
|
31
|
+
</NavigationMenuPrimitive.Root>
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function NavigationMenuList({ className, ...props }: React.ComponentProps<typeof NavigationMenuPrimitive.List>) {
|
|
36
|
+
return (
|
|
37
|
+
<NavigationMenuPrimitive.List
|
|
38
|
+
data-slot="navigation-menu-list"
|
|
39
|
+
className={cn("group flex flex-1 list-none items-center justify-center gap-1", className)}
|
|
40
|
+
{...props}
|
|
41
|
+
/>
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function NavigationMenuItem({ className, ...props }: React.ComponentProps<typeof NavigationMenuPrimitive.Item>) {
|
|
46
|
+
return (
|
|
47
|
+
<NavigationMenuPrimitive.Item data-slot="navigation-menu-item" className={cn("relative", className)} {...props} />
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const navigationMenuTriggerStyle = buttonVariants({
|
|
52
|
+
variant: "ghost",
|
|
53
|
+
className:
|
|
54
|
+
"data-[state=open]:hover:text-secondary data-[state=open]:focus:text-secondary data-[state=open]:text-secondary",
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
function NavigationMenuTrigger({
|
|
58
|
+
className,
|
|
59
|
+
children,
|
|
60
|
+
...props
|
|
61
|
+
}: React.ComponentProps<typeof NavigationMenuPrimitive.Trigger>) {
|
|
62
|
+
return (
|
|
63
|
+
<NavigationMenuPrimitive.Trigger
|
|
64
|
+
data-slot="navigation-menu-trigger"
|
|
65
|
+
className={cn(navigationMenuTriggerStyle, "group", className)}
|
|
66
|
+
{...props}
|
|
67
|
+
>
|
|
68
|
+
{children}{" "}
|
|
69
|
+
<ChevronDownIcon
|
|
70
|
+
className="relative top-[1px] ml-1 size-3 transition duration-300 group-data-[state=open]:rotate-180"
|
|
71
|
+
aria-hidden="true"
|
|
72
|
+
/>
|
|
73
|
+
</NavigationMenuPrimitive.Trigger>
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function NavigationMenuContent({ className, ...props }: React.ComponentProps<typeof NavigationMenuPrimitive.Content>) {
|
|
78
|
+
return (
|
|
79
|
+
<NavigationMenuPrimitive.Content
|
|
80
|
+
data-slot="navigation-menu-content"
|
|
81
|
+
className={cn(
|
|
82
|
+
"max-md:h-[calc(100vh-var(--spacing-page-nav))] top-0 left-0 min-w-xs w-auto absolute group-data-[mega=true]/navigation-menu:w-full",
|
|
83
|
+
"data-[motion^=from-]:animate-in data-[motion^=to-]:animate-out data-[motion^=from-]:fade-in data-[motion^=to-]:fade-out data-[motion=from-end]:slide-in-from-right-52 data-[motion=from-start]:slide-in-from-left-52 data-[motion=to-end]:slide-out-to-right-52 data-[motion=to-start]:slide-out-to-left-52",
|
|
84
|
+
"group-data-[viewport=false]/navigation-menu:data-[state=open]:animate-in group-data-[viewport=false]/navigation-menu:data-[state=closed]:animate-out group-data-[viewport=false]/navigation-menu:data-[state=closed]:zoom-out-95 group-data-[viewport=false]/navigation-menu:data-[state=open]:zoom-in-95 group-data-[viewport=false]/navigation-menu:data-[state=open]:fade-in-0 group-data-[viewport=false]/navigation-menu:data-[state=closed]:fade-out-0",
|
|
85
|
+
"group-data-[viewport=false]/navigation-menu:bg-popover group-data-[viewport=false]/navigation-menu:text-popover-foreground group-data-[viewport=false]/navigation-menu:top-full group-data-[viewport=false]/navigation-menu:mt-1.5 group-data-[viewport=false]/navigation-menu:overflow-hidden group-data-[viewport=false]/navigation-menu:rounded-md group-data-[viewport=false]/navigation-menu:border group-data-[viewport=false]/navigation-menu:shadow group-data-[viewport=false]/navigation-menu:duration-200 **:data-[slot=navigation-menu-link]:focus:ring-0 **:data-[slot=navigation-menu-link]:focus:outline-none",
|
|
86
|
+
className
|
|
87
|
+
)}
|
|
88
|
+
{...props}
|
|
89
|
+
/>
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function NavigationMenuViewport({
|
|
94
|
+
className,
|
|
95
|
+
mega = false,
|
|
96
|
+
...props
|
|
97
|
+
}: React.ComponentProps<typeof NavigationMenuPrimitive.Viewport> & {
|
|
98
|
+
mega?: boolean;
|
|
99
|
+
}) {
|
|
100
|
+
return (
|
|
101
|
+
<div
|
|
102
|
+
className={cn("absolute top-full left-0 isolate z-50 flex justify-center bg-popover", {
|
|
103
|
+
"min-w-xs": !mega,
|
|
104
|
+
"w-full px-(--spacing-section)": mega,
|
|
105
|
+
})}
|
|
106
|
+
>
|
|
107
|
+
<NavigationMenuPrimitive.Viewport
|
|
108
|
+
data-slot="navigation-menu-viewport"
|
|
109
|
+
className={cn(
|
|
110
|
+
"origin-top-center duration-150 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out data-[state=open]:fade-in",
|
|
111
|
+
"bg-popover text-popover-foreground relative overflow-hidden w-full h-[var(--radix-navigation-menu-viewport-height)] overscroll-contain",
|
|
112
|
+
{
|
|
113
|
+
"mt-1.5 rounded-md border shadow md:w-[var(--radix-navigation-menu-viewport-width)]": !mega,
|
|
114
|
+
"border-b-1 border-complement-1-50": mega,
|
|
115
|
+
},
|
|
116
|
+
className
|
|
117
|
+
)}
|
|
118
|
+
{...props}
|
|
119
|
+
/>
|
|
120
|
+
</div>
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function NavigationMenuLink({ className, ...props }: React.ComponentProps<typeof NavigationMenuPrimitive.Link>) {
|
|
125
|
+
return (
|
|
126
|
+
<NavigationMenuPrimitive.Link
|
|
127
|
+
data-slot="navigation-menu-link"
|
|
128
|
+
className={cn(
|
|
129
|
+
"[&_svg:not([class*='text-'])]:text-muted-foreground flex flex-col gap-1 rounded-sm p-2 text-sm transition-all outline-none focus-visible:ring-[3px] focus-visible:outline-1 [&_svg:not([class*='size-'])]:size-4",
|
|
130
|
+
className
|
|
131
|
+
)}
|
|
132
|
+
{...props}
|
|
133
|
+
/>
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function NavigationMenuIndicator({
|
|
138
|
+
className,
|
|
139
|
+
...props
|
|
140
|
+
}: React.ComponentProps<typeof NavigationMenuPrimitive.Indicator>) {
|
|
141
|
+
return (
|
|
142
|
+
<NavigationMenuPrimitive.Indicator
|
|
143
|
+
data-slot="navigation-menu-indicator"
|
|
144
|
+
className={cn(
|
|
145
|
+
"data-[state=visible]:animate-in data-[state=hidden]:animate-out data-[state=hidden]:fade-out data-[state=visible]:fade-in top-full z-[1] flex h-1.5 items-end justify-center overflow-hidden",
|
|
146
|
+
className
|
|
147
|
+
)}
|
|
148
|
+
{...props}
|
|
149
|
+
>
|
|
150
|
+
<div className="bg-border relative top-[60%] h-2 w-2 rotate-45 rounded-tl-sm shadow-md" />
|
|
151
|
+
</NavigationMenuPrimitive.Indicator>
|
|
152
|
+
);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
export {
|
|
156
|
+
NavigationMenu,
|
|
157
|
+
NavigationMenuList,
|
|
158
|
+
NavigationMenuItem,
|
|
159
|
+
NavigationMenuContent,
|
|
160
|
+
NavigationMenuTrigger,
|
|
161
|
+
NavigationMenuLink,
|
|
162
|
+
NavigationMenuIndicator,
|
|
163
|
+
NavigationMenuViewport,
|
|
164
|
+
navigationMenuTriggerStyle,
|
|
165
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { cn } from "@/lib/utils";
|
|
2
|
+
import { cva, type VariantProps } from "class-variance-authority";
|
|
3
|
+
|
|
4
|
+
const overlayVariants = cva("absolute w-fit h-fit z-1 overflow-hidden p-0.25", {
|
|
5
|
+
variants: {
|
|
6
|
+
position: {
|
|
7
|
+
t: "top-0 left-1/2 -translate-x-1/2",
|
|
8
|
+
b: "bottom-0 left-1/2 -translate-x-1/2",
|
|
9
|
+
l: "top-1/2 left-0 -translate-y-1/2",
|
|
10
|
+
r: "top-1/2 right-0 -translate-y-1/2",
|
|
11
|
+
tl: "top-0 left-0 rounded-tl-container",
|
|
12
|
+
tr: "top-0 right-0 rounded-tr-container",
|
|
13
|
+
bl: "bottom-0 left-0 rounded-bl-container",
|
|
14
|
+
br: "bottom-0 right-0 rounded-br-container",
|
|
15
|
+
c: "top-1/2 left-1/2 -translate-1/2",
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
defaultVariants: {
|
|
19
|
+
position: "br",
|
|
20
|
+
},
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
export type OverlayProps = React.ComponentProps<"div"> & VariantProps<typeof overlayVariants>;
|
|
24
|
+
|
|
25
|
+
function Overlay({ className, position, ...props }: OverlayProps) {
|
|
26
|
+
return <div className={cn(overlayVariants({ position }), className)} {...props} />;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export { Overlay };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Slot } from "@radix-ui/react-slot";
|
|
2
|
+
import { PageSection } from "./page-section";
|
|
3
|
+
import { LogoBCcampusWithTagline } from "@bccampus/media-kit";
|
|
4
|
+
|
|
5
|
+
export type PageHeaderProps = React.ComponentProps<"div"> & {
|
|
6
|
+
asChild?: boolean;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
function PageHeader({ children, asChild, ...props }: PageHeaderProps) {
|
|
10
|
+
const Comp = asChild ? Slot : "div";
|
|
11
|
+
return (
|
|
12
|
+
<PageSection py="none" className="sticky top-0 right-0 left-0 z-50 bg-background" {...props}>
|
|
13
|
+
<Comp className="h-page-nav overflow-hidden flex flex-row flex-nowrap border-b-1 border-b-complement-1-50 gap-2 sm:gap-12 justify-between items-center sm:justify-start">
|
|
14
|
+
<div className="py-4 h-full">
|
|
15
|
+
<LogoBCcampusWithTagline height="100%" variant="color" />
|
|
16
|
+
</div>
|
|
17
|
+
|
|
18
|
+
{children}
|
|
19
|
+
</Comp>
|
|
20
|
+
</PageSection>
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export { PageHeader };
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { cn } from "@/lib/utils";
|
|
2
|
+
import { cva, type VariantProps } from "class-variance-authority";
|
|
3
|
+
|
|
4
|
+
const pageSectionVariants = cva("group @container/page-section relative w-full", {
|
|
5
|
+
variants: {
|
|
6
|
+
px: {
|
|
7
|
+
none: "px-0",
|
|
8
|
+
default: "px-(--spacing-section)",
|
|
9
|
+
sm: "px-(--spacing-section-sm)",
|
|
10
|
+
lg: "px-(--spacing-section-lg)",
|
|
11
|
+
xl: "px-(--spacing-section-xl)",
|
|
12
|
+
},
|
|
13
|
+
py: {
|
|
14
|
+
none: "py-0",
|
|
15
|
+
default: "py-(--spacing-section)",
|
|
16
|
+
sm: "py-(--spacing-section-sm)",
|
|
17
|
+
lg: "py-(--spacing-section-lg)",
|
|
18
|
+
xl: "py-(--spacing-section-xl)",
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
defaultVariants: {
|
|
22
|
+
px: "default",
|
|
23
|
+
py: "default",
|
|
24
|
+
},
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
export type PageSectionProps = React.ComponentProps<"div"> & VariantProps<typeof pageSectionVariants>;
|
|
28
|
+
|
|
29
|
+
function PageSection({ className, px, py, ...props }: PageSectionProps) {
|
|
30
|
+
return <div data-slot="page-section" className={cn(pageSectionVariants({ px, py }), className)} {...props} />;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export { PageSection };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { cn } from "@/lib/utils";
|
|
2
|
+
|
|
3
|
+
export type PageProps = React.ComponentProps<"div">;
|
|
4
|
+
|
|
5
|
+
function Page({ className, ...props }: PageProps) {
|
|
6
|
+
return (
|
|
7
|
+
<div data-slot="page" className={cn("group/page @container/page relative w-full", className)} {...props} />
|
|
8
|
+
);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export { Page };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { cn } from "@/lib/utils";
|
|
2
|
+
import { Search } from "lucide-react";
|
|
3
|
+
import { Input } from "./input";
|
|
4
|
+
|
|
5
|
+
export type SearchInputProps = React.ComponentProps<"input">;
|
|
6
|
+
|
|
7
|
+
function SearchInput({ className, ...props }: SearchInputProps) {
|
|
8
|
+
return (
|
|
9
|
+
<div className={cn("relative", className)}>
|
|
10
|
+
<Input {...props} />
|
|
11
|
+
<Search className="absolute size-4 top-1/2 right-3 -translate-y-1/2 pointer-events-none text-primary" />
|
|
12
|
+
</div>
|
|
13
|
+
);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export { SearchInput };
|
|
@@ -1,39 +1,39 @@
|
|
|
1
|
-
import { Slot } from "@radix-ui/react-slot";
|
|
2
|
-
import { cva, type VariantProps } from "class-variance-authority";
|
|
3
|
-
|
|
4
|
-
import { cn } from "@/lib/utils";
|
|
5
|
-
|
|
6
|
-
const tagVariants = cva(
|
|
7
|
-
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-sm text-sm bg-complement-3 text-white [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0",
|
|
8
|
-
{
|
|
9
|
-
variants: {
|
|
10
|
-
variant: {
|
|
11
|
-
default: "",
|
|
12
|
-
button:
|
|
13
|
-
"hover:bg-primary transition-all disabled:pointer-events-none disabled:opacity-50 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
|
|
14
|
-
},
|
|
15
|
-
size: {
|
|
16
|
-
default: "h-8 px-4 py-1.5 has-[>svg]:px-3",
|
|
17
|
-
sm: "h-6 gap-1 px-3 has-[>svg]:px-2.5",
|
|
18
|
-
lg: "scroll-mr-6 text-xl/5 font-medium h-16 px-8 has-[>svg]:px-4",
|
|
19
|
-
icon: "size-8",
|
|
20
|
-
},
|
|
21
|
-
},
|
|
22
|
-
defaultVariants: {
|
|
23
|
-
variant: "default",
|
|
24
|
-
size: "default",
|
|
25
|
-
},
|
|
26
|
-
}
|
|
27
|
-
);
|
|
28
|
-
|
|
29
|
-
interface TagProps extends VariantProps<typeof tagVariants>, React.ComponentProps<"div"> {
|
|
30
|
-
asChild?: boolean;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
function Tag({ className, size, variant, asChild = false, ...props }: TagProps) {
|
|
34
|
-
const Comp = asChild ? Slot : "div";
|
|
35
|
-
|
|
36
|
-
return <Comp data-slot="tag" className={cn(tagVariants({ variant, size, className
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export { Tag, tagVariants };
|
|
1
|
+
import { Slot } from "@radix-ui/react-slot";
|
|
2
|
+
import { cva, type VariantProps } from "class-variance-authority";
|
|
3
|
+
|
|
4
|
+
import { cn } from "@/lib/utils";
|
|
5
|
+
|
|
6
|
+
const tagVariants = cva(
|
|
7
|
+
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-sm text-sm bg-complement-3 text-white [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0",
|
|
8
|
+
{
|
|
9
|
+
variants: {
|
|
10
|
+
variant: {
|
|
11
|
+
default: "",
|
|
12
|
+
button:
|
|
13
|
+
"hover:bg-primary transition-all disabled:pointer-events-none disabled:opacity-50 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
|
|
14
|
+
},
|
|
15
|
+
size: {
|
|
16
|
+
default: "h-8 px-4 py-1.5 has-[>svg]:px-3",
|
|
17
|
+
sm: "h-6 gap-1 px-3 has-[>svg]:px-2.5",
|
|
18
|
+
lg: "scroll-mr-6 text-xl/5 font-medium h-16 px-8 has-[>svg]:px-4",
|
|
19
|
+
icon: "size-8",
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
defaultVariants: {
|
|
23
|
+
variant: "default",
|
|
24
|
+
size: "default",
|
|
25
|
+
},
|
|
26
|
+
}
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
export interface TagProps extends VariantProps<typeof tagVariants>, React.ComponentProps<"div"> {
|
|
30
|
+
asChild?: boolean;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function Tag({ className, size, variant, asChild = false, ...props }: TagProps) {
|
|
34
|
+
const Comp = asChild ? Slot : "div";
|
|
35
|
+
|
|
36
|
+
return <Comp data-slot="tag" className={cn(tagVariants({ variant, size }), className)} {...props} />;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export { Tag, tagVariants };
|
|
@@ -1,32 +1,32 @@
|
|
|
1
|
-
import { Slot } from "@radix-ui/react-slot";
|
|
2
|
-
import { cva, type VariantProps } from "class-variance-authority";
|
|
3
|
-
|
|
4
|
-
import { cn } from "@/lib/utils";
|
|
5
|
-
|
|
6
|
-
const captionVariants = cva("tracking-tight text-balance", {
|
|
7
|
-
variants: {
|
|
8
|
-
variant: {
|
|
9
|
-
default: "scroll-mr-5 text-lg/5 font-bold text-secondary dark:text-foreground",
|
|
10
|
-
light: "scroll-mr-4 text-sm/4 font-normal text-primary",
|
|
11
|
-
},
|
|
12
|
-
},
|
|
13
|
-
defaultVariants: {
|
|
14
|
-
variant: "default",
|
|
15
|
-
},
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
function Caption({
|
|
19
|
-
className,
|
|
20
|
-
variant,
|
|
21
|
-
asChild = false,
|
|
22
|
-
...props
|
|
23
|
-
}: React.ComponentProps<"div"> &
|
|
24
|
-
VariantProps<typeof captionVariants> & {
|
|
25
|
-
asChild?: boolean;
|
|
26
|
-
}) {
|
|
27
|
-
const Comp = asChild ? Slot : "div";
|
|
28
|
-
|
|
29
|
-
return <Comp
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export { Caption, captionVariants };
|
|
1
|
+
import { Slot } from "@radix-ui/react-slot";
|
|
2
|
+
import { cva, type VariantProps } from "class-variance-authority";
|
|
3
|
+
|
|
4
|
+
import { cn } from "@/lib/utils";
|
|
5
|
+
|
|
6
|
+
const captionVariants = cva("tracking-tight text-balance", {
|
|
7
|
+
variants: {
|
|
8
|
+
variant: {
|
|
9
|
+
default: "scroll-mr-5 text-lg/5 font-bold text-secondary dark:text-foreground",
|
|
10
|
+
light: "scroll-mr-4 text-sm/4 font-normal text-primary",
|
|
11
|
+
},
|
|
12
|
+
},
|
|
13
|
+
defaultVariants: {
|
|
14
|
+
variant: "default",
|
|
15
|
+
},
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
function Caption({
|
|
19
|
+
className,
|
|
20
|
+
variant,
|
|
21
|
+
asChild = false,
|
|
22
|
+
...props
|
|
23
|
+
}: React.ComponentProps<"div"> &
|
|
24
|
+
VariantProps<typeof captionVariants> & {
|
|
25
|
+
asChild?: boolean;
|
|
26
|
+
}) {
|
|
27
|
+
const Comp = asChild ? Slot : "div";
|
|
28
|
+
|
|
29
|
+
return <Comp className={cn(captionVariants({ variant, className }))} {...props} />;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export { Caption, captionVariants };
|
package/src/styles/all.css
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
@import "./colors.css";
|
|
2
|
-
@import "./fonts.css";
|
|
3
|
-
@import "./theme.css";
|
|
4
|
-
@import "./typography.css";
|
|
1
|
+
@import "./colors.css";
|
|
2
|
+
@import "./fonts.css";
|
|
3
|
+
@import "./theme.css";
|
|
4
|
+
@import "./typography.css";
|