aural-ui 4.2.3 → 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.
@@ -0,0 +1,210 @@
1
+ import React from "react"
2
+ import type { Meta, StoryObj } from "@storybook/react-vite"
3
+
4
+ import { BackwardTenSecondsIcon } from "src/ui/icons/backward-ten-seconds-icon"
5
+ import { ForwardTenSecondsIcon } from "src/ui/icons/forward-ten-seconds-icon"
6
+ import { NotepadIcon } from "src/ui/icons/notepad-icon"
7
+ import { SpinnerSolidIcon } from "src/ui/icons/spinner-solid-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 { ClockIcon } from "."
19
+
20
+ const meta: Meta<typeof ClockIcon> = {
21
+ title: "Icons/ClockIcon",
22
+ component: ClockIcon,
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: "Time & Schedule",
40
+ description: "Represents time-based UI",
41
+ },
42
+ { title: "Compact Shape", description: "Crisp at small sizes" },
43
+ { title: "Accessible", description: "ARIA-ready by default" },
44
+ ]}
45
+ quickStart={{
46
+ codeExample: `import { ClockIcon } from "src/ui/icons/clock-icon"
47
+
48
+ function PublishedAt({ time }: { time: string }) {
49
+ return (
50
+ <span className="flex items-center gap-1.5">
51
+ <ClockIcon className="h-4 w-4 text-fm-icon-inactive" />
52
+ <span className="text-fm-secondary text-sm">{time}</span>
53
+ </span>
54
+ )
55
+ }`,
56
+ livePreview: (
57
+ <span className="flex items-center gap-1.5">
58
+ <ClockIcon className="text-fm-icon-inactive h-4 w-4" />
59
+ <span className="text-fm-secondary font-fm-text text-sm">
60
+ 2 hours ago
61
+ </span>
62
+ </span>
63
+ ),
64
+ }}
65
+ relatedIcons={[
66
+ {
67
+ name: "BackwardTenSecondsIcon",
68
+ description: "Rewind ten seconds",
69
+ icon: BackwardTenSecondsIcon,
70
+ accentToken: "info",
71
+ },
72
+ {
73
+ name: "ForwardTenSecondsIcon",
74
+ description: "Skip ten seconds ahead",
75
+ icon: ForwardTenSecondsIcon,
76
+ accentToken: "positive",
77
+ },
78
+ {
79
+ name: "SpinnerSolidIcon",
80
+ description: "Loading / waiting state",
81
+ icon: SpinnerSolidIcon,
82
+ accentToken: "warning",
83
+ },
84
+ {
85
+ name: "NotepadIcon",
86
+ description: "Notes and scheduling",
87
+ icon: NotepadIcon,
88
+ accentToken: "negative",
89
+ },
90
+ ]}
91
+ />
92
+ ),
93
+ },
94
+ },
95
+ tags: ["autodocs"],
96
+ argTypes: {
97
+ className: {
98
+ control: "text",
99
+ description: "CSS classes including color token",
100
+ },
101
+ withAccessibility: {
102
+ control: "boolean",
103
+ description: "Wrap with accessibility label",
104
+ },
105
+ },
106
+ }
107
+
108
+ export default meta
109
+ type Story = StoryObj<typeof ClockIcon>
110
+
111
+ export const Default: Story = {
112
+ args: {
113
+ className: "h-6 w-6 text-fm-icon-active",
114
+ withAccessibility: true,
115
+ },
116
+ render: (args) => (
117
+ <IconDefaultCanvas>
118
+ <ClockIcon {...args} />
119
+ </IconDefaultCanvas>
120
+ ),
121
+ }
122
+
123
+ export const SizeVariations: Story = {
124
+ render: () => <IconSizeVariations icon={ClockIcon} />,
125
+ }
126
+
127
+ export const ColorVariations: Story = {
128
+ render: () => <IconColorVariations icon={ClockIcon} />,
129
+ }
130
+
131
+ export const UsageExamples: Story = {
132
+ render: () => (
133
+ <IconUsageCanvas>
134
+ <IconUsageSection title="Timestamp Label">
135
+ <span className="flex items-center gap-1.5">
136
+ <ClockIcon className="text-fm-icon-inactive h-4 w-4" />
137
+ <span className="text-fm-secondary font-fm-text text-sm">
138
+ 2 hours ago
139
+ </span>
140
+ </span>
141
+ </IconUsageSection>
142
+
143
+ <IconUsageSection title="Episode Duration">
144
+ <div className="border-fm-divider-secondary bg-fm-surface-secondary flex w-full max-w-sm items-center gap-3 rounded-xl border px-4 py-3">
145
+ <div className="bg-fm-surface-primary h-10 w-10 flex-none rounded-lg" />
146
+ <div className="min-w-0 flex-1">
147
+ <p className="text-fm-primary font-fm-text truncate text-sm font-medium">
148
+ The Morning Show
149
+ </p>
150
+ <span className="text-fm-tertiary font-fm-text flex items-center gap-1 text-xs">
151
+ <ClockIcon className="text-fm-icon-inactive h-3 w-3" />
152
+ 45 min
153
+ </span>
154
+ </div>
155
+ </div>
156
+ </IconUsageSection>
157
+
158
+ <IconUsageSection title="Scheduled Release">
159
+ <div className="border-fm-divider-secondary bg-fm-surface-secondary w-full max-w-sm rounded-xl border px-4 py-3">
160
+ <div className="flex items-center justify-between">
161
+ <span className="text-fm-primary font-fm-text text-sm font-medium">
162
+ Episode 12
163
+ </span>
164
+ <span className="text-fm-icon-info bg-fm-icon-info/10 flex items-center gap-1 rounded-full px-2 py-0.5 text-xs font-medium">
165
+ <ClockIcon className="h-3 w-3" />
166
+ Scheduled
167
+ </span>
168
+ </div>
169
+ <p className="text-fm-tertiary font-fm-text mt-1 text-xs">
170
+ Publishes on May 10 at 9:00 AM
171
+ </p>
172
+ </div>
173
+ </IconUsageSection>
174
+
175
+ <IconUsageSection title="Listening History">
176
+ <div className="border-fm-divider-secondary bg-fm-surface-secondary w-full max-w-sm divide-y rounded-xl border">
177
+ {["Yesterday", "2 days ago", "Last week"].map((time) => (
178
+ <div
179
+ key={time}
180
+ className="flex items-center gap-3 px-4 py-3 first:rounded-t-xl last:rounded-b-xl"
181
+ >
182
+ <div className="bg-fm-surface-primary h-8 w-8 flex-none rounded-lg" />
183
+ <div className="min-w-0 flex-1">
184
+ <p className="text-fm-primary font-fm-text truncate text-sm">
185
+ Episode Title
186
+ </p>
187
+ </div>
188
+ <span className="text-fm-tertiary font-fm-text flex flex-none items-center gap-1 text-xs">
189
+ <ClockIcon className="text-fm-icon-inactive h-3 w-3" />
190
+ {time}
191
+ </span>
192
+ </div>
193
+ ))}
194
+ </div>
195
+ </IconUsageSection>
196
+ </IconUsageCanvas>
197
+ ),
198
+ }
199
+
200
+ export const Playground: Story = {
201
+ args: {
202
+ className: "h-8 w-8 text-fm-icon-active",
203
+ withAccessibility: true,
204
+ },
205
+ render: (args) => (
206
+ <IconPlaygroundCanvas>
207
+ <ClockIcon {...args} />
208
+ </IconPlaygroundCanvas>
209
+ ),
210
+ }
@@ -0,0 +1,28 @@
1
+ import React from "react"
2
+ import { AccessibleIcon } from "@radix-ui/react-accessible-icon"
3
+
4
+ export interface IClockIconProps extends React.SVGProps<SVGSVGElement> {
5
+ withAccessibility?: boolean
6
+ }
7
+
8
+ export const ClockIcon = (props: IClockIconProps) => {
9
+ const { withAccessibility = true, ...svgProps } = props
10
+
11
+ const svg = (
12
+ <svg
13
+ viewBox="0 0 11 11"
14
+ fill="currentColor"
15
+ xmlns="http://www.w3.org/2000/svg"
16
+ aria-hidden="true"
17
+ {...svgProps}
18
+ >
19
+ <path d="M5.625 3V2.5H4.625V3H5.125H5.625ZM5.125 5.125H4.625V5.33211L4.77145 5.47855L5.125 5.125ZM6.14645 6.85355C6.34171 7.04882 6.65829 7.04882 6.85355 6.85355C7.04882 6.65829 7.04882 6.34171 6.85355 6.14645L6.5 6.5L6.14645 6.85355ZM9.75 5.125H9.25C9.25 7.40317 7.40317 9.25 5.125 9.25V9.75V10.25C7.95546 10.25 10.25 7.95546 10.25 5.125H9.75ZM5.125 9.75V9.25C2.84683 9.25 1 7.40317 1 5.125H0.5H0C0 7.95546 2.29454 10.25 5.125 10.25V9.75ZM0.5 5.125H1C1 2.84683 2.84683 1 5.125 1V0.5V0C2.29454 0 0 2.29454 0 5.125H0.5ZM5.125 0.5V1C7.40317 1 9.25 2.84683 9.25 5.125H9.75H10.25C10.25 2.29454 7.95546 0 5.125 0V0.5ZM5.125 3H4.625V5.125H5.125H5.625V3H5.125ZM5.125 5.125L4.77145 5.47855L6.14645 6.85355L6.5 6.5L6.85355 6.14645L5.47855 4.77145L5.125 5.125Z" />
20
+ </svg>
21
+ )
22
+
23
+ if (withAccessibility) {
24
+ return <AccessibleIcon label="Clock icon">{svg}</AccessibleIcon>
25
+ }
26
+
27
+ return svg
28
+ }
@@ -0,0 +1,8 @@
1
+ export const meta = {
2
+ dependencies: {
3
+ "@radix-ui/react-accessible-icon": "^1.1.7",
4
+ },
5
+ devDependencies: {},
6
+ internalDependencies: [],
7
+ tokens: [],
8
+ }
@@ -0,0 +1,186 @@
1
+ import React from "react"
2
+ import type { Meta, StoryObj } from "@storybook/react-vite"
3
+
4
+ import { AudioBarIcon } from "src/ui/icons/audio-bar-icon"
5
+ import { HeadIcon } from "src/ui/icons/head-icon"
6
+ import { MusicalNoteIcon } from "src/ui/icons/musical-note-icon"
7
+ import { VolumeFullIcon } from "src/ui/icons/volume-full-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 { HeadphoneIcon } from "."
19
+
20
+ const meta: Meta<typeof HeadphoneIcon> = {
21
+ title: "Icons/HeadphoneIcon",
22
+ component: HeadphoneIcon,
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
+ { title: "Audio Listening", description: "Headphone idle state" },
39
+ { title: "Navigation", description: "Tab bar unselected state" },
40
+ { title: "Accessible", description: "ARIA-ready by default" },
41
+ ]}
42
+ quickStart={{
43
+ codeExample: `import { HeadphoneIcon } from "src/ui/icons/headphone-icon"
44
+
45
+ function ListenTab() {
46
+ return (
47
+ <div className="flex flex-col items-center gap-1">
48
+ <HeadphoneIcon className="h-6 w-6 text-fm-icon-inactive" />
49
+ <span className="text-fm-secondary text-xs">Listen</span>
50
+ </div>
51
+ )
52
+ }`,
53
+ livePreview: (
54
+ <div className="flex flex-col items-center gap-1">
55
+ <HeadphoneIcon className="text-fm-icon-inactive h-6 w-6" />
56
+ <span className="text-fm-secondary font-fm-text text-xs">
57
+ Listen
58
+ </span>
59
+ </div>
60
+ ),
61
+ }}
62
+ relatedIcons={[
63
+ {
64
+ name: "AudioBarIcon",
65
+ description: "Audio playback bars",
66
+ icon: AudioBarIcon,
67
+ accentToken: "info",
68
+ },
69
+ {
70
+ name: "VolumeFullIcon",
71
+ description: "Full volume indicator",
72
+ icon: VolumeFullIcon,
73
+ accentToken: "positive",
74
+ },
75
+ {
76
+ name: "MusicalNoteIcon",
77
+ description: "Music / audio content",
78
+ icon: MusicalNoteIcon,
79
+ accentToken: "warning",
80
+ },
81
+ {
82
+ name: "HeadIcon",
83
+ description: "Narrator or character",
84
+ icon: HeadIcon,
85
+ accentToken: "negative",
86
+ },
87
+ ]}
88
+ />
89
+ ),
90
+ },
91
+ },
92
+ tags: ["autodocs"],
93
+ argTypes: {
94
+ className: {
95
+ control: "text",
96
+ description: "CSS classes including color token",
97
+ },
98
+ withAccessibility: {
99
+ control: "boolean",
100
+ description: "Wrap with accessibility label",
101
+ },
102
+ },
103
+ }
104
+
105
+ export default meta
106
+ type Story = StoryObj<typeof HeadphoneIcon>
107
+
108
+ export const Default: Story = {
109
+ args: {
110
+ className: "h-6 w-6 text-fm-icon-inactive",
111
+ withAccessibility: true,
112
+ },
113
+ render: (args) => (
114
+ <IconDefaultCanvas>
115
+ <HeadphoneIcon {...args} />
116
+ </IconDefaultCanvas>
117
+ ),
118
+ }
119
+
120
+ export const SizeVariations: Story = {
121
+ render: () => <IconSizeVariations icon={HeadphoneIcon} />,
122
+ }
123
+
124
+ export const ColorVariations: Story = {
125
+ render: () => <IconColorVariations icon={HeadphoneIcon} />,
126
+ }
127
+
128
+ export const UsageExamples: Story = {
129
+ render: () => (
130
+ <IconUsageCanvas>
131
+ <IconUsageSection title="Tab Bar Navigation">
132
+ <div className="border-fm-divider-secondary bg-fm-surface-secondary flex w-full max-w-sm items-center justify-around rounded-xl border px-4 py-3">
133
+ {["Home", "Listen", "Library"].map((label, i) => (
134
+ <div key={label} className="flex flex-col items-center gap-1">
135
+ <HeadphoneIcon
136
+ className={`h-6 w-6 ${i === 1 ? "text-fm-icon-active" : "text-fm-icon-inactive"}`}
137
+ />
138
+ <span
139
+ className={`font-fm-text text-xs ${i === 1 ? "text-fm-primary" : "text-fm-secondary"}`}
140
+ >
141
+ {label}
142
+ </span>
143
+ </div>
144
+ ))}
145
+ </div>
146
+ </IconUsageSection>
147
+
148
+ <IconUsageSection title="Audio Player Header">
149
+ <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">
150
+ <div className="bg-fm-divider-secondary flex h-10 w-10 items-center justify-center rounded-full">
151
+ <HeadphoneIcon className="text-fm-icon-inactive h-5 w-5" />
152
+ </div>
153
+ <div>
154
+ <div className="text-fm-primary font-fm-text text-sm font-medium">
155
+ Now Playing
156
+ </div>
157
+ <div className="text-fm-secondary font-fm-text text-xs">
158
+ Tap to open player
159
+ </div>
160
+ </div>
161
+ </div>
162
+ </IconUsageSection>
163
+
164
+ <IconUsageSection title="Empty State">
165
+ <div className="flex flex-col items-center gap-3 py-4">
166
+ <HeadphoneIcon className="text-fm-icon-inactive h-12 w-12" />
167
+ <p className="text-fm-secondary font-fm-text text-sm">
168
+ No audio playing
169
+ </p>
170
+ </div>
171
+ </IconUsageSection>
172
+ </IconUsageCanvas>
173
+ ),
174
+ }
175
+
176
+ export const Playground: Story = {
177
+ args: {
178
+ className: "h-8 w-8 text-fm-icon-inactive",
179
+ withAccessibility: true,
180
+ },
181
+ render: (args) => (
182
+ <IconPlaygroundCanvas>
183
+ <HeadphoneIcon {...args} />
184
+ </IconPlaygroundCanvas>
185
+ ),
186
+ }
@@ -0,0 +1,49 @@
1
+ import React from "react"
2
+ import { AccessibleIcon } from "@radix-ui/react-accessible-icon"
3
+
4
+ export interface IHeadphoneIconProps extends React.SVGProps<SVGSVGElement> {
5
+ withAccessibility?: boolean
6
+ }
7
+
8
+ export const HeadphoneIcon = (props: IHeadphoneIconProps) => {
9
+ const { withAccessibility = true, ...svgProps } = props
10
+
11
+ const svg = (
12
+ <svg
13
+ xmlns="http://www.w3.org/2000/svg"
14
+ width="24"
15
+ height="24"
16
+ viewBox="0 0 24 24"
17
+ fill="none"
18
+ {...svgProps}
19
+ >
20
+ <path
21
+ d="M3 18V11C3 8.61305 3.94821 6.32387 5.63604 4.63604C7.32387 2.94821 9.61305 2 12 2C14.3869 2 16.6761 2.94821 18.364 4.63604C20.0518 6.32387 21 8.61305 21 11V18"
22
+ stroke="currentColor"
23
+ strokeWidth="1.5"
24
+ strokeLinecap="round"
25
+ strokeLinejoin="round"
26
+ />
27
+ <path
28
+ d="M21 19C21 19.5304 20.7893 20.0391 20.4142 20.4142C20.0391 20.7893 19.5304 21 19 21H18C17.4696 21 16.9609 20.7893 16.5858 20.4142C16.2107 20.0391 16 19.5304 16 19V16C16 15.4696 16.2107 14.9609 16.5858 14.5858C16.9609 14.2107 17.4696 14 18 14H21V19ZM3 19C3 19.5304 3.21071 20.0391 3.58579 20.4142C3.96086 20.7893 4.46957 21 5 21H6C6.53043 21 7.03914 20.7893 7.41421 20.4142C7.78929 20.0391 8 19.5304 8 19V16C8 15.4696 7.78929 14.9609 7.41421 14.5858C7.03914 14.2107 6.53043 14 6 14H3V19Z"
29
+ stroke="currentColor"
30
+ strokeWidth="1.5"
31
+ strokeLinecap="round"
32
+ strokeLinejoin="round"
33
+ />
34
+ <path
35
+ d="M12 22V7"
36
+ stroke="currentColor"
37
+ strokeWidth="1.5"
38
+ strokeLinecap="round"
39
+ strokeLinejoin="round"
40
+ />
41
+ </svg>
42
+ )
43
+
44
+ if (withAccessibility) {
45
+ return <AccessibleIcon label="Headphone Icon">{svg}</AccessibleIcon>
46
+ }
47
+
48
+ return svg
49
+ }
@@ -0,0 +1,8 @@
1
+ export const meta = {
2
+ dependencies: {
3
+ "@radix-ui/react-accessible-icon": "^1.1.7",
4
+ },
5
+ devDependencies: {},
6
+ internalDependencies: [],
7
+ tokens: [],
8
+ }
@@ -16,14 +16,16 @@ export * from "./bubble-crossed-icon"
16
16
  export * from "./bubble-sparkle-icon"
