@windstream/react-shared-components 0.0.9 → 0.0.11
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/README.md +623 -623
- package/dist/contentful/index.d.ts +10 -6
- package/dist/contentful/index.esm.js +1 -1
- package/dist/contentful/index.esm.js.map +1 -1
- package/dist/contentful/index.js +1 -1
- package/dist/contentful/index.js.map +1 -1
- package/dist/core.d.ts +3 -3
- package/dist/index.d.ts +4 -4
- package/dist/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +159 -159
- package/src/components/accordion/Accordion.stories.tsx +225 -225
- package/src/components/accordion/index.tsx +36 -36
- package/src/components/accordion/types.ts +9 -9
- package/src/components/alert-card/types.ts +9 -9
- package/src/components/brand-button/BrandButton.stories.tsx +221 -221
- package/src/components/brand-button/helpers.ts +35 -35
- package/src/components/brand-button/index.tsx +90 -90
- package/src/components/brand-button/types.ts +26 -26
- package/src/components/button/Button.stories.tsx +108 -108
- package/src/components/button/index.tsx +23 -23
- package/src/components/button/types.ts +14 -14
- package/src/components/call-button/CallButton.stories.tsx +324 -324
- package/src/components/call-button/index.tsx +80 -80
- package/src/components/call-button/types.ts +9 -9
- package/src/components/checkbox/Checkbox.stories.tsx +248 -248
- package/src/components/checkbox/types.ts +23 -23
- package/src/components/checklist/Checklist.stories.tsx +151 -151
- package/src/components/checklist/index.tsx +33 -33
- package/src/components/checklist/types.ts +5 -5
- package/src/components/collapse/Collapse.stories.tsx +256 -256
- package/src/components/collapse/index.tsx +44 -44
- package/src/components/collapse/types.ts +5 -5
- package/src/components/divider/Divider.stories.tsx +206 -206
- package/src/components/divider/index.tsx +23 -23
- package/src/components/divider/type.ts +2 -2
- package/src/components/input/Input.stories.tsx +358 -358
- package/src/components/input/index.tsx +174 -174
- package/src/components/input/types.ts +36 -36
- package/src/components/link/Link.stories.tsx +163 -163
- package/src/components/link/index.tsx +96 -96
- package/src/components/link/types.ts +25 -25
- package/src/components/list/List.stories.tsx +272 -272
- package/src/components/list/index.tsx +86 -86
- package/src/components/list/list-item/index.tsx +36 -36
- package/src/components/list/list-item/types.ts +13 -13
- package/src/components/list/types.ts +29 -29
- package/src/components/material-icon/MaterialIcon.stories.tsx +330 -330
- package/src/components/material-icon/constants.ts +95 -95
- package/src/components/material-icon/index.tsx +44 -44
- package/src/components/material-icon/types.ts +31 -31
- package/src/components/modal/Modal.stories.tsx +171 -171
- package/src/components/modal/index.tsx +168 -168
- package/src/components/modal/types.ts +23 -23
- package/src/components/radio-button/index.tsx +73 -73
- package/src/components/radio-button/types.ts +21 -21
- package/src/components/see-more/SeeMore.stories.tsx +182 -182
- package/src/components/see-more/index.tsx +38 -38
- package/src/components/see-more/types.ts +3 -3
- package/src/components/select/Select.stories.tsx +410 -410
- package/src/components/select/index.tsx +150 -150
- package/src/components/select/types.ts +34 -34
- package/src/components/select-plan-button/SelectPlanButton.stories.tsx +160 -160
- package/src/components/select-plan-button/index.tsx +20 -20
- package/src/components/select-plan-button/types.ts +3 -3
- package/src/components/skeleton/Skeleton.stories.tsx +180 -180
- package/src/components/skeleton/index.tsx +61 -61
- package/src/components/skeleton/types.ts +3 -3
- package/src/components/spinner/Spinner.stories.tsx +335 -335
- package/src/components/spinner/index.tsx +44 -44
- package/src/components/spinner/types.ts +4 -4
- package/src/components/text/Text.stories.tsx +302 -302
- package/src/components/text/index.tsx +26 -26
- package/src/components/text/types.ts +45 -45
- package/src/components/tooltip/Tooltip.stories.tsx +220 -220
- package/src/components/tooltip/index.tsx +78 -78
- package/src/components/tooltip/types.ts +6 -6
- package/src/components/view-cart-button/ViewCartButton.stories.tsx +241 -241
- package/src/components/view-cart-button/index.tsx +38 -38
- package/src/components/view-cart-button/types.ts +4 -4
- package/src/contentful/blocks/accordion/index.tsx +7 -7
- package/src/contentful/blocks/button/index.tsx +5 -5
- package/src/contentful/blocks/callout/index.tsx +7 -7
- package/src/contentful/blocks/cards/index.tsx +7 -7
- package/src/contentful/blocks/carousel/index.tsx +7 -7
- package/src/contentful/blocks/cta-callout/index.tsx +6 -0
- package/src/contentful/blocks/cta-callout/types.ts +1 -0
- package/src/contentful/blocks/floating-banner/index.tsx +7 -7
- package/src/contentful/blocks/footer/index.tsx +7 -7
- package/src/contentful/blocks/image-promo-bar/index.tsx +7 -7
- package/src/contentful/blocks/modal/index.tsx +5 -5
- package/src/contentful/blocks/navigation/index.tsx +7 -7
- package/src/contentful/blocks/primary-hero/index.tsx +7 -7
- package/src/contentful/blocks/shape-background-wrapper/index.tsx +123 -101
- package/src/contentful/blocks/shape-background-wrapper/types.ts +35 -29
- package/src/contentful/blocks/text/index.tsx +6 -6
- package/src/contentful/index.ts +4 -1
- package/src/hooks/use-body-scroll-lock.ts +31 -31
- package/src/index.ts +81 -81
- package/src/setupTests.ts +46 -46
- package/src/styles/globals.css +275 -269
- package/src/types/global.d.ts +9 -9
- package/src/utils/index.ts +49 -49
|
@@ -1,163 +1,163 @@
|
|
|
1
|
-
import { Link } from "./index";
|
|
2
|
-
import { DocsPage } from "@shared/stories/DocsTemplate";
|
|
3
|
-
|
|
4
|
-
import type { Meta, StoryObj } from "@storybook/react";
|
|
5
|
-
|
|
6
|
-
const meta: Meta<typeof Link> = {
|
|
7
|
-
title: "Components/Link",
|
|
8
|
-
component: Link,
|
|
9
|
-
tags: ["autodocs"],
|
|
10
|
-
parameters: {
|
|
11
|
-
layout: "centered",
|
|
12
|
-
docs: {
|
|
13
|
-
page: DocsPage,
|
|
14
|
-
description: {
|
|
15
|
-
component:
|
|
16
|
-
"A flexible link component with multiple variants and states.",
|
|
17
|
-
},
|
|
18
|
-
},
|
|
19
|
-
},
|
|
20
|
-
argTypes: {
|
|
21
|
-
variant: {
|
|
22
|
-
control: { type: "select" },
|
|
23
|
-
options: ["default", "unstyled"],
|
|
24
|
-
description: "Link styling variant",
|
|
25
|
-
},
|
|
26
|
-
href: {
|
|
27
|
-
control: { type: "text" },
|
|
28
|
-
description: "Link URL",
|
|
29
|
-
},
|
|
30
|
-
target: {
|
|
31
|
-
control: { type: "select" },
|
|
32
|
-
options: ["_self", "_blank", "_parent", "_top"],
|
|
33
|
-
description: "Link target",
|
|
34
|
-
},
|
|
35
|
-
disabled: {
|
|
36
|
-
control: { type: "boolean" },
|
|
37
|
-
description: "Disable the link",
|
|
38
|
-
},
|
|
39
|
-
children: {
|
|
40
|
-
control: { type: "text" },
|
|
41
|
-
description: "Link content",
|
|
42
|
-
},
|
|
43
|
-
},
|
|
44
|
-
args: {
|
|
45
|
-
children: "Link Text",
|
|
46
|
-
href: "#",
|
|
47
|
-
variant: "default",
|
|
48
|
-
target: "_self",
|
|
49
|
-
disabled: false,
|
|
50
|
-
},
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
export default meta;
|
|
54
|
-
type Story = StoryObj<typeof meta>;
|
|
55
|
-
|
|
56
|
-
// Default link
|
|
57
|
-
export const Default: Story = {
|
|
58
|
-
args: {},
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
// Unstyled link
|
|
62
|
-
export const Unstyled: Story = {
|
|
63
|
-
args: {
|
|
64
|
-
variant: "unstyled",
|
|
65
|
-
children: "Unstyled Link",
|
|
66
|
-
},
|
|
67
|
-
};
|
|
68
|
-
|
|
69
|
-
// External link
|
|
70
|
-
export const External: Story = {
|
|
71
|
-
args: {
|
|
72
|
-
href: "https://example.com",
|
|
73
|
-
target: "_blank",
|
|
74
|
-
children: "External Link ↗",
|
|
75
|
-
},
|
|
76
|
-
};
|
|
77
|
-
|
|
78
|
-
// Disabled link
|
|
79
|
-
export const Disabled: Story = {
|
|
80
|
-
args: {
|
|
81
|
-
disabled: true,
|
|
82
|
-
children: "Disabled Link",
|
|
83
|
-
},
|
|
84
|
-
};
|
|
85
|
-
|
|
86
|
-
// Link with icon
|
|
87
|
-
export const WithIcon: Story = {
|
|
88
|
-
args: {
|
|
89
|
-
children: "Link with Icon →",
|
|
90
|
-
className: "flex items-center gap-2",
|
|
91
|
-
},
|
|
92
|
-
};
|
|
93
|
-
|
|
94
|
-
// Navigation links
|
|
95
|
-
export const Navigation: Story = {
|
|
96
|
-
render: () => (
|
|
97
|
-
<nav className="flex gap-6">
|
|
98
|
-
<Link href="#home" variant="default">
|
|
99
|
-
Home
|
|
100
|
-
</Link>
|
|
101
|
-
<Link href="#about">About</Link>
|
|
102
|
-
<Link href="#services">Services</Link>
|
|
103
|
-
<Link href="#contact">Contact</Link>
|
|
104
|
-
</nav>
|
|
105
|
-
),
|
|
106
|
-
parameters: {
|
|
107
|
-
docs: {
|
|
108
|
-
description: {
|
|
109
|
-
story: "Navigation menu with different link variants.",
|
|
110
|
-
},
|
|
111
|
-
},
|
|
112
|
-
},
|
|
113
|
-
};
|
|
114
|
-
|
|
115
|
-
// All variants showcase
|
|
116
|
-
export const AllVariants: Story = {
|
|
117
|
-
render: () => (
|
|
118
|
-
<div className="space-y-6">
|
|
119
|
-
<div>
|
|
120
|
-
<h3 className="mb-3 text-lg font-semibold">Variants</h3>
|
|
121
|
-
<div className="flex gap-4">
|
|
122
|
-
<Link href="#" variant="default">
|
|
123
|
-
Default
|
|
124
|
-
</Link>
|
|
125
|
-
<Link href="#" variant="unstyled">
|
|
126
|
-
Unstyled
|
|
127
|
-
</Link>
|
|
128
|
-
</div>
|
|
129
|
-
</div>
|
|
130
|
-
|
|
131
|
-
<div>
|
|
132
|
-
<h3 className="mb-3 text-lg font-semibold">Variants</h3>
|
|
133
|
-
<div className="flex items-center gap-4">
|
|
134
|
-
<Link href="#" variant="default">
|
|
135
|
-
Default
|
|
136
|
-
</Link>
|
|
137
|
-
<Link href="#" variant="unstyled">
|
|
138
|
-
Unstyled
|
|
139
|
-
</Link>
|
|
140
|
-
</div>
|
|
141
|
-
</div>
|
|
142
|
-
|
|
143
|
-
<div>
|
|
144
|
-
<h3 className="mb-3 text-lg font-semibold">States</h3>
|
|
145
|
-
<div className="flex gap-4">
|
|
146
|
-
<Link href="#" disabled>
|
|
147
|
-
Disabled
|
|
148
|
-
</Link>
|
|
149
|
-
<Link href="https://example.com" target="_blank">
|
|
150
|
-
External ↗
|
|
151
|
-
</Link>
|
|
152
|
-
</div>
|
|
153
|
-
</div>
|
|
154
|
-
</div>
|
|
155
|
-
),
|
|
156
|
-
parameters: {
|
|
157
|
-
docs: {
|
|
158
|
-
description: {
|
|
159
|
-
story: "Showcase of all link variants, sizes, and states.",
|
|
160
|
-
},
|
|
161
|
-
},
|
|
162
|
-
},
|
|
163
|
-
};
|
|
1
|
+
import { Link } from "./index";
|
|
2
|
+
import { DocsPage } from "@shared/stories/DocsTemplate";
|
|
3
|
+
|
|
4
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
5
|
+
|
|
6
|
+
const meta: Meta<typeof Link> = {
|
|
7
|
+
title: "Components/Link",
|
|
8
|
+
component: Link,
|
|
9
|
+
tags: ["autodocs"],
|
|
10
|
+
parameters: {
|
|
11
|
+
layout: "centered",
|
|
12
|
+
docs: {
|
|
13
|
+
page: DocsPage,
|
|
14
|
+
description: {
|
|
15
|
+
component:
|
|
16
|
+
"A flexible link component with multiple variants and states.",
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
argTypes: {
|
|
21
|
+
variant: {
|
|
22
|
+
control: { type: "select" },
|
|
23
|
+
options: ["default", "unstyled"],
|
|
24
|
+
description: "Link styling variant",
|
|
25
|
+
},
|
|
26
|
+
href: {
|
|
27
|
+
control: { type: "text" },
|
|
28
|
+
description: "Link URL",
|
|
29
|
+
},
|
|
30
|
+
target: {
|
|
31
|
+
control: { type: "select" },
|
|
32
|
+
options: ["_self", "_blank", "_parent", "_top"],
|
|
33
|
+
description: "Link target",
|
|
34
|
+
},
|
|
35
|
+
disabled: {
|
|
36
|
+
control: { type: "boolean" },
|
|
37
|
+
description: "Disable the link",
|
|
38
|
+
},
|
|
39
|
+
children: {
|
|
40
|
+
control: { type: "text" },
|
|
41
|
+
description: "Link content",
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
args: {
|
|
45
|
+
children: "Link Text",
|
|
46
|
+
href: "#",
|
|
47
|
+
variant: "default",
|
|
48
|
+
target: "_self",
|
|
49
|
+
disabled: false,
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
export default meta;
|
|
54
|
+
type Story = StoryObj<typeof meta>;
|
|
55
|
+
|
|
56
|
+
// Default link
|
|
57
|
+
export const Default: Story = {
|
|
58
|
+
args: {},
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
// Unstyled link
|
|
62
|
+
export const Unstyled: Story = {
|
|
63
|
+
args: {
|
|
64
|
+
variant: "unstyled",
|
|
65
|
+
children: "Unstyled Link",
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
// External link
|
|
70
|
+
export const External: Story = {
|
|
71
|
+
args: {
|
|
72
|
+
href: "https://example.com",
|
|
73
|
+
target: "_blank",
|
|
74
|
+
children: "External Link ↗",
|
|
75
|
+
},
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
// Disabled link
|
|
79
|
+
export const Disabled: Story = {
|
|
80
|
+
args: {
|
|
81
|
+
disabled: true,
|
|
82
|
+
children: "Disabled Link",
|
|
83
|
+
},
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
// Link with icon
|
|
87
|
+
export const WithIcon: Story = {
|
|
88
|
+
args: {
|
|
89
|
+
children: "Link with Icon →",
|
|
90
|
+
className: "flex items-center gap-2",
|
|
91
|
+
},
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
// Navigation links
|
|
95
|
+
export const Navigation: Story = {
|
|
96
|
+
render: () => (
|
|
97
|
+
<nav className="flex gap-6">
|
|
98
|
+
<Link href="#home" variant="default">
|
|
99
|
+
Home
|
|
100
|
+
</Link>
|
|
101
|
+
<Link href="#about">About</Link>
|
|
102
|
+
<Link href="#services">Services</Link>
|
|
103
|
+
<Link href="#contact">Contact</Link>
|
|
104
|
+
</nav>
|
|
105
|
+
),
|
|
106
|
+
parameters: {
|
|
107
|
+
docs: {
|
|
108
|
+
description: {
|
|
109
|
+
story: "Navigation menu with different link variants.",
|
|
110
|
+
},
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
// All variants showcase
|
|
116
|
+
export const AllVariants: Story = {
|
|
117
|
+
render: () => (
|
|
118
|
+
<div className="space-y-6">
|
|
119
|
+
<div>
|
|
120
|
+
<h3 className="mb-3 text-lg font-semibold">Variants</h3>
|
|
121
|
+
<div className="flex gap-4">
|
|
122
|
+
<Link href="#" variant="default">
|
|
123
|
+
Default
|
|
124
|
+
</Link>
|
|
125
|
+
<Link href="#" variant="unstyled">
|
|
126
|
+
Unstyled
|
|
127
|
+
</Link>
|
|
128
|
+
</div>
|
|
129
|
+
</div>
|
|
130
|
+
|
|
131
|
+
<div>
|
|
132
|
+
<h3 className="mb-3 text-lg font-semibold">Variants</h3>
|
|
133
|
+
<div className="flex items-center gap-4">
|
|
134
|
+
<Link href="#" variant="default">
|
|
135
|
+
Default
|
|
136
|
+
</Link>
|
|
137
|
+
<Link href="#" variant="unstyled">
|
|
138
|
+
Unstyled
|
|
139
|
+
</Link>
|
|
140
|
+
</div>
|
|
141
|
+
</div>
|
|
142
|
+
|
|
143
|
+
<div>
|
|
144
|
+
<h3 className="mb-3 text-lg font-semibold">States</h3>
|
|
145
|
+
<div className="flex gap-4">
|
|
146
|
+
<Link href="#" disabled>
|
|
147
|
+
Disabled
|
|
148
|
+
</Link>
|
|
149
|
+
<Link href="https://example.com" target="_blank">
|
|
150
|
+
External ↗
|
|
151
|
+
</Link>
|
|
152
|
+
</div>
|
|
153
|
+
</div>
|
|
154
|
+
</div>
|
|
155
|
+
),
|
|
156
|
+
parameters: {
|
|
157
|
+
docs: {
|
|
158
|
+
description: {
|
|
159
|
+
story: "Showcase of all link variants, sizes, and states.",
|
|
160
|
+
},
|
|
161
|
+
},
|
|
162
|
+
},
|
|
163
|
+
};
|
|
@@ -1,96 +1,96 @@
|
|
|
1
|
-
import React, { forwardRef } from "react";
|
|
2
|
-
import { cx } from "../../utils";
|
|
3
|
-
import { LinkProps } from "./types";
|
|
4
|
-
|
|
5
|
-
export const Link = forwardRef<HTMLAnchorElement, LinkProps>(
|
|
6
|
-
(
|
|
7
|
-
{
|
|
8
|
-
children,
|
|
9
|
-
href,
|
|
10
|
-
className = "",
|
|
11
|
-
onClick,
|
|
12
|
-
variant = "unstyled",
|
|
13
|
-
style,
|
|
14
|
-
external = false,
|
|
15
|
-
disabled = false,
|
|
16
|
-
...props
|
|
17
|
-
},
|
|
18
|
-
ref
|
|
19
|
-
) => {
|
|
20
|
-
// Get Tailwind classes for different variants
|
|
21
|
-
const getVariantClasses = () => {
|
|
22
|
-
if (variant === "unstyled") return "";
|
|
23
|
-
|
|
24
|
-
// TODO: Add styles based on the figma design for all variants
|
|
25
|
-
const baseClasses =
|
|
26
|
-
"transition-colors duration-200 focus:outline-none focus:ring-2 focus:ring-offset-2";
|
|
27
|
-
|
|
28
|
-
const variantClasses = {
|
|
29
|
-
default:
|
|
30
|
-
"text-text underline",
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
const stateClasses = [
|
|
34
|
-
disabled
|
|
35
|
-
? "opacity-60 cursor-not-allowed pointer-events-none"
|
|
36
|
-
: "cursor-pointer",
|
|
37
|
-
]
|
|
38
|
-
.filter(Boolean)
|
|
39
|
-
.join(" ");
|
|
40
|
-
|
|
41
|
-
return [
|
|
42
|
-
baseClasses,
|
|
43
|
-
variantClasses[variant as keyof typeof variantClasses] ||
|
|
44
|
-
variantClasses.default,
|
|
45
|
-
stateClasses,
|
|
46
|
-
]
|
|
47
|
-
.filter(Boolean)
|
|
48
|
-
.join(" ");
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
const tailwindClasses = getVariantClasses();
|
|
52
|
-
|
|
53
|
-
// Handle click events
|
|
54
|
-
const handleClick = (event: React.MouseEvent<HTMLAnchorElement>) => {
|
|
55
|
-
if (disabled) {
|
|
56
|
-
event.preventDefault();
|
|
57
|
-
return;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
onClick?.(event);
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
// Combine all classes
|
|
64
|
-
const combinedClassName = cx(
|
|
65
|
-
tailwindClasses,
|
|
66
|
-
`link--${variant}`,
|
|
67
|
-
disabled && "link--disabled",
|
|
68
|
-
className
|
|
69
|
-
);
|
|
70
|
-
|
|
71
|
-
// Determine link props based on external/internal
|
|
72
|
-
const linkProps = {
|
|
73
|
-
...props,
|
|
74
|
-
ref,
|
|
75
|
-
className: combinedClassName,
|
|
76
|
-
style,
|
|
77
|
-
href: disabled ? undefined : href,
|
|
78
|
-
onClick: handleClick,
|
|
79
|
-
...(external &&
|
|
80
|
-
!disabled && {
|
|
81
|
-
target: "_blank",
|
|
82
|
-
rel: "noopener noreferrer",
|
|
83
|
-
}),
|
|
84
|
-
...(disabled && {
|
|
85
|
-
"aria-disabled": true,
|
|
86
|
-
tabIndex: -1,
|
|
87
|
-
}),
|
|
88
|
-
};
|
|
89
|
-
|
|
90
|
-
return <a {...linkProps}>{children}</a>;
|
|
91
|
-
}
|
|
92
|
-
);
|
|
93
|
-
|
|
94
|
-
Link.displayName = "Link";
|
|
95
|
-
|
|
96
|
-
export type { LinkProps };
|
|
1
|
+
import React, { forwardRef } from "react";
|
|
2
|
+
import { cx } from "../../utils";
|
|
3
|
+
import { LinkProps } from "./types";
|
|
4
|
+
|
|
5
|
+
export const Link = forwardRef<HTMLAnchorElement, LinkProps>(
|
|
6
|
+
(
|
|
7
|
+
{
|
|
8
|
+
children,
|
|
9
|
+
href,
|
|
10
|
+
className = "",
|
|
11
|
+
onClick,
|
|
12
|
+
variant = "unstyled",
|
|
13
|
+
style,
|
|
14
|
+
external = false,
|
|
15
|
+
disabled = false,
|
|
16
|
+
...props
|
|
17
|
+
},
|
|
18
|
+
ref
|
|
19
|
+
) => {
|
|
20
|
+
// Get Tailwind classes for different variants
|
|
21
|
+
const getVariantClasses = () => {
|
|
22
|
+
if (variant === "unstyled") return "";
|
|
23
|
+
|
|
24
|
+
// TODO: Add styles based on the figma design for all variants
|
|
25
|
+
const baseClasses =
|
|
26
|
+
"transition-colors duration-200 focus:outline-none focus:ring-2 focus:ring-offset-2";
|
|
27
|
+
|
|
28
|
+
const variantClasses = {
|
|
29
|
+
default:
|
|
30
|
+
"text-text underline",
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const stateClasses = [
|
|
34
|
+
disabled
|
|
35
|
+
? "opacity-60 cursor-not-allowed pointer-events-none"
|
|
36
|
+
: "cursor-pointer",
|
|
37
|
+
]
|
|
38
|
+
.filter(Boolean)
|
|
39
|
+
.join(" ");
|
|
40
|
+
|
|
41
|
+
return [
|
|
42
|
+
baseClasses,
|
|
43
|
+
variantClasses[variant as keyof typeof variantClasses] ||
|
|
44
|
+
variantClasses.default,
|
|
45
|
+
stateClasses,
|
|
46
|
+
]
|
|
47
|
+
.filter(Boolean)
|
|
48
|
+
.join(" ");
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
const tailwindClasses = getVariantClasses();
|
|
52
|
+
|
|
53
|
+
// Handle click events
|
|
54
|
+
const handleClick = (event: React.MouseEvent<HTMLAnchorElement>) => {
|
|
55
|
+
if (disabled) {
|
|
56
|
+
event.preventDefault();
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
onClick?.(event);
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
// Combine all classes
|
|
64
|
+
const combinedClassName = cx(
|
|
65
|
+
tailwindClasses,
|
|
66
|
+
`link--${variant}`,
|
|
67
|
+
disabled && "link--disabled",
|
|
68
|
+
className
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
// Determine link props based on external/internal
|
|
72
|
+
const linkProps = {
|
|
73
|
+
...props,
|
|
74
|
+
ref,
|
|
75
|
+
className: combinedClassName,
|
|
76
|
+
style,
|
|
77
|
+
href: disabled ? undefined : href,
|
|
78
|
+
onClick: handleClick,
|
|
79
|
+
...(external &&
|
|
80
|
+
!disabled && {
|
|
81
|
+
target: "_blank",
|
|
82
|
+
rel: "noopener noreferrer",
|
|
83
|
+
}),
|
|
84
|
+
...(disabled && {
|
|
85
|
+
"aria-disabled": true,
|
|
86
|
+
tabIndex: -1,
|
|
87
|
+
}),
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
return <a {...linkProps}>{children}</a>;
|
|
91
|
+
}
|
|
92
|
+
);
|
|
93
|
+
|
|
94
|
+
Link.displayName = "Link";
|
|
95
|
+
|
|
96
|
+
export type { LinkProps };
|
|
@@ -1,25 +1,25 @@
|
|
|
1
|
-
import {
|
|
2
|
-
type AnchorHTMLAttributes,
|
|
3
|
-
type CSSProperties,
|
|
4
|
-
type MouseEvent,
|
|
5
|
-
type ReactNode,
|
|
6
|
-
} from "react";
|
|
7
|
-
|
|
8
|
-
export interface LinkProps extends AnchorHTMLAttributes<HTMLAnchorElement> {
|
|
9
|
-
/** Content to render inside the link */
|
|
10
|
-
children: ReactNode;
|
|
11
|
-
/** URL to navigate to */
|
|
12
|
-
href?: string;
|
|
13
|
-
/** Custom className for the link */
|
|
14
|
-
className?: string;
|
|
15
|
-
/** Click handler function */
|
|
16
|
-
onClick?: (event: MouseEvent<HTMLAnchorElement>) => void;
|
|
17
|
-
/** Additional styling options */
|
|
18
|
-
variant?: "default" | "unstyled";
|
|
19
|
-
/** Custom styles */
|
|
20
|
-
style?: CSSProperties;
|
|
21
|
-
/** External link behavior - opens in new tab */
|
|
22
|
-
external?: boolean;
|
|
23
|
-
/** Disable the link */
|
|
24
|
-
disabled?: boolean;
|
|
25
|
-
}
|
|
1
|
+
import {
|
|
2
|
+
type AnchorHTMLAttributes,
|
|
3
|
+
type CSSProperties,
|
|
4
|
+
type MouseEvent,
|
|
5
|
+
type ReactNode,
|
|
6
|
+
} from "react";
|
|
7
|
+
|
|
8
|
+
export interface LinkProps extends AnchorHTMLAttributes<HTMLAnchorElement> {
|
|
9
|
+
/** Content to render inside the link */
|
|
10
|
+
children: ReactNode;
|
|
11
|
+
/** URL to navigate to */
|
|
12
|
+
href?: string;
|
|
13
|
+
/** Custom className for the link */
|
|
14
|
+
className?: string;
|
|
15
|
+
/** Click handler function */
|
|
16
|
+
onClick?: (event: MouseEvent<HTMLAnchorElement>) => void;
|
|
17
|
+
/** Additional styling options */
|
|
18
|
+
variant?: "default" | "unstyled";
|
|
19
|
+
/** Custom styles */
|
|
20
|
+
style?: CSSProperties;
|
|
21
|
+
/** External link behavior - opens in new tab */
|
|
22
|
+
external?: boolean;
|
|
23
|
+
/** Disable the link */
|
|
24
|
+
disabled?: boolean;
|
|
25
|
+
}
|