aural-ui 4.2.4 → 4.2.5
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/components/index.ts +1 -1
- package/dist/components/offer-label/OfferLabel.stories.tsx +267 -0
- package/dist/components/offer-label/index.tsx +32 -0
- package/dist/components/offer-label/meta.ts +6 -0
- package/dist/icons/chain-link-icon/ChainLinkIcon.stories.tsx +167 -0
- package/dist/icons/chain-link-icon/index.tsx +30 -0
- package/dist/icons/chain-link-icon/meta.ts +8 -0
- package/dist/icons/clock-icon/ClockIcon.stories.tsx +210 -0
- package/dist/icons/clock-icon/index.tsx +28 -0
- package/dist/icons/clock-icon/meta.ts +8 -0
- package/dist/icons/headphone-icon/HeadphoneIcon.stories.tsx +186 -0
- package/dist/icons/headphone-icon/index.tsx +49 -0
- package/dist/icons/headphone-icon/meta.ts +8 -0
- package/dist/icons/index.ts +5 -1
- package/dist/icons/underline-icon/UnderlineIcon.stories.tsx +238 -0
- package/dist/icons/underline-icon/index.tsx +58 -0
- package/dist/icons/underline-icon/meta.ts +8 -0
- package/dist/index.cjs +1 -1
- package/dist/index.js +1 -1
- package/package.json +2 -2
package/dist/components/index.ts
CHANGED
|
@@ -23,9 +23,9 @@ export * from "./if-else"
|
|
|
23
23
|
export * from "./label"
|
|
24
24
|
export * from "./list"
|
|
25
25
|
export * from "./marquee"
|
|
26
|
+
export * from "./offer-label"
|
|
26
27
|
export * from "./otp-inputs"
|
|
27
28
|
export * from "./overlay"
|
|
28
|
-
export * from "./otp-inputs"
|
|
29
29
|
export * from "./pagination"
|
|
30
30
|
export * from "./popover"
|
|
31
31
|
export * from "./radio"
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
import React from "react"
|
|
2
|
+
import type { Meta, StoryObj } from "@storybook/react-vite"
|
|
3
|
+
|
|
4
|
+
import { AuralComponentDocsPage } from "src/ui/story-spec/components/component-story-docs-page"
|
|
5
|
+
|
|
6
|
+
import { OfferLabel } from "."
|
|
7
|
+
|
|
8
|
+
const meta: Meta<typeof OfferLabel> = {
|
|
9
|
+
title: "Components/UI/OfferLabel",
|
|
10
|
+
component: OfferLabel,
|
|
11
|
+
parameters: {
|
|
12
|
+
layout: "centered",
|
|
13
|
+
docs: {
|
|
14
|
+
description: {
|
|
15
|
+
component:
|
|
16
|
+
"An inline label that renders text with a decorative gradient underline stroke beneath it — ideal for surfacing promotional copy, highlighted offers, or key phrases.",
|
|
17
|
+
},
|
|
18
|
+
page: () => (
|
|
19
|
+
<AuralComponentDocsPage
|
|
20
|
+
features={[
|
|
21
|
+
{
|
|
22
|
+
title: "Gradient Underline",
|
|
23
|
+
description: "Animated SVG accent",
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
title: "Composable Text",
|
|
27
|
+
description: "Accepts any className",
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
title: "SSR Safe",
|
|
31
|
+
description: "Stable gradient ID prop",
|
|
32
|
+
},
|
|
33
|
+
]}
|
|
34
|
+
/>
|
|
35
|
+
),
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
tags: ["autodocs"],
|
|
39
|
+
argTypes: {
|
|
40
|
+
text: {
|
|
41
|
+
control: "text",
|
|
42
|
+
description: "The label text to display",
|
|
43
|
+
},
|
|
44
|
+
className: {
|
|
45
|
+
control: "text",
|
|
46
|
+
description: "CSS classes applied to the inner text span",
|
|
47
|
+
},
|
|
48
|
+
iconId: {
|
|
49
|
+
control: "text",
|
|
50
|
+
description: "Optional stable ID for the underline gradient",
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export default meta
|
|
56
|
+
type Story = StoryObj<typeof OfferLabel>
|
|
57
|
+
|
|
58
|
+
// ─── 1. Playground ────────────────────────────────────────────────────────────
|
|
59
|
+
|
|
60
|
+
export const Playground: Story = {
|
|
61
|
+
args: {
|
|
62
|
+
text: "Limited Offer",
|
|
63
|
+
className:
|
|
64
|
+
"text-fm-primary font-fm-brand text-fm-2xl leading-fm-2xl font-bold",
|
|
65
|
+
},
|
|
66
|
+
render: (args) => (
|
|
67
|
+
<div className="w-full max-w-sm space-y-4">
|
|
68
|
+
<div className="flex justify-center py-4">
|
|
69
|
+
<OfferLabel {...args} />
|
|
70
|
+
</div>
|
|
71
|
+
<div className="border-fm-divider-secondary bg-fm-surface-secondary rounded-lg border px-4 py-3">
|
|
72
|
+
<code className="text-fm-secondary text-fm-md leading-fm-md font-(--font-fm-mono)">{`<OfferLabel text="${args.text}" className="${args.className ?? ""}" />`}</code>
|
|
73
|
+
</div>
|
|
74
|
+
</div>
|
|
75
|
+
),
|
|
76
|
+
parameters: {
|
|
77
|
+
docs: {
|
|
78
|
+
description: {
|
|
79
|
+
story:
|
|
80
|
+
"Adjust the text and className using the controls panel in the sidebar.",
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
},
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// ─── 2. All Variants ──────────────────────────────────────────────────────────
|
|
87
|
+
|
|
88
|
+
export const AllVariants: Story = {
|
|
89
|
+
render: () => (
|
|
90
|
+
<div className="space-y-8">
|
|
91
|
+
<div className="space-y-4">
|
|
92
|
+
<h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
|
|
93
|
+
Typography Scale
|
|
94
|
+
</h4>
|
|
95
|
+
<div className="flex flex-wrap items-end gap-6">
|
|
96
|
+
<div className="space-y-2 text-center">
|
|
97
|
+
<OfferLabel
|
|
98
|
+
text="Headline"
|
|
99
|
+
className="text-fm-primary font-fm-brand text-fm-4xl leading-fm-4xl font-bold"
|
|
100
|
+
iconId="variant-4xl"
|
|
101
|
+
/>
|
|
102
|
+
<p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
|
|
103
|
+
4xl / bold
|
|
104
|
+
</p>
|
|
105
|
+
</div>
|
|
106
|
+
<div className="space-y-2 text-center">
|
|
107
|
+
<OfferLabel
|
|
108
|
+
text="Subheading"
|
|
109
|
+
className="text-fm-primary font-fm-brand text-fm-2xl leading-fm-2xl font-semibold"
|
|
110
|
+
iconId="variant-2xl"
|
|
111
|
+
/>
|
|
112
|
+
<p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
|
|
113
|
+
2xl / semibold
|
|
114
|
+
</p>
|
|
115
|
+
</div>
|
|
116
|
+
<div className="space-y-2 text-center">
|
|
117
|
+
<OfferLabel
|
|
118
|
+
text="Body label"
|
|
119
|
+
className="text-fm-primary font-fm-text text-fm-lg leading-fm-lg font-medium"
|
|
120
|
+
iconId="variant-lg"
|
|
121
|
+
/>
|
|
122
|
+
<p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
|
|
123
|
+
lg / medium
|
|
124
|
+
</p>
|
|
125
|
+
</div>
|
|
126
|
+
<div className="space-y-2 text-center">
|
|
127
|
+
<OfferLabel
|
|
128
|
+
text="Small"
|
|
129
|
+
className="text-fm-primary font-fm-text text-fm-sm leading-fm-sm"
|
|
130
|
+
iconId="variant-sm"
|
|
131
|
+
/>
|
|
132
|
+
<p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
|
|
133
|
+
sm / regular
|
|
134
|
+
</p>
|
|
135
|
+
</div>
|
|
136
|
+
</div>
|
|
137
|
+
</div>
|
|
138
|
+
|
|
139
|
+
<div className="space-y-4">
|
|
140
|
+
<h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
|
|
141
|
+
Text Color
|
|
142
|
+
</h4>
|
|
143
|
+
<div className="flex flex-wrap items-end gap-6">
|
|
144
|
+
<div className="space-y-2 text-center">
|
|
145
|
+
<OfferLabel
|
|
146
|
+
text="Primary"
|
|
147
|
+
className="text-fm-primary font-fm-brand text-fm-2xl leading-fm-2xl font-bold"
|
|
148
|
+
iconId="color-primary"
|
|
149
|
+
/>
|
|
150
|
+
<p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
|
|
151
|
+
text-fm-primary
|
|
152
|
+
</p>
|
|
153
|
+
</div>
|
|
154
|
+
<div className="space-y-2 text-center">
|
|
155
|
+
<OfferLabel
|
|
156
|
+
text="Secondary"
|
|
157
|
+
className="text-fm-secondary font-fm-brand text-fm-2xl leading-fm-2xl font-bold"
|
|
158
|
+
iconId="color-secondary"
|
|
159
|
+
/>
|
|
160
|
+
<p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
|
|
161
|
+
text-fm-secondary
|
|
162
|
+
</p>
|
|
163
|
+
</div>
|
|
164
|
+
<div className="space-y-2 text-center">
|
|
165
|
+
<OfferLabel
|
|
166
|
+
text="Tertiary"
|
|
167
|
+
className="text-fm-tertiary font-fm-brand text-fm-2xl leading-fm-2xl font-bold"
|
|
168
|
+
iconId="color-tertiary"
|
|
169
|
+
/>
|
|
170
|
+
<p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
|
|
171
|
+
text-fm-tertiary
|
|
172
|
+
</p>
|
|
173
|
+
</div>
|
|
174
|
+
</div>
|
|
175
|
+
</div>
|
|
176
|
+
</div>
|
|
177
|
+
),
|
|
178
|
+
parameters: {
|
|
179
|
+
docs: {
|
|
180
|
+
description: {
|
|
181
|
+
story:
|
|
182
|
+
"OfferLabel across different type scales and text color tokens — the gradient underline adapts naturally to each.",
|
|
183
|
+
},
|
|
184
|
+
},
|
|
185
|
+
},
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// ─── 3. Use Cases ─────────────────────────────────────────────────────────────
|
|
189
|
+
|
|
190
|
+
export const UseCases: Story = {
|
|
191
|
+
render: () => (
|
|
192
|
+
<div className="mx-auto max-w-3xl space-y-8 p-8">
|
|
193
|
+
<div className="space-y-4">
|
|
194
|
+
<h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
|
|
195
|
+
Promotional Hero Banner
|
|
196
|
+
</h4>
|
|
197
|
+
<div className="border-fm-divider-secondary bg-fm-surface-secondary mx-auto max-w-md space-y-3 rounded-xl border p-6 text-center">
|
|
198
|
+
<p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm tracking-widest uppercase">
|
|
199
|
+
Pocket FM Premium
|
|
200
|
+
</p>
|
|
201
|
+
<div className="flex justify-center">
|
|
202
|
+
<OfferLabel
|
|
203
|
+
text="3 Months Free"
|
|
204
|
+
className="text-fm-primary font-fm-brand text-fm-4xl leading-fm-4xl font-bold"
|
|
205
|
+
iconId="use-case-hero"
|
|
206
|
+
/>
|
|
207
|
+
</div>
|
|
208
|
+
<p className="text-fm-secondary font-fm-text text-fm-md leading-fm-md">
|
|
209
|
+
Unlock unlimited access to all audio stories.
|
|
210
|
+
</p>
|
|
211
|
+
</div>
|
|
212
|
+
</div>
|
|
213
|
+
|
|
214
|
+
<div className="space-y-4">
|
|
215
|
+
<h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
|
|
216
|
+
Inline Promotional Copy
|
|
217
|
+
</h4>
|
|
218
|
+
<div className="border-fm-divider-secondary bg-fm-surface-secondary mx-auto max-w-md rounded-xl border p-5">
|
|
219
|
+
<p className="text-fm-primary font-fm-text text-fm-lg leading-fm-xl">
|
|
220
|
+
Subscribe today and get{" "}
|
|
221
|
+
<OfferLabel
|
|
222
|
+
text="50% off"
|
|
223
|
+
className="text-fm-primary font-fm-brand text-fm-lg leading-fm-xl font-semibold"
|
|
224
|
+
iconId="use-case-inline"
|
|
225
|
+
/>{" "}
|
|
226
|
+
your first month — no strings attached.
|
|
227
|
+
</p>
|
|
228
|
+
</div>
|
|
229
|
+
</div>
|
|
230
|
+
|
|
231
|
+
<div className="space-y-4">
|
|
232
|
+
<h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
|
|
233
|
+
Pricing Card Highlight
|
|
234
|
+
</h4>
|
|
235
|
+
<div className="border-fm-divider-secondary bg-fm-surface-secondary mx-auto max-w-sm space-y-4 rounded-xl border p-6">
|
|
236
|
+
<div className="space-y-1">
|
|
237
|
+
<p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm tracking-widest uppercase">
|
|
238
|
+
Annual Plan
|
|
239
|
+
</p>
|
|
240
|
+
<div className="flex items-baseline gap-1">
|
|
241
|
+
<OfferLabel
|
|
242
|
+
text="₹999"
|
|
243
|
+
className="text-fm-primary font-fm-brand text-fm-5xl leading-fm-5xl font-bold"
|
|
244
|
+
iconId="use-case-price"
|
|
245
|
+
/>
|
|
246
|
+
<span className="text-fm-secondary font-fm-text text-fm-md leading-fm-md">
|
|
247
|
+
/ year
|
|
248
|
+
</span>
|
|
249
|
+
</div>
|
|
250
|
+
</div>
|
|
251
|
+
<p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
|
|
252
|
+
Save 40% compared to the monthly plan.
|
|
253
|
+
</p>
|
|
254
|
+
</div>
|
|
255
|
+
</div>
|
|
256
|
+
</div>
|
|
257
|
+
),
|
|
258
|
+
parameters: {
|
|
259
|
+
layout: "fullscreen",
|
|
260
|
+
docs: {
|
|
261
|
+
description: {
|
|
262
|
+
story:
|
|
263
|
+
"Real-world usage: promotional hero banners, inline highlighted copy, and pricing card accents.",
|
|
264
|
+
},
|
|
265
|
+
},
|
|
266
|
+
},
|
|
267
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import React from "react"
|
|
2
|
+
import { UnderlineIcon } from "@icons/underline-icon"
|
|
3
|
+
import { cn } from "@lib/utils"
|
|
4
|
+
|
|
5
|
+
export interface IOfferLabelProps {
|
|
6
|
+
className?: string
|
|
7
|
+
iconClass?: string
|
|
8
|
+
/**
|
|
9
|
+
* Optional stable ID for the underline gradient. Can help if SSR hydration mismatches occur.
|
|
10
|
+
*/
|
|
11
|
+
iconId?: string
|
|
12
|
+
text: string
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function OfferLabel({
|
|
16
|
+
text,
|
|
17
|
+
className,
|
|
18
|
+
iconId,
|
|
19
|
+
iconClass,
|
|
20
|
+
}: IOfferLabelProps) {
|
|
21
|
+
return (
|
|
22
|
+
<span className="relative inline-block pb-1">
|
|
23
|
+
<span className={className}>{text}</span>
|
|
24
|
+
<UnderlineIcon
|
|
25
|
+
id={iconId}
|
|
26
|
+
aria-hidden="true"
|
|
27
|
+
withAccessibility={false}
|
|
28
|
+
className={cn("absolute left-0 w-8", iconClass)}
|
|
29
|
+
/>
|
|
30
|
+
</span>
|
|
31
|
+
)
|
|
32
|
+
}
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import React from "react"
|
|
2
|
+
import type { Meta, StoryObj } from "@storybook/react-vite"
|
|
3
|
+
|
|
4
|
+
import { ArrowRightUpIcon } from "src/ui/icons/arrow-right-up-icon"
|
|
5
|
+
import { CopyIcon } from "src/ui/icons/copy-icon"
|
|
6
|
+
import { GlobeIcon } from "src/ui/icons/globe-icon"
|
|
7
|
+
import { ShareIcon } from "src/ui/icons/share-icon"
|
|
8
|
+
import {
|
|
9
|
+
IconColorVariations,
|
|
10
|
+
IconDefaultCanvas,
|
|
11
|
+
IconPlaygroundCanvas,
|
|
12
|
+
IconSizeVariations,
|
|
13
|
+
IconUsageCanvas,
|
|
14
|
+
IconUsageSection,
|
|
15
|
+
} from "src/ui/story-spec/icons/icon-story-canvas"
|
|
16
|
+
import { AuralIconDocsPage } from "src/ui/story-spec/icons/icon-story-docs-page"
|
|
17
|
+
|
|
18
|
+
import { ChainLinkIcon } from "."
|
|
19
|
+
|
|
20
|
+
const meta: Meta<typeof ChainLinkIcon> = {
|
|
21
|
+
title: "Icons/ChainLinkIcon",
|
|
22
|
+
component: ChainLinkIcon,
|
|
23
|
+
parameters: {
|
|
24
|
+
layout: "fullscreen",
|
|
25
|
+
backgrounds: {
|
|
26
|
+
default: "dark",
|
|
27
|
+
values: [
|
|
28
|
+
{ name: "dark", value: "var(--color-fm-surface-primary)" },
|
|
29
|
+
{ name: "darker", value: "var(--color-fm-neutral-0)" },
|
|
30
|
+
{ name: "light", value: "var(--color-fm-neutral-1100)" },
|
|
31
|
+
],
|
|
32
|
+
},
|
|
33
|
+
docs: {
|
|
34
|
+
page: () => (
|
|
35
|
+
<AuralIconDocsPage
|
|
36
|
+
accentToken="info"
|
|
37
|
+
features={[
|
|
38
|
+
{
|
|
39
|
+
title: "Chain Link Shape",
|
|
40
|
+
description: "Two-link URL indicator",
|
|
41
|
+
},
|
|
42
|
+
{ title: "Scalable", description: "Works at any size" },
|
|
43
|
+
{ title: "Accessible", description: "ARIA-ready by default" },
|
|
44
|
+
]}
|
|
45
|
+
quickStart={{
|
|
46
|
+
codeExample: `import { ChainLinkIcon } from "src/ui/icons/chain-link-icon"
|
|
47
|
+
|
|
48
|
+
function CopyLinkButton() {
|
|
49
|
+
return (
|
|
50
|
+
<button className="flex items-center gap-2">
|
|
51
|
+
<ChainLinkIcon className="h-4 w-4" />
|
|
52
|
+
Copy link
|
|
53
|
+
</button>
|
|
54
|
+
)
|
|
55
|
+
}`,
|
|
56
|
+
livePreview: (
|
|
57
|
+
<button className="bg-fm-surface-secondary border-fm-divider-secondary text-fm-primary font-fm-text flex items-center gap-2 rounded-xl border px-4 py-2.5 text-sm">
|
|
58
|
+
<ChainLinkIcon className="text-fm-icon-active h-4 w-4" />
|
|
59
|
+
Copy link
|
|
60
|
+
</button>
|
|
61
|
+
),
|
|
62
|
+
}}
|
|
63
|
+
relatedIcons={[
|
|
64
|
+
{
|
|
65
|
+
name: "ShareIcon",
|
|
66
|
+
description: "Share content externally",
|
|
67
|
+
icon: ShareIcon,
|
|
68
|
+
accentToken: "info",
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
name: "CopyIcon",
|
|
72
|
+
description: "Duplicate to clipboard",
|
|
73
|
+
icon: CopyIcon,
|
|
74
|
+
accentToken: "positive",
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
name: "GlobeIcon",
|
|
78
|
+
description: "Web or URL context",
|
|
79
|
+
icon: GlobeIcon,
|
|
80
|
+
accentToken: "warning",
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
name: "ArrowRightUpIcon",
|
|
84
|
+
description: "Open in new tab",
|
|
85
|
+
icon: ArrowRightUpIcon,
|
|
86
|
+
accentToken: "negative",
|
|
87
|
+
},
|
|
88
|
+
]}
|
|
89
|
+
/>
|
|
90
|
+
),
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
tags: ["autodocs"],
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export default meta
|
|
97
|
+
type Story = StoryObj<typeof ChainLinkIcon>
|
|
98
|
+
|
|
99
|
+
export const Default: Story = {
|
|
100
|
+
render: (args) => (
|
|
101
|
+
<IconDefaultCanvas>
|
|
102
|
+
<ChainLinkIcon className="text-fm-icon-active h-5 w-5" {...args} />
|
|
103
|
+
</IconDefaultCanvas>
|
|
104
|
+
),
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export const SizeVariations: Story = {
|
|
108
|
+
render: () => <IconSizeVariations icon={ChainLinkIcon} />,
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export const ColorVariations: Story = {
|
|
112
|
+
render: () => <IconColorVariations icon={ChainLinkIcon} />,
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export const UsageExamples: Story = {
|
|
116
|
+
render: () => (
|
|
117
|
+
<IconUsageCanvas>
|
|
118
|
+
<IconUsageSection title="Copy Link Button">
|
|
119
|
+
<button className="bg-fm-surface-secondary border-fm-divider-secondary text-fm-primary font-fm-text flex items-center gap-2 rounded-xl border px-4 py-2.5 text-sm">
|
|
120
|
+
<ChainLinkIcon className="text-fm-icon-active h-4 w-4" />
|
|
121
|
+
Copy link
|
|
122
|
+
</button>
|
|
123
|
+
</IconUsageSection>
|
|
124
|
+
|
|
125
|
+
<IconUsageSection title="Inline Link Reference">
|
|
126
|
+
<div className="border-fm-divider-secondary bg-fm-surface-secondary flex w-full max-w-sm items-center gap-3 rounded-xl border p-4">
|
|
127
|
+
<ChainLinkIcon className="text-fm-icon-info h-4 w-4 shrink-0" />
|
|
128
|
+
<span className="text-fm-secondary font-fm-text truncate text-sm">
|
|
129
|
+
https://pocketfm.com/show/audio-drama
|
|
130
|
+
</span>
|
|
131
|
+
</div>
|
|
132
|
+
</IconUsageSection>
|
|
133
|
+
|
|
134
|
+
<IconUsageSection title="Share Row">
|
|
135
|
+
<div className="border-fm-divider-secondary bg-fm-surface-secondary w-full max-w-sm rounded-xl border p-4">
|
|
136
|
+
<p className="text-fm-secondary font-fm-text mb-3 text-xs tracking-wider uppercase">
|
|
137
|
+
Share via
|
|
138
|
+
</p>
|
|
139
|
+
<div className="flex flex-col gap-3">
|
|
140
|
+
{[
|
|
141
|
+
{ label: "Copy link", icon: ChainLinkIcon },
|
|
142
|
+
{ label: "Share externally", icon: ShareIcon },
|
|
143
|
+
].map(({ label, icon: Icon }) => (
|
|
144
|
+
<button
|
|
145
|
+
key={label}
|
|
146
|
+
className="text-fm-primary font-fm-text flex items-center gap-3 text-sm"
|
|
147
|
+
>
|
|
148
|
+
<span className="bg-fm-surface-tertiary flex h-8 w-8 items-center justify-center rounded-lg">
|
|
149
|
+
<Icon className="text-fm-icon-active h-4 w-4" />
|
|
150
|
+
</span>
|
|
151
|
+
{label}
|
|
152
|
+
</button>
|
|
153
|
+
))}
|
|
154
|
+
</div>
|
|
155
|
+
</div>
|
|
156
|
+
</IconUsageSection>
|
|
157
|
+
</IconUsageCanvas>
|
|
158
|
+
),
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
export const Playground: Story = {
|
|
162
|
+
render: (args) => (
|
|
163
|
+
<IconPlaygroundCanvas>
|
|
164
|
+
<ChainLinkIcon className="text-fm-icon-active h-6 w-6" {...args} />
|
|
165
|
+
</IconPlaygroundCanvas>
|
|
166
|
+
),
|
|
167
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import React from "react"
|
|
2
|
+
import { AccessibleIcon } from "@radix-ui/react-accessible-icon"
|
|
3
|
+
|
|
4
|
+
export interface IChainLinkIconProps extends React.SVGProps<SVGSVGElement> {
|
|
5
|
+
withAccessibility?: boolean
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export const ChainLinkIcon = (props: IChainLinkIconProps) => {
|
|
9
|
+
const { withAccessibility = true, ...svgProps } = props
|
|
10
|
+
|
|
11
|
+
const svg = (
|
|
12
|
+
<svg
|
|
13
|
+
viewBox="0 0 16 16"
|
|
14
|
+
fill="none"
|
|
15
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
16
|
+
stroke="currentColor"
|
|
17
|
+
strokeWidth="1.5"
|
|
18
|
+
strokeLinecap="square"
|
|
19
|
+
{...svgProps}
|
|
20
|
+
>
|
|
21
|
+
<path d="M6.5001 3.68247L7.14443 3.03814C8.75084 1.43172 11.3554 1.43172 12.9618 3.03814C14.5682 4.64456 14.5682 7.24907 12.9618 8.85548L12.316 9.50124M3.68582 6.49674L3.03806 7.1445C1.43165 8.75092 1.43165 11.3554 3.03806 12.9618C4.64448 14.5683 7.24899 14.5683 8.85541 12.9618L9.49843 12.3188M6.33325 9.66666L9.66658 6.33333" />
|
|
22
|
+
</svg>
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
if (withAccessibility) {
|
|
26
|
+
return <AccessibleIcon label="Chain link icon">{svg}</AccessibleIcon>
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return svg
|
|
30
|
+
}
|