17
17
  export * from "./camera-icon"
18
18
  export * from "./capital-a-letter-icon"
19
+ export * from "./chain-link-icon"
19
20
  export * from "./chevron-double-left-icon"
20
21
  export * from "./chevron-double-right-icon"
21
22
  export * from "./chevron-down-icon"
22
23
  export * from "./chevron-left-icon"
23
- export * from "./circular-play-icon"
24
24
  export * from "./chevron-right-icon"
25
25
  export * from "./chevron-up-icon"
26
26
  export * from "./circle-tick-icon"
27
+ export * from "./circular-play-icon"
28
+ export * from "./clock-icon"
27
29
  export * from "./column-wide-add-icon"
28
30
  export * from "./coin-icon"
29
31
  export * from "./coin-toons-icon"
@@ -47,6 +49,7 @@ export * from "./globe-icon"
47
49
  export * from "./google-logo-icon"
48
50
  export * from "./grip-vertical-icon"
49
51
  export * from "./head-icon"
52
+ export * from "./headphone-icon"
50
53
  export * from "./heart-icon"
51
54
  export * from "./image-avatar-sparkle-icon"
52
55
  export * from "./image-icon"
@@ -103,6 +106,7 @@ export * from "./tick-circle-icon"
103
106
  export * from "./tick-icon"
104
107
  export * from "./trash-icon"
105
108
  export * from "./twitter-x-icon"
109
+ export * from "./underline-icon"
106
110
  export * from "./upload-icon"
107
111
  export * from "./vertical-menu-icon"
108
112
  export * from "./video-play-list-icon"