aural-ui 4.0.1 → 4.2.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.
Files changed (175) hide show
  1. package/README.md +8 -1
  2. package/dist/components/aspect-ratio/AspectRatio.stories.tsx +290 -1228
  3. package/dist/components/avatar/Avatar.stories.tsx +219 -235
  4. package/dist/components/badge/Badge.stories.tsx +379 -116
  5. package/dist/components/banner/Banner.stories.tsx +445 -391
  6. package/dist/components/breadcrumb/Breadcrumb.stories.tsx +453 -199
  7. package/dist/components/button/Button.stories.tsx +585 -230
  8. package/dist/components/card/Card.stories.tsx +619 -301
  9. package/dist/components/char-count/CharCount.stories.tsx +350 -248
  10. package/dist/components/checkbox/Checkbox.stories.tsx +309 -167
  11. package/dist/components/chip/Chip.stories.tsx +362 -168
  12. package/dist/components/circular-loader/CircularLoader.stories.tsx +221 -636
  13. package/dist/components/clamp-lines/ClampLines.stories.tsx +246 -117
  14. package/dist/components/collapsible/Collapsible.stories.tsx +391 -252
  15. package/dist/components/command/Command.stories.tsx +530 -867
  16. package/dist/components/dialog/Dialog.stories.tsx +501 -950
  17. package/dist/components/divider/Divider.stories.tsx +264 -527
  18. package/dist/components/dot-loader/DotLoader.stories.tsx +256 -257
  19. package/dist/components/drawer/Drawer.stories.tsx +659 -1023
  20. package/dist/components/dropdown/Dropdown.stories.tsx +643 -1028
  21. package/dist/components/form/Form.stories.tsx +560 -274
  22. package/dist/components/helper-text/HelperText.stories.tsx +199 -200
  23. package/dist/components/hover-card/HoverCard.stories.tsx +318 -1254
  24. package/dist/components/icon-button/IconButton.stories.tsx +837 -194
  25. package/dist/components/if-else/if-else.stories.tsx +370 -83
  26. package/dist/components/input/Input.stories.tsx +436 -368
  27. package/dist/components/label/Label.stories.tsx +156 -154
  28. package/dist/components/list/List.stories.tsx +484 -835
  29. package/dist/components/marquee/Marquee.stories.tsx +356 -712
  30. package/dist/components/otp-inputs/OtpInputs.stories.tsx +352 -422
  31. package/dist/components/overlay/Overlay.stories.tsx +452 -824
  32. package/dist/components/pagination/Pagination.stories.tsx +721 -210
  33. package/dist/components/popover/Popover.stories.tsx +481 -896
  34. package/dist/components/radio/Radio.stories.tsx +432 -124
  35. package/dist/components/resizable/Resizable.stories.tsx +495 -799
  36. package/dist/components/scroll-area/ScrollArea.stories.tsx +383 -1059
  37. package/dist/components/search/Search.stories.tsx +312 -595
  38. package/dist/components/select/Select.stories.tsx +684 -789
  39. package/dist/components/sheet/Sheet.stories.tsx +671 -950
  40. package/dist/components/skelton/Skelton.stories.tsx +230 -764
  41. package/dist/components/slider/Slider.stories.tsx +383 -760
  42. package/dist/components/stepper/Stepper.stories.tsx +371 -514
  43. package/dist/components/switch/Switch.stories.tsx +461 -208
  44. package/dist/components/switch-case/SwitchCase.stories.tsx +367 -188
  45. package/dist/components/table/Table.stories.tsx +770 -916
  46. package/dist/components/tabs/Tabs.stories.tsx +458 -1455
  47. package/dist/components/tag/Tag.stories.tsx +714 -542
  48. package/dist/components/textarea/TextArea.stories.tsx +621 -562
  49. package/dist/components/thumbnail-tags/ThumbnailTags.stories.tsx +228 -154
  50. package/dist/components/toast/Toast.stories.tsx +452 -1339
  51. package/dist/components/toggle/Toggle.stories.tsx +488 -931
  52. package/dist/components/tooltip/Tooltip.stories.tsx +344 -1388
  53. package/dist/components/typography/Typography.stories.tsx +406 -89
  54. package/dist/hooks/use-change-state/UseChangeState.stories.tsx +309 -606
  55. package/dist/hooks/use-previous/UsePrevious.stories.tsx +367 -917
  56. package/dist/hooks/use-standalone-pagination/UseStandalonePagination.stories.tsx +639 -867
  57. package/dist/icons/Icons.stories.tsx +0 -12
  58. package/dist/icons/ai-avatar-icon/AiAvatarIcon.stories.tsx +223 -1060
  59. package/dist/icons/alert-icon/AlertIcon.stories.tsx +106 -968
  60. package/dist/icons/all-icons.tsx +37 -16
  61. package/dist/icons/angle-down-icon/AngleDownIcon.stories.tsx +137 -1010
  62. package/dist/icons/apple-logo-icon/AppleLogoIcon.stories.tsx +145 -935
  63. package/dist/icons/arrow-box-left-icon/ArrowBoxLeftIcon.stories.tsx +132 -1046
  64. package/dist/icons/arrow-corner-up-left-icon/ArrowCornerUpLeftIcon.stories.tsx +134 -986
  65. package/dist/icons/arrow-corner-up-right-icon/ArrowCornerUpRightIcon.stories.tsx +135 -1028
  66. package/dist/icons/arrow-left-icon/ArrowLeftIcon.stories.tsx +133 -971
  67. package/dist/icons/arrow-right-icon/ArrowRightIcon.stories.tsx +145 -1123
  68. package/dist/icons/arrow-right-up-icon/ArrowRightUpIcon.stories.tsx +143 -1252
  69. package/dist/icons/art-board-icon/ArtBoardIcon.stories.tsx +123 -632
  70. package/dist/icons/audio-bar-icon/AudioBarIcon.stories.tsx +141 -1223
  71. package/dist/icons/backward-ten-seconds-icon/BackwardTenSecondsIcon.stories.tsx +164 -1018
  72. package/dist/icons/bubble-check-icon/BubbleCheckIcon.stories.tsx +121 -1236
  73. package/dist/icons/bubble-crossed-icon/BubbleCrossedIcon.stories.tsx +121 -1213
  74. package/dist/icons/bubble-sparkle-icon/BubbleSparkleIcon.stories.tsx +116 -893
  75. package/dist/icons/camera-icon/CameraIcon.stories.tsx +109 -1254
  76. package/dist/icons/capital-a-letter-icon/CapitalALetterIcon.stories.tsx +114 -975
  77. package/dist/icons/chevron-double-left-icon/ChevronDoubleLeftIcon.stories.tsx +157 -994
  78. package/dist/icons/chevron-double-right-icon/ChevronDoubleRightIcon.stories.tsx +160 -992
  79. package/dist/icons/chevron-down-icon/ChevronDownIcon.stories.tsx +140 -970
  80. package/dist/icons/chevron-left-icon/ChevronLeftIcon.stories.tsx +126 -993
  81. package/dist/icons/chevron-right-icon/ChevronRightIcon.stories.tsx +144 -987
  82. package/dist/icons/chevron-up-icon/ChevronUpIcon.stories.tsx +141 -1007
  83. package/dist/icons/circle-tick-icon/CircleTickIcon.stories.tsx +147 -1187
  84. package/dist/icons/circular-play-icon/CircularPlayIcon.stories.tsx +110 -476
  85. package/dist/icons/coin-icon/CoinIcon.stories.tsx +120 -1364
  86. package/dist/icons/coin-toons-icon/CoinToonsIcon.stories.tsx +113 -1360
  87. package/dist/icons/column-wide-add-icon/ColumnWideAddIcon.stories.tsx +111 -942
  88. package/dist/icons/command-icon/CommandIcon.stories.tsx +124 -1087
  89. package/dist/icons/copy-icon/CopyIcon.stories.tsx +119 -996
  90. package/dist/icons/cross-circle-icon/CrossCircleIcon.stories.tsx +144 -1046
  91. package/dist/icons/cross-icon/CrossIcon.stories.tsx +136 -999
  92. package/dist/icons/download-icon/DownloadIcon.stories.tsx +123 -857
  93. package/dist/icons/edit-big-icon/EditBigIcon.stories.tsx +121 -1080
  94. package/dist/icons/email-icon/EmailIcon.stories.tsx +112 -979
  95. package/dist/icons/expand-icon/ExpandIcon.stories.tsx +109 -1146
  96. package/dist/icons/eye-close-icon/EyeCloseIcon.stories.tsx +141 -1068
  97. package/dist/icons/eye-open-icon/EyeOpenIcon.stories.tsx +140 -1081
  98. package/dist/icons/feature-shine-icon/FeatureShineIcon.stories.tsx +124 -1050
  99. package/dist/icons/file-chart-icon/FileChartIcon.stories.tsx +123 -1091
  100. package/dist/icons/file-text-icon/FileTextIcon.stories.tsx +122 -633
  101. package/dist/icons/filter-bar-row-icon/FilterBarRowIcon.stories.tsx +116 -1087
  102. package/dist/icons/forward-ten-seconds-icon/ForwardTenSecondsIcon.stories.tsx +166 -1020
  103. package/dist/icons/git-branch-icon/GitBranchIcon.stories.tsx +112 -1182
  104. package/dist/icons/git-fork-icon/GitForkIcon.stories.tsx +112 -1155
  105. package/dist/icons/globe-icon/GlobeIcon.stories.tsx +127 -325
  106. package/dist/icons/google-logo-icon/GoogleLogoIcon.stories.tsx +142 -985
  107. package/dist/icons/grip-vertical-icon/GripVerticalIcon.stories.tsx +116 -1217
  108. package/dist/icons/head-icon/HeadIcon.stories.tsx +108 -953
  109. package/dist/icons/heart-icon/HeartIcon.stories.tsx +117 -1060
  110. package/dist/icons/image-avatar-sparkle-icon/ImageAvatarSparkleIcon.stories.tsx +116 -716
  111. package/dist/icons/image-icon/ImageIcon.stories.tsx +102 -1164
  112. package/dist/icons/import-folder-icon/ImportFolderIcon.stories.tsx +108 -1233
  113. package/dist/icons/import-left-arrow-folder-icon/ImportLeftArrowFolderIcon.stories.tsx +133 -1289
  114. package/dist/icons/indian-flag-icon/IndianFlagIcon.stories.tsx +155 -1012
  115. package/dist/icons/instagram-icon/InstagramIcon.stories.tsx +158 -1438
  116. package/dist/icons/layout-column-icon/LayoutColumnIcon.stories.tsx +121 -1011
  117. package/dist/icons/layout-left-icon/LayoutLeftIcon.stories.tsx +116 -981
  118. package/dist/icons/layout-right-icon/LayoutRightIcon.stories.tsx +116 -979
  119. package/dist/icons/light-bulb-simple-icon/LightBulbSimpleIcon.stories.tsx +105 -1252
  120. package/dist/icons/linked-in-icon/LinkedInIcon.stories.tsx +151 -1554
  121. package/dist/icons/magic-book-icon/MagicBookIcon.stories.tsx +107 -1227
  122. package/dist/icons/magic-edit-icon/MagicEditIcon.stories.tsx +116 -707
  123. package/dist/icons/maintenance-icon/MaintenanceIcon.stories.tsx +119 -1226
  124. package/dist/icons/message-icon/MessageIcon.stories.tsx +111 -557
  125. package/dist/icons/minimize-icon/MinimizeIcon.stories.tsx +112 -1198
  126. package/dist/icons/moon-icon/MoonIcon.stories.tsx +117 -557
  127. package/dist/icons/move-horizontal-icon/MoveHorizontalIcon.stories.tsx +106 -1235
  128. package/dist/icons/move-vertical-icon/MoveVerticalIcon.stories.tsx +112 -1185
  129. package/dist/icons/musical-note-icon/MusicalNoteIcon.stories.tsx +116 -1012
  130. package/dist/icons/notepad-icon/NotepadIcon.stories.tsx +108 -1137
  131. package/dist/icons/notes-icon/NotesIcon.stories.tsx +116 -1138
  132. package/dist/icons/page-search-icon/PageSearchIcon.stories.tsx +106 -1146
  133. package/dist/icons/page-text-icon/PageTextIcon.stories.tsx +119 -719
  134. package/dist/icons/paint-roll-icon/PaintRollIcon.stories.tsx +110 -999
  135. package/dist/icons/paper-plane-icon/PaperPlaneIcon.stories.tsx +109 -912
  136. package/dist/icons/pause-icon/PauseIcon.stories.tsx +110 -1041
  137. package/dist/icons/pencil-icon/PencilIcon.stories.tsx +112 -1109
  138. package/dist/icons/phone-icon/PhoneIcon.stories.tsx +112 -1023
  139. package/dist/icons/plus-icon/PlusIcon.stories.tsx +103 -1132
  140. package/dist/icons/pocket-studio-icon/PocketStudioIcon.stories.tsx +104 -870
  141. package/dist/icons/scroll-down-icon/ScrollDownIcon.stories.tsx +99 -476
  142. package/dist/icons/search-icon/SearchIcon.stories.tsx +108 -1161
  143. package/dist/icons/setting-icon/SettingIcon.stories.tsx +104 -1009
  144. package/dist/icons/share-icon/ShareIcon.stories.tsx +117 -1064
  145. package/dist/icons/shield-icon/ShieldIcon.stories.tsx +114 -974
  146. package/dist/icons/site-logo-icon/SiteLogoIcon.stories.tsx +134 -1160
  147. package/dist/icons/skip-backward-icon/SkipBackwardIcon.stories.tsx +169 -1017
  148. package/dist/icons/skip-forward-icon/SkipForwardIcon.stories.tsx +161 -1016
  149. package/dist/icons/sparkles-soft-icon/SparklesSoftIcon.stories.tsx +102 -1001
  150. package/dist/icons/spinner-gradient-icon/SpinnerGradientIcon.stories.tsx +155 -593
  151. package/dist/icons/spinner-solid-icon/SpinnerSolidIcon.stories.tsx +155 -608
  152. package/dist/icons/spinner-solid-neutral-icon/SpinnerSolidINeutralcon.stories.tsx +142 -712
  153. package/dist/icons/star-icon/StarIcon.stories.tsx +120 -946
  154. package/dist/icons/store-coin-icon/StoreCoinIcon.stories.tsx +109 -1013
  155. package/dist/icons/suggestion-icon/SuggestionIcon.stories.tsx +113 -891
  156. package/dist/icons/sun-icon/SunIcon.stories.tsx +117 -864
  157. package/dist/icons/text-color-icon/TextColorIcon.stories.tsx +113 -989
  158. package/dist/icons/text-indicator-icon/TextIndicatorIcon.stories.tsx +120 -1027
  159. package/dist/icons/threads-icon/ThreadsIcon.stories.tsx +153 -1476
  160. package/dist/icons/tick-circle-icon/TickCircleIcon.stories.tsx +143 -1187
  161. package/dist/icons/tick-icon/TickIcon.stories.tsx +142 -1322
  162. package/dist/icons/trash-icon/TrashIcon.stories.tsx +105 -970
  163. package/dist/icons/twitter-x-icon/TwitterXIcon.stories.tsx +154 -1457
  164. package/dist/icons/upload-icon/UploadIcon.stories.tsx +112 -930
  165. package/dist/icons/vertical-menu-icon/VerticalMenuIcon.stories.tsx +115 -1019
  166. package/dist/icons/video-play-list-icon/VideoPlaylistIcon.stories.tsx +122 -1092
  167. package/dist/icons/voice-playing-icon/VoicePlayingIcon.stories.tsx +120 -1401
  168. package/dist/icons/volume-full-icon/VolumeFullIcon.stories.tsx +107 -1212
  169. package/dist/icons/volume-half-icon/VolumeHalfIcon.stories.tsx +109 -1122
  170. package/dist/icons/volume-off-icon/VolumeOffIcon.stories.tsx +112 -1124
  171. package/dist/icons/warning-icon/WarningIcon.stories.tsx +119 -1083
  172. package/dist/icons/youtube-icon/YoutubeIcon.stories.tsx +158 -983
  173. package/dist/index.cjs +90 -90
  174. package/dist/index.js +90 -90
  175. package/package.json +8 -3
@@ -1,10 +1,10 @@
1
- import React from "react"
1
+ import React, { useState } from "react"
2
2
  import { Button } from "@components/button"
3
3
  import Input from "@components/input"
4
4
  import { Label } from "@components/label"
5
5
  import type { Meta, StoryObj } from "@storybook/react-vite"
6
6
 
7
- import { FeatureShineIcon } from "src/ui/icons"
7
+ import { AuralComponentDocsPage } from "src/ui/story-spec/components/component-story-docs-page"
8
8
 
9
9
  import {
10
10
  Popover,
@@ -14,43 +14,35 @@ import {
14
14
  PopoverContent,
15
15
  PopoverTrigger,
16
16
  } from "."
17
- import { IconButton } from "../icon-button"
18
17
 
19
18
  const meta: Meta<typeof Popover> = {
20
19
  title: "Components/UI/Popover",
21
20
  component: Popover,
22
21
  parameters: {
23
22
  layout: "centered",
24
- backgrounds: {
25
- default: "dark",
26
- values: [
27
- { name: "dark", value: "#0a0a0a" },
28
- { name: "light", value: "#ffffff" },
29
- ],
30
- },
31
23
  docs: {
32
24
  description: {
33
- component: `
34
- A comprehensive popover component system built on Radix UI with dark theme optimization.
35
-
36
- ## Components Overview
37
-
38
- - **Popover**: Root container managing state and context
39
- - **PopoverTrigger**: Interactive element that opens the popover
40
- - **PopoverContent**: The floating content panel with frosted glass effect
41
- - **PopoverAnchor**: Custom positioning anchor point
42
- - **PopoverArrow**: Optional arrow pointer to trigger
43
- - **PopoverClose**: Button to close popover from within content
44
-
45
- ## Features
46
- - Dark theme optimized with frosted glass effect
47
- - Smooth CSS animations with direction awareness
48
- - Comprehensive accessibility support
49
- - Flexible positioning and anchoring
50
- - Self-contained content management
51
- - Portal rendering for proper stacking
52
- `,
25
+ component:
26
+ "A compound floating panel built on Radix UI. Composed of Popover (root state), PopoverTrigger (toggle element), PopoverContent (frosted-glass panel with gradient top stroke), PopoverClose (dismiss button inside content), PopoverArrow (optional pointer), and PopoverAnchor (custom positioning reference). Portal-rendered for proper z-index stacking.",
53
27
  },
28
+ page: () => (
29
+ <AuralComponentDocsPage
30
+ features={[
31
+ {
32
+ title: "Floating Panel",
33
+ description: "Portal z-index layering",
34
+ },
35
+ {
36
+ title: "Compound Parts",
37
+ description: "Trigger, content, arrow",
38
+ },
39
+ {
40
+ title: "Glass Aesthetic",
41
+ description: "Frosted top gradient",
42
+ },
43
+ ]}
44
+ />
45
+ ),
54
46
  },
55
47
  },
56
48
  tags: ["autodocs"],
@@ -59,1005 +51,598 @@ A comprehensive popover component system built on Radix UI with dark theme optim
59
51
  export default meta
60
52
  type Story = StoryObj<typeof meta>
61
53
 
62
- // 1. Popover Root Component Example
63
- export const PopoverRoot: Story = {
64
- render: () => (
65
- <div className="space-y-4">
66
- <div className="text-center">
67
- <h3 className="text-fm-primary mb-2 font-medium">
68
- Popover Root Component
69
- </h3>
70
- <p className="text-fm-secondary text-sm">
71
- The root Popover component manages state and provides context
72
- </p>
73
- </div>
74
-
75
- <div className="flex justify-center gap-4">
76
- {/* Uncontrolled Popover */}
77
- <Popover>
78
- <PopoverTrigger asChild>
79
- <Button variant="outline">Uncontrolled</Button>
80
- </PopoverTrigger>
81
- <PopoverContent className="border-fm-divider-secondary rounded-lg border shadow-2xl">
82
- <div className="p-4">
83
- <p className="text-fm-primary text-sm">
84
- This popover manages its own open/close state internally.
85
- </p>
86
- </div>
87
- </PopoverContent>
88
- </Popover>
54
+ // ─── Parts ───────────────────────────────────────────────────────────────────
89
55
 
90
- {/* Controlled Popover */}
91
- <Popover defaultOpen={false}>
92
- <PopoverTrigger asChild>
93
- <Button variant="outline">Default Closed</Button>
94
- </PopoverTrigger>
95
- <PopoverContent className="border-fm-divider-secondary rounded-lg border shadow-2xl">
96
- <div className="p-4">
97
- <p className="text-fm-primary text-sm">
98
- This popover starts in a closed state by default.
99
- </p>
100
- </div>
101
- </PopoverContent>
102
- </Popover>
103
-
104
- {/* Modal Popover */}
105
- <Popover modal>
106
- <PopoverTrigger asChild>
107
- <Button variant="outline">Modal Mode</Button>
108
- </PopoverTrigger>
109
- <PopoverContent className="border-fm-divider-secondary rounded-lg border shadow-2xl">
110
- <div className="p-4">
111
- <p className="text-fm-primary text-sm">
112
- This is a modal popover that captures focus and blocks
113
- interaction.
114
- </p>
115
- </div>
116
- </PopoverContent>
117
- </Popover>
118
- </div>
119
- </div>
120
- ),
56
+ export const Parts: Story = {
121
57
  parameters: {
122
58
  docs: {
123
59
  description: {
124
60
  story:
125
- "The Popover root component with different configuration options: uncontrolled, default state, and modal behavior.",
61
+ "Every sub-component shown individually with a description of its role in the compound pattern.",
126
62
  },
127
63
  },
128
64
  },
129
- }
130
-
131
- // 2. PopoverTrigger Component Examples
132
- export const PopoverTriggerVariants: Story = {
133
65
  render: () => (
134
- <div className="space-y-6">
135
- <div className="text-center">
136
- <h3 className="text-fm-primary mb-2 font-medium">
137
- PopoverTrigger Variants
138
- </h3>
139
- <p className="text-fm-secondary text-sm">
140
- Different types of trigger elements using asChild prop
141
- </p>
142
- </div>
143
-
144
- <div className="grid grid-cols-2 gap-4">
145
- {/* Button Trigger */}
66
+ <div className="w-full max-w-2xl space-y-10">
67
+ {/* PopoverTrigger */}
68
+ <div className="space-y-3">
69
+ <h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
70
+ PopoverTrigger
71
+ </h4>
146
72
  <Popover>
147
73
  <PopoverTrigger asChild>
148
- <Button>Button Trigger</Button>
74
+ <Button variant="outline">Open Popover</Button>
149
75
  </PopoverTrigger>
150
- <PopoverContent className="border-fm-divider-secondary rounded-lg border shadow-2xl">
151
- <div className="p-3">
152
- <p className="text-fm-primary text-sm">
153
- Triggered by a Button component
154
- </p>
155
- </div>
76
+ <PopoverContent className="rounded-lg p-4">
77
+ <p className="text-fm-primary font-fm-text text-fm-sm leading-fm-sm">
78
+ Triggered by the button above.
79
+ </p>
156
80
  </PopoverContent>
157
81
  </Popover>
82
+ <div className="border-fm-divider-secondary bg-fm-surface-secondary rounded-lg border p-4">
83
+ <p className="text-fm-secondary font-fm-text text-fm-md leading-fm-xl">
84
+ The element that toggles the popover open/closed. Pass{" "}
85
+ <code>asChild</code> to render as any child element. Without{" "}
86
+ <code>asChild</code> it renders a plain <code>&lt;button&gt;</code>.
87
+ </p>
88
+ </div>
89
+ </div>
158
90
 
159
- {/* Text Link Trigger */}
160
- <Popover>
91
+ {/* PopoverContent */}
92
+ <div className="space-y-3">
93
+ <h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
94
+ PopoverContent
95
+ </h4>
96
+ <Popover defaultOpen>
161
97
  <PopoverTrigger asChild>
162
- <Button
163
- variant="text"
164
- className="text-fm-info hover:text-fm-info-sec text-sm underline"
165
- >
166
- Click this link
167
- </Button>
98
+ <Button variant="outline">Content panel (open)</Button>
168
99
  </PopoverTrigger>
169
- <PopoverContent className="border-fm-divider-secondary rounded-lg border shadow-2xl">
170
- <div className="p-3">
171
- <p className="text-fm-primary text-sm">
172
- Triggered by a text link
173
- </p>
174
- </div>
100
+ <PopoverContent className="rounded-lg p-4">
101
+ <p className="text-fm-primary font-fm-text text-fm-sm leading-fm-sm">
102
+ Frosted-glass panel with a gradient top stroke. Default width{" "}
103
+ <code>w-72</code>, max height <code>max-h-96</code>. Rendered in a
104
+ portal — safe across any stacking context.
105
+ </p>
175
106
  </PopoverContent>
176
107
  </Popover>
108
+ <div className="border-fm-divider-secondary bg-fm-surface-secondary rounded-lg border p-4">
109
+ <p className="text-fm-secondary font-fm-text text-fm-md leading-fm-xl">
110
+ Accepts <code>align</code> (start / center / end), <code>side</code>{" "}
111
+ (top / right / bottom / left), and <code>sideOffset</code>. The
112
+ gradient top-stroke is always rendered automatically.
113
+ </p>
114
+ </div>
115
+ </div>
177
116
 
178
- {/* Icon Trigger */}
179
- <Popover>
117
+ {/* PopoverClose */}
118
+ <div className="space-y-3">
119
+ <h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
120
+ PopoverClose
121
+ </h4>
122
+ <Popover defaultOpen>
180
123
  <PopoverTrigger asChild>
181
- <IconButton
182
- label="Icon Popover Button"
183
- icon={<FeatureShineIcon />}
184
- />
124
+ <Button variant="outline">Open (with close button)</Button>
185
125
  </PopoverTrigger>
186
- <PopoverContent className="border-fm-divider-secondary rounded-lg border shadow-2xl">
187
- <div className="p-3">
188
- <p className="text-fm-primary text-sm">
189
- Triggered by an icon button
126
+ <PopoverContent className="rounded-lg p-4">
127
+ <div className="flex items-center justify-between gap-4">
128
+ <p className="text-fm-primary font-fm-text text-fm-sm leading-fm-sm">
129
+ Click × to dismiss.
190
130
  </p>
131
+ <PopoverClose asChild>
132
+ <Button variant="text" size="sm">
133
+ ×
134
+ </Button>
135
+ </PopoverClose>
191
136
  </div>
192
137
  </PopoverContent>
193
138
  </Popover>
139
+ <div className="border-fm-divider-secondary bg-fm-surface-secondary rounded-lg border p-4">
140
+ <p className="text-fm-secondary font-fm-text text-fm-md leading-fm-xl">
141
+ Closes the popover from within the content panel. Use with{" "}
142
+ <code>asChild</code> to render as any button or icon. Must be placed
143
+ inside <code>PopoverContent</code>.
144
+ </p>
145
+ </div>
146
+ </div>
194
147
 
195
- {/* Image Trigger */}
196
- <Popover>
148
+ {/* PopoverArrow */}
149
+ <div className="space-y-3">
150
+ <h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
151
+ PopoverArrow
152
+ </h4>
153
+ <Popover defaultOpen>
197
154
  <PopoverTrigger asChild>
198
- <IconButton
199
- label="Profile Popover"
200
- icon={null}
201
- className="overflow-hidden"
202
- >
203
- <img
204
- src="https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?w=40&h=40&fit=crop&crop=face"
205
- alt="Profile"
206
- className="h-12 w-12 object-cover"
207
- />
208
- </IconButton>
155
+ <Button variant="outline">Open (with arrow)</Button>
209
156
  </PopoverTrigger>
210
- <PopoverContent className="border-fm-divider-secondary rounded-lg border shadow-2xl">
211
- <div className="p-3">
212
- <p className="text-fm-primary text-sm">
213
- Triggered by an avatar image
214
- </p>
215
- </div>
157
+ <PopoverContent className="rounded-lg p-4" sideOffset={8}>
158
+ <p className="text-fm-primary font-fm-text text-fm-sm leading-fm-sm">
159
+ An arrow points back at the trigger.
160
+ </p>
161
+ <PopoverArrow className="fill-fm-surface-frosted/20" />
216
162
  </PopoverContent>
217
163
  </Popover>
164
+ <div className="border-fm-divider-secondary bg-fm-surface-secondary rounded-lg border p-4">
165
+ <p className="text-fm-secondary font-fm-text text-fm-md leading-fm-xl">
166
+ Optional SVG arrow rendered inside <code>PopoverContent</code>.
167
+ Inherits positioning from the content and rotates automatically
168
+ based on side.
169
+ </p>
170
+ </div>
171
+ </div>
172
+
173
+ {/* PopoverAnchor */}
174
+ <div className="space-y-3">
175
+ <h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
176
+ PopoverAnchor
177
+ </h4>
178
+ <Popover defaultOpen>
179
+ <div className="flex items-center gap-4">
180
+ <PopoverAnchor asChild>
181
+ <div className="border-fm-divider-secondary rounded-lg border px-4 py-2">
182
+ <span className="text-fm-tertiary font-fm-text text-fm-sm leading-fm-sm">
183
+ Anchor element
184
+ </span>
185
+ </div>
186
+ </PopoverAnchor>
187
+ <PopoverTrigger asChild>
188
+ <Button variant="outline" size="sm">
189
+ Trigger
190
+ </Button>
191
+ </PopoverTrigger>
192
+ </div>
193
+ <PopoverContent className="rounded-lg p-4">
194
+ <p className="text-fm-primary font-fm-text text-fm-sm leading-fm-sm">
195
+ Positioned relative to the anchor box, not the trigger.
196
+ </p>
197
+ </PopoverContent>
198
+ </Popover>
199
+ <div className="border-fm-divider-secondary bg-fm-surface-secondary rounded-lg border p-4">
200
+ <p className="text-fm-secondary font-fm-text text-fm-md leading-fm-xl">
201
+ Decouples the visual anchor from the trigger. The popover positions
202
+ itself relative to <code>PopoverAnchor</code> while the trigger
203
+ retains click behavior. Useful for inline text flows or custom
204
+ layouts.
205
+ </p>
206
+ </div>
218
207
  </div>
219
208
  </div>
220
209
  ),
210
+ }
211
+
212
+ // ─── Configurations ──────────────────────────────────────────────────────────
213
+
214
+ export const Configurations: Story = {
221
215
  parameters: {
222
216
  docs: {
223
217
  description: {
224
218
  story:
225
- "PopoverTrigger examples showing different interactive elements: buttons, links, icons, and images.",
219
+ "Positioning axes (side + align), sideOffset values, with close button, with arrow, and the anchored variant — all as live examples.",
226
220
  },
227
221
  },
228
222
  },
229
- }
230
-
231
- // 3. PopoverContent Component Examples
232
- export const PopoverContentVariants: Story = {
233
223
  render: () => (
234
- <div className="space-y-6">
235
- <div className="text-center">
236
- <h3 className="text-fm-primary mb-2 font-medium">
237
- PopoverContent Variants
238
- </h3>
239
- <p className="text-fm-secondary text-sm">
240
- Different content layouts and styling options
241
- </p>
242
- </div>
243
-
244
- <div className="flex flex-wrap justify-center gap-4">
245
- {/* Simple Content */}
246
- <Popover>
247
- <PopoverTrigger asChild>
248
- <Button variant="outline" size="sm">
249
- Simple Content
250
- </Button>
251
- </PopoverTrigger>
252
- <PopoverContent className="border-fm-divider-secondary w-56 rounded-lg border shadow-2xl">
253
- <div className="p-3">
254
- <p className="text-fm-primary text-sm">
255
- Simple text content in a popover.
256
- </p>
257
- </div>
258
- </PopoverContent>
259
- </Popover>
260
-
261
- {/* Rich Content */}
262
- <Popover>
263
- <PopoverTrigger asChild>
264
- <Button variant="outline" size="sm">
265
- Rich Content
266
- </Button>
267
- </PopoverTrigger>
268
- <PopoverContent className="border-fm-divider-secondary w-72 rounded-lg border shadow-2xl">
269
- <div className="space-y-3 p-4">
270
- <div className="flex items-center gap-3">
271
- <div className="flex h-10 w-10 items-center justify-center rounded-full bg-blue-600">
272
- <span className="text-fm-primary text-sm font-medium">
273
- JD
274
- </span>
275
- </div>
276
- <div>
277
- <h4 className="text-fm-primary font-medium">John Doe</h4>
278
- <p className="text-fm-secondary text-xs">
279
- Software Developer
224
+ <div className="w-full max-w-3xl space-y-8">
225
+ {/* Side positioning */}
226
+ <div className="space-y-4">
227
+ <h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
228
+ Side — side prop
229
+ </h4>
230
+ <div className="flex flex-wrap justify-center gap-4">
231
+ {(["top", "right", "bottom", "left"] as const).map((side) => (
232
+ <div key={side} className="space-y-2 text-center">
233
+ <Popover>
234
+ <PopoverTrigger asChild>
235
+ <Button variant="outline" size="sm">
236
+ {side}
237
+ </Button>
238
+ </PopoverTrigger>
239
+ <PopoverContent side={side} className="w-40 rounded-lg p-3">
240
+ <p className="text-fm-primary font-fm-text text-fm-sm leading-fm-sm">
241
+ Opens to the <strong>{side}</strong>.
280
242
  </p>
281
- </div>
282
- </div>
283
- <p className="text-fm-secondary text-sm">
284
- Rich content with avatar, title, and description.
243
+ </PopoverContent>
244
+ </Popover>
245
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
246
+ {side}
285
247
  </p>
286
248
  </div>
287
- </PopoverContent>
288
- </Popover>
289
-
290
- {/* Custom Styled Content */}
291
- <Popover>
292
- <PopoverTrigger asChild>
293
- <Button variant="outline" size="sm">
294
- Custom Style
295
- </Button>
296
- </PopoverTrigger>
297
- <PopoverContent className="w-64 rounded-lg border border-purple-500/30 bg-gradient-to-b from-purple-900/90 to-blue-900/90 shadow-2xl">
298
- <div className="p-4">
299
- <h4 className="text-fm-primary mb-2 font-medium">Custom Theme</h4>
300
- <p className="text-fm-secondary text-sm">
301
- PopoverContent with custom gradient background and purple theme.
302
- </p>
303
- </div>
304
- </PopoverContent>
305
- </Popover>
249
+ ))}
250
+ </div>
251
+ </div>
306
252
 
307
- {/* No Border Content */}
308
- <Popover>
309
- <PopoverTrigger asChild>
310
- <Button variant="outline" size="sm">
311
- No Border
312
- </Button>
313
- </PopoverTrigger>
314
- <PopoverContent className="bg-fm-surface-primary w-56 rounded-xl shadow-2xl">
315
- <div className="p-4">
316
- <p className="text-fm-primary text-sm">
317
- Content without border, just shadow and background.
253
+ {/* Alignment */}
254
+ <div className="space-y-4">
255
+ <h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
256
+ Alignment align prop
257
+ </h4>
258
+ <div className="flex flex-wrap justify-center gap-4">
259
+ {(["start", "center", "end"] as const).map((align) => (
260
+ <div key={align} className="space-y-2 text-center">
261
+ <Popover>
262
+ <PopoverTrigger asChild>
263
+ <Button variant="outline" size="sm">
264
+ {align}
265
+ </Button>
266
+ </PopoverTrigger>
267
+ <PopoverContent align={align} className="rounded-lg p-3">
268
+ <p className="text-fm-primary font-fm-text text-fm-sm leading-fm-sm">
269
+ Aligned <strong>{align}</strong> to trigger.
270
+ </p>
271
+ </PopoverContent>
272
+ </Popover>
273
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
274
+ {align}
318
275
  </p>
319
276
  </div>
320
- </PopoverContent>
321
- </Popover>
322
- </div>
323
- </div>
324
- ),
325
- parameters: {
326
- docs: {
327
- description: {
328
- story:
329
- "PopoverContent examples with different styling approaches: simple, rich content, custom themes, and borderless variants.",
330
- },
331
- },
332
- },
333
- }
334
-
335
- // 4. PopoverAnchor Component Example
336
- export const PopoverAnchorExample: Story = {
337
- render: () => {
338
- const [anchorEl, setAnchorEl] = React.useState<HTMLDivElement | null>(null)
339
-
340
- return (
341
- <div className="space-y-6">
342
- <div className="text-center">
343
- <h3 className="text-fm-primary mb-2 font-medium">
344
- PopoverAnchor Component
345
- </h3>
346
- <p className="text-fm-secondary text-sm">
347
- Position popover relative to a different element than the trigger
348
- </p>
277
+ ))}
349
278
  </div>
279
+ </div>
350
280
 
351
- <div className="flex items-center justify-center gap-8">
352
- {/* Anchor Target */}
353
- <div
354
- ref={setAnchorEl}
355
- className="flex h-20 w-20 items-center justify-center rounded-lg border-2 border-dashed border-blue-400 bg-gradient-to-br from-blue-500 to-purple-600"
356
- >
357
- <span className="text-fm-primary text-center text-xs font-medium">
358
- Anchor
359
- <br />
360
- Point
361
- </span>
362
- </div>
363
-
364
- {/* Trigger (separate from anchor) */}
281
+ {/* With close button */}
282
+ <div className="space-y-4">
283
+ <h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
284
+ With Close Button
285
+ </h4>
286
+ <div className="flex justify-center">
365
287
  <Popover>
366
- <PopoverAnchor
367
- style={{
368
- position: "absolute",
369
- left: anchorEl?.offsetLeft || 0,
370
- top: anchorEl?.offsetTop || 0,
371
- width: anchorEl?.offsetWidth || 0,
372
- height: anchorEl?.offsetHeight || 0,
373
- }}
374
- />
375
288
  <PopoverTrigger asChild>
376
- <Button variant="outline">Open at Anchor</Button>
289
+ <Button variant="outline">Open panel</Button>
377
290
  </PopoverTrigger>
378
- <PopoverContent className="border-fm-divider-secondary rounded-lg border shadow-2xl">
379
- <PopoverArrow className="fill-white/10" />
380
- <div className="space-y-2 p-4">
381
- <h4 className="text-fm-primary font-medium">
382
- Anchored Popover
383
- </h4>
384
- <p className="text-fm-secondary text-sm">
385
- This popover is positioned relative to the blue anchor box,
386
- not the trigger button.
387
- </p>
388
- <div className="bg-fm-surface-secondary text-fm-tertiary rounded p-2 text-xs">
389
- <strong>Note:</strong> The popover appears near the anchor
390
- point even though the trigger is elsewhere.
291
+ <PopoverContent className="w-64 rounded-lg p-4">
292
+ <div className="flex items-start justify-between gap-3">
293
+ <div className="space-y-1">
294
+ <p className="text-fm-primary font-fm-text text-fm-md leading-fm-md font-semibold">
295
+ Quick note
296
+ </p>
297
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
298
+ Dismiss with the × button.
299
+ </p>
391
300
  </div>
301
+ <PopoverClose asChild>
302
+ <button className="text-fm-tertiary hover:text-fm-primary text-lg leading-none transition-colors outline-none">
303
+ ×
304
+ </button>
305
+ </PopoverClose>
392
306
  </div>
393
307
  </PopoverContent>
394
308
  </Popover>
395
309
  </div>
396
-
397
- {/* Multiple Anchors Example */}
398
- <div className="mt-8">
399
- <h4 className="text-fm-primary mb-4 text-center font-medium">
400
- Multiple Anchor Points
401
- </h4>
402
- <div className="flex justify-center gap-4">
403
- {["Anchor A", "Anchor B", "Anchor C"].map((label) => {
404
- const [anchor, setAnchor] = React.useState<HTMLDivElement | null>(
405
- null
406
- )
407
-
408
- return (
409
- <div key={label} className="space-y-2 text-center">
410
- <div
411
- ref={setAnchor}
412
- className="flex h-16 w-16 items-center justify-center rounded-lg border border-green-400 bg-green-600"
413
- >
414
- <span className="text-fm-primary text-xs font-medium">
415
- {label}
416
- </span>
417
- </div>
418
-
419
- <Popover>
420
- <PopoverAnchor
421
- style={{
422
- position: "absolute",
423
- left: anchor?.offsetLeft || 0,
424
- top: anchor?.offsetTop || 0,
425
- width: anchor?.offsetWidth || 0,
426
- height: anchor?.offsetHeight || 0,
427
- }}
428
- />
429
- <PopoverTrigger asChild>
430
- <Button size="sm" variant="outline">
431
- Open {label}
432
- </Button>
433
- </PopoverTrigger>
434
- <PopoverContent className="border-fm-divider-secondary rounded-lg border shadow-2xl">
435
- <div className="p-3">
436
- <p className="text-fm-primary text-sm">
437
- Content for {label}
438
- </p>
439
- </div>
440
- </PopoverContent>
441
- </Popover>
442
- </div>
443
- )
444
- })}
445
- </div>
446
- </div>
447
310
  </div>
448
- )
449
- },
450
- parameters: {
451
- docs: {
452
- description: {
453
- story:
454
- "PopoverAnchor examples showing how to position popovers relative to different elements than their triggers, including single and multiple anchor scenarios.",
455
- },
456
- },
457
- },
458
- }
459
311
 
460
- // 5. PopoverArrow Component Examples
461
- export const PopoverArrowVariants: Story = {
462
- render: () => (
463
- <div className="space-y-6">
464
- <div className="text-center">
465
- <h3 className="text-fm-primary mb-2 font-medium">
466
- PopoverArrow Variants
467
- </h3>
468
- <p className="text-fm-secondary text-sm">
469
- Different arrow styles and positioning options
470
- </p>
471
- </div>
472
-
473
- <div className="grid grid-cols-2 gap-6">
474
- {/* Default Arrow */}
475
- <Popover>
476
- <PopoverTrigger asChild>
477
- <Button variant="outline">Default Arrow</Button>
478
- </PopoverTrigger>
479
- <PopoverContent className="border-fm-divider-secondary rounded-lg border shadow-2xl">
480
- <PopoverArrow className="fill-white/10" />
481
- <div className="p-3">
482
- <p className="text-fm-primary text-sm">
483
- Default semi-transparent arrow
484
- </p>
485
- </div>
486
- </PopoverContent>
487
- </Popover>
488
-
489
- {/* Solid Arrow */}
490
- <Popover>
491
- <PopoverTrigger asChild>
492
- <Button variant="outline">Solid Arrow</Button>
493
- </PopoverTrigger>
494
- <PopoverContent className="bg-fm-surface-primary rounded-lg border border-gray-600 shadow-2xl">
495
- <PopoverArrow className="fill-gray-800" />
496
- <div className="p-3">
497
- <p className="text-fm-primary text-sm">
498
- Solid arrow matching background
499
- </p>
500
- </div>
501
- </PopoverContent>
502
- </Popover>
503
-
504
- {/* Colored Arrow */}
505
- <Popover>
506
- <PopoverTrigger asChild>
507
- <Button variant="outline">Colored Arrow</Button>
508
- </PopoverTrigger>
509
- <PopoverContent className="rounded-lg border border-blue-700 bg-blue-900 shadow-2xl">
510
- <PopoverArrow className="fill-blue-700" />
511
- <div className="p-3">
512
- <p className="text-fm-primary text-sm">
513
- Colored arrow with theme accent
514
- </p>
515
- </div>
516
- </PopoverContent>
517
- </Popover>
518
-
519
- {/* Large Arrow */}
520
- <Popover>
521
- <PopoverTrigger asChild>
522
- <Button variant="outline">Large Arrow</Button>
523
- </PopoverTrigger>
524
- <PopoverContent className="border-fm-divider-secondary rounded-lg border shadow-2xl">
525
- <PopoverArrow className="h-4 w-4 fill-white/10" />
526
- <div className="p-3">
527
- <p className="text-fm-primary text-sm">Larger arrow size</p>
528
- </div>
529
- </PopoverContent>
530
- </Popover>
531
-
532
- {/* Gradient Arrow */}
533
- <Popover>
534
- <PopoverTrigger asChild>
535
- <Button variant="outline">Gradient Arrow</Button>
536
- </PopoverTrigger>
537
- <PopoverContent className="rounded-lg border border-purple-600 bg-gradient-to-b from-purple-800 to-pink-800 shadow-2xl">
538
- <PopoverArrow className="fill-purple-700" />
539
- <div className="p-3">
540
- <p className="text-fm-primary text-sm">
541
- Arrow with gradient background
312
+ {/* With arrow */}
313
+ <div className="space-y-4">
314
+ <h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
315
+ With Arrow
316
+ </h4>
317
+ <div className="flex justify-center">
318
+ <Popover>
319
+ <PopoverTrigger asChild>
320
+ <Button variant="outline">Open with arrow</Button>
321
+ </PopoverTrigger>
322
+ <PopoverContent className="w-56 rounded-lg p-4" sideOffset={10}>
323
+ <p className="text-fm-primary font-fm-text text-fm-sm leading-fm-sm">
324
+ The arrow points back at the trigger.
542
325
  </p>
543
- </div>
544
- </PopoverContent>
545
- </Popover>
546
-
547
- {/* No Arrow */}
548
- <Popover>
549
- <PopoverTrigger asChild>
550
- <Button variant="outline">No Arrow</Button>
551
- </PopoverTrigger>
552
- <PopoverContent className="border-fm-divider-secondary rounded-lg border shadow-2xl">
553
- <div className="p-3">
554
- <p className="text-fm-primary text-sm">Popover without arrow</p>
555
- </div>
556
- </PopoverContent>
557
- </Popover>
326
+ <PopoverArrow className="fill-fm-surface-frosted/20" />
327
+ </PopoverContent>
328
+ </Popover>
329
+ </div>
558
330
  </div>
559
331
 
560
- {/* Arrow Positioning */}
561
- <div className="mt-8">
562
- <h4 className="text-fm-primary mb-4 text-center font-medium">
563
- Arrow Positioning
332
+ {/* Anchored variant */}
333
+ <div className="space-y-4">
334
+ <h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
335
+ Anchored Variant
564
336
  </h4>
565
- <div className="flex justify-center gap-4">
566
- {(["top", "right", "bottom", "left"] as const).map((side) => (
567
- <Popover key={side}>
337
+ <div className="flex justify-center">
338
+ <Popover>
339
+ <div className="flex items-center gap-3">
340
+ <PopoverAnchor asChild>
341
+ <div className="border-fm-divider-secondary min-w-32 rounded-lg border px-3 py-2">
342
+ <span className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
343
+ Search field
344
+ </span>
345
+ </div>
346
+ </PopoverAnchor>
568
347
  <PopoverTrigger asChild>
569
- <Button variant="outline" size="sm">
570
- {side}
571
- </Button>
348
+ <Button size="sm">Suggest</Button>
572
349
  </PopoverTrigger>
573
- <PopoverContent
574
- side={side}
575
- className="border-fm-divider-secondary rounded-lg border shadow-2xl"
576
- >
577
- <PopoverArrow className="fill-white/10" />
578
- <div className="p-3">
579
- <p className="text-fm-primary text-sm">Arrow on {side}</p>
580
- </div>
581
- </PopoverContent>
582
- </Popover>
583
- ))}
350
+ </div>
351
+ <PopoverContent className="w-64 rounded-lg p-4">
352
+ <p className="text-fm-primary font-fm-text text-fm-sm leading-fm-sm">
353
+ Positioned over the anchor, not the trigger button.
354
+ </p>
355
+ </PopoverContent>
356
+ </Popover>
584
357
  </div>
585
358
  </div>
586
359
  </div>
587
360
  ),
361
+ }
362
+
363
+ // ─── Interactive ──────────────────────────────────────────────────────────────
364
+
365
+ export const Interactive: Story = {
588
366
  parameters: {
589
367
  docs: {
590
368
  description: {
591
369
  story:
592
- "PopoverArrow examples showing different styling options: default, solid, colored, large, gradient, and positioning on different sides.",
370
+ "Live popovers with action panels inside add to playlist and share options demonstrating real audio-app workflows with controlled state.",
593
371
  },
594
372
  },
595
373
  },
596
- }
597
-
598
- // 6. PopoverClose Component Examples
599
- export const PopoverCloseVariants: Story = {
600
- render: () => (
601
- <div className="space-y-6">
602
- <div className="text-center">
603
- <h3 className="text-fm-primary mb-2 font-medium">
604
- PopoverClose Variants
605
- </h3>
606
- <p className="text-fm-secondary text-sm">
607
- Different ways to implement close functionality
608
- </p>
609
- </div>
610
-
611
- <div className="grid grid-cols-2 gap-4">
612
- {/* Close Button in Header */}
374
+ render: () => {
375
+ const AddToPlaylist = () => {
376
+ const [selected, setSelected] = useState<string[]>([])
377
+ const [newName, setNewName] = useState("")
378
+
379
+ const playlists = [
380
+ "Late Night Drives",
381
+ "Morning Workout",
382
+ "Focus Mode",
383
+ "Weekend Vibes",
384
+ ]
385
+
386
+ const toggle = (name: string) =>
387
+ setSelected((prev) =>
388
+ prev.includes(name) ? prev.filter((p) => p !== name) : [...prev, name]
389
+ )
390
+
391
+ return (
613
392
  <Popover>
614
393
  <PopoverTrigger asChild>
615
- <Button variant="outline">Header Close</Button>
394
+ <Button variant="outline" size="sm">
395
+ + Add to Playlist
396
+ </Button>
616
397
  </PopoverTrigger>
617
- <PopoverContent className="border-fm-divider-secondary w-72 rounded-lg border shadow-2xl">
618
- <PopoverArrow className="fill-white/10" />
619
- <div className="p-4">
620
- <div className="mb-3 flex items-center justify-between">
621
- <h4 className="text-fm-primary font-medium">Settings</h4>
622
- <PopoverClose asChild>
623
- <Button variant="text" size="sm">
624
-
625
- </Button>
626
- </PopoverClose>
627
- </div>
628
- <p className="text-fm-secondary text-sm">
629
- Close button in the header
398
+ <PopoverContent className="w-72 rounded-xl">
399
+ <div className="space-y-4 p-4">
400
+ <p className="text-fm-primary font-fm-brand text-fm-sm leading-fm-sm font-semibold tracking-widest uppercase">
401
+ Add to Playlist
630
402
  </p>
631
- </div>
632
- </PopoverContent>
633
- </Popover>
634
403
 
635
- {/* Close Button in Footer */}
636
- <Popover>
637
- <PopoverTrigger asChild>
638
- <Button variant="outline">Footer Close</Button>
639
- </PopoverTrigger>
640
- <PopoverContent className="border-fm-divider-secondary w-72 rounded-lg border shadow-2xl">
641
- <PopoverArrow className="fill-white/10" />
642
- <div className="space-y-3 p-4">
643
- <h4 className="text-fm-primary font-medium">Confirmation</h4>
644
- <p className="text-fm-secondary text-sm">
645
- Are you sure you want to continue?
646
- </p>
647
- <div className="flex gap-2">
648
- <Button size="sm">Confirm</Button>
649
- <PopoverClose asChild>
650
- <Button size="sm" variant="outline">
651
- Cancel
652
- </Button>
653
- </PopoverClose>
404
+ <div className="space-y-1">
405
+ {playlists.map((pl) => (
406
+ <button
407
+ key={pl}
408
+ onClick={() => toggle(pl)}
409
+ className="hover:bg-fm-surface-secondary flex w-full items-center justify-between rounded-lg px-3 py-2 transition-colors"
410
+ >
411
+ <span className="text-fm-primary font-fm-text text-fm-sm leading-fm-sm">
412
+ {pl}
413
+ </span>
414
+ {selected.includes(pl) && (
415
+ <span className="text-fm-positive font-fm-text text-fm-xs leading-fm-xs">
416
+
417
+ </span>
418
+ )}
419
+ </button>
420
+ ))}
421
+ </div>
422
+
423
+ <div className="border-fm-divider-secondary space-y-2 border-t pt-3">
424
+ <Label className="text-fm-secondary font-fm-text text-fm-xs leading-fm-xs">
425
+ New playlist
426
+ </Label>
427
+ <div className="flex gap-2">
428
+ <Input
429
+ value={newName}
430
+ onChange={(e) => setNewName(e.target.value)}
431
+ placeholder="Playlist name…"
432
+ className="text-fm-sm flex-1"
433
+ />
434
+ <PopoverClose asChild>
435
+ <Button
436
+ size="sm"
437
+ disabled={!newName.trim()}
438
+ onClick={() => setNewName("")}
439
+ >
440
+ Create
441
+ </Button>
442
+ </PopoverClose>
443
+ </div>
654
444
  </div>
655
445
  </div>
656
446
  </PopoverContent>
657
447
  </Popover>
448
+ )
449
+ }
450
+
451
+ const ShareOptions = () => {
452
+ const [copied, setCopied] = useState(false)
453
+
454
+ const copy = () => {
455
+ setCopied(true)
456
+ setTimeout(() => setCopied(false), 1500)
457
+ }
658
458
 
659
- {/* Multiple Close Options */}
459
+ return (
660
460
  <Popover>
661
461
  <PopoverTrigger asChild>
662
- <Button variant="outline">Multiple Close</Button>
462
+ <Button variant="outline" size="sm">
463
+ Share Track
464
+ </Button>
663
465
  </PopoverTrigger>
664
- <PopoverContent className="border-fm-divider-secondary w-80 rounded-lg border shadow-2xl">
665
- <PopoverArrow className="fill-white/10" />
466
+ <PopoverContent className="w-72 rounded-xl">
666
467
  <div className="space-y-4 p-4">
667
468
  <div className="flex items-center justify-between">
668
- <h4 className="text-fm-primary font-medium">Actions</h4>
669
- <PopoverClose asChild>
670
- <Button variant="text" size="sm">
671
-
672
- </Button>
673
- </PopoverClose>
674
- </div>
675
-
676
- <div className="space-y-2">
677
- <PopoverClose asChild>
678
- <button className="text-fm-primary hover:bg-fm-surface-secondary w-full rounded px-3 py-2 text-left text-sm">
679
- Save and Close
680
- </button>
681
- </PopoverClose>
469
+ <p className="text-fm-primary font-fm-brand text-fm-sm leading-fm-sm font-semibold tracking-widest uppercase">
470
+ Share
471
+ </p>
682
472
  <PopoverClose asChild>
683
- <button className="text-fm-primary hover:bg-fm-surface-secondary w-full rounded px-3 py-2 text-left text-sm">
684
- Discard and Close
473
+ <button className="text-fm-tertiary hover:text-fm-primary text-lg leading-none transition-colors outline-none">
474
+ ×
685
475
  </button>
686
476
  </PopoverClose>
687
- <button className="text-fm-primary hover:bg-fm-surface-secondary w-full rounded px-3 py-2 text-left text-sm">
688
- Keep Open
689
- </button>
690
477
  </div>
691
- </div>
692
- </PopoverContent>
693
- </Popover>
694
478
 
695
- {/* Icon Close Button */}
696
- <Popover>
697
- <PopoverTrigger asChild>
698
- <Button variant="outline">Icon Close</Button>
699
- </PopoverTrigger>
700
- <PopoverContent className="border-fm-divider-secondary w-64 rounded-lg border shadow-2xl">
701
- <PopoverArrow className="fill-white/10" />
702
- <div className="p-4">
703
- <div className="mb-3 flex items-start justify-between">
704
- <div>
705
- <h4 className="text-fm-primary font-medium">Notification</h4>
706
- <p className="text-fm-secondary mt-1 text-sm">
707
- New message received
708
- </p>
709
- </div>
710
- <PopoverClose asChild>
711
- <Button variant="text" size="sm">
712
- <svg
713
- className="h-4 w-4"
714
- fill="none"
715
- stroke="currentColor"
716
- viewBox="0 0 24 24"
717
- >
718
- <path
719
- strokeLinecap="round"
720
- strokeLinejoin="round"
721
- strokeWidth={2}
722
- d="M6 18L18 6M6 6l12 12"
723
- />
724
- </svg>
725
- </Button>
726
- </PopoverClose>
727
- </div>
728
- </div>
729
- </PopoverContent>
730
- </Popover>
731
-
732
- {/* Text Close Link */}
733
- <Popover>
734
- <PopoverTrigger asChild>
735
- <Button variant="outline">Text Close</Button>
736
- </PopoverTrigger>
737
- <PopoverContent className="border-fm-divider-secondary w-64 rounded-lg border shadow-2xl">
738
- <PopoverArrow className="fill-white/10" />
739
- <div className="space-y-3 p-4">
740
- <h4 className="text-fm-primary font-medium">Quick Tip</h4>
741
- <p className="text-fm-secondary text-sm">
742
- Use keyboard shortcuts to speed up your workflow.
743
- </p>
744
- <div className="text-right">
745
- <PopoverClose asChild>
746
- <button className="text-fm-info hover:text-fm-info-sec text-sm underline">
747
- Got it, thanks!
479
+ <div className="space-y-2">
480
+ {[
481
+ "Copy Link",
482
+ "Share to Profile",
483
+ "Send to Friend",
484
+ "Embed",
485
+ ].map((action) => (
486
+ <button
487
+ key={action}
488
+ onClick={action === "Copy Link" ? copy : undefined}
489
+ className="hover:bg-fm-surface-secondary flex w-full items-center gap-3 rounded-lg px-3 py-2 text-left transition-colors"
490
+ >
491
+ <span className="text-fm-primary font-fm-text text-fm-sm leading-fm-sm">
492
+ {action === "Copy Link" && copied ? "Copied!" : action}
493
+ </span>
748
494
  </button>
749
- </PopoverClose>
495
+ ))}
750
496
  </div>
751
- </div>
752
- </PopoverContent>
753
- </Popover>
754
497
 
755
- {/* Auto-close on Action */}
756
- <Popover>
757
- <PopoverTrigger asChild>
758
- <Button variant="outline">Auto Close</Button>
759
- </PopoverTrigger>
760
- <PopoverContent className="border-fm-divider-secondary w-72 rounded-lg border shadow-2xl">
761
- <PopoverArrow className="fill-white/10" />
762
- <div className="space-y-3 p-4">
763
- <h4 className="text-fm-primary font-medium">Quick Actions</h4>
764
- <div className="grid grid-cols-2 gap-2">
765
- <PopoverClose asChild>
766
- <Button size="sm" variant="outline">
767
- Copy
768
- </Button>
769
- </PopoverClose>
770
- <PopoverClose asChild>
771
- <Button size="sm" variant="outline">
772
- Share
773
- </Button>
774
- </PopoverClose>
775
- <PopoverClose asChild>
776
- <Button size="sm" variant="outline">
777
- Download
778
- </Button>
779
- </PopoverClose>
780
- <PopoverClose asChild>
781
- <Button size="sm" variant="outline">
782
- Delete
783
- </Button>
784
- </PopoverClose>
498
+ <div className="border-fm-divider-secondary border-t pt-3">
499
+ <p className="text-fm-tertiary font-fm-text text-fm-xs leading-fm-xs">
500
+ Midnight Rain · Taylor Swift · Midnights
501
+ </p>
785
502
  </div>
786
- <p className="text-fm-tertiary text-xs">
787
- Actions will close the popover automatically
788
- </p>
789
503
  </div>
790
504
  </PopoverContent>
791
505
  </Popover>
792
- </div>
793
- </div>
794
- ),
795
- parameters: {
796
- docs: {
797
- description: {
798
- story:
799
- "PopoverClose examples showing different implementation patterns: header close, footer close, multiple options, icon buttons, text links, and auto-close actions.",
800
- },
801
- },
802
- },
803
- }
804
-
805
- // 7. Complete Integration Example
806
- export const CompleteIntegration: Story = {
807
- render: () => (
808
- <div className="space-y-6">
809
- <div className="text-center">
810
- <h3 className="text-fm-primary mb-2 font-medium">
811
- Complete Integration
812
- </h3>
813
- <p className="text-fm-secondary text-sm">
814
- All components working together in real-world scenarios
815
- </p>
816
- </div>
817
-
818
- <div className="flex justify-center gap-4">
819
- {/* Complete User Menu */}
506
+ )
507
+ }
508
+
509
+ const EQSettings = () => {
510
+ const bands = [
511
+ { label: "Bass", freq: "80 Hz", default: 3 },
512
+ { label: "Low Mid", freq: "500 Hz", default: 0 },
513
+ { label: "High Mid", freq: "3 kHz", default: -1 },
514
+ { label: "Treble", freq: "10 kHz", default: -2 },
515
+ ]
516
+ const [values, setValues] = useState<Record<string, number>>(
517
+ Object.fromEntries(bands.map(({ label, default: d }) => [label, d]))
518
+ )
519
+
520
+ return (
820
521
  <Popover>
821
522
  <PopoverTrigger asChild>
822
- <Button variant="text">
823
- <img
824
- src="https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?w=32&h=32&fit=crop&crop=face"
825
- alt="Profile"
826
- className="border-fm-divider-secondary h-8 w-8 rounded-full border"
827
- />
828
- <span className="text-sm">John Doe</span>
829
- <svg
830
- className="text-fm-secondary h-4 w-4"
831
- fill="none"
832
- stroke="currentColor"
833
- viewBox="0 0 24 24"
834
- >
835
- <path
836
- strokeLinecap="round"
837
- strokeLinejoin="round"
838
- strokeWidth={2}
839
- d="M19 9l-7 7-7-7"
840
- />
841
- </svg>
523
+ <Button variant="outline" size="sm">
524
+ EQ Settings
842
525
  </Button>
843
526
  </PopoverTrigger>
844
- <PopoverContent
845
- align="end"
846
- className="border-fm-divider-secondary w-80 rounded-lg border shadow-2xl"
847
- >
848
- <PopoverArrow className="fill-white/10" />
527
+ <PopoverContent className="w-72 rounded-xl">
849
528
  <div className="space-y-4 p-4">
850
- {/* Header with close */}
851
529
  <div className="flex items-center justify-between">
852
- <h4 className="text-fm-primary font-medium">Account Menu</h4>
853
- <PopoverClose asChild>
854
- <Button variant="text" size="sm">
855
-
856
- </Button>
857
- </PopoverClose>
530
+ <p className="text-fm-primary font-fm-brand text-fm-sm leading-fm-sm font-semibold tracking-widest uppercase">
531
+ Equalizer
532
+ </p>
533
+ <button
534
+ onClick={() =>
535
+ setValues(
536
+ Object.fromEntries(
537
+ bands.map(({ label, default: d }) => [label, d])
538
+ )
539
+ )
540
+ }
541
+ className="text-fm-tertiary hover:text-fm-primary font-fm-text text-fm-xs leading-fm-xs transition-colors"
542
+ >
543
+ Reset
544
+ </button>
858
545
  </div>
859
546
 
860
- {/* User Info */}
861
- <div className="bg-fm-surface-secondary flex items-center gap-3 rounded-lg p-3">
862
- <img
863
- src="https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?w=48&h=48&fit=crop&crop=face"
864
- alt="Profile"
865
- className="border-fm-divider-secondary h-12 w-12 rounded-full border"
866
- />
867
- <div>
868
- <div className="text-fm-primary font-medium">John Doe</div>
869
- <div className="text-fm-secondary text-sm">
870
- john@example.com
547
+ <div className="space-y-3">
548
+ {bands.map(({ label, freq }) => (
549
+ <div key={label} className="space-y-1">
550
+ <div className="flex items-center justify-between">
551
+ <span className="text-fm-secondary font-fm-text text-fm-xs leading-fm-xs">
552
+ {label} · {freq}
553
+ </span>
554
+ <span className="text-fm-primary font-fm-text text-fm-xs leading-fm-xs w-12 text-right">
555
+ {values[label] > 0 ? "+" : ""}
556
+ {values[label]} dB
557
+ </span>
558
+ </div>
559
+ <input
560
+ type="range"
561
+ min={-12}
562
+ max={12}
563
+ step={1}
564
+ value={values[label]}
565
+ onChange={(e) =>
566
+ setValues((v) => ({
567
+ ...v,
568
+ [label]: Number(e.target.value),
569
+ }))
570
+ }
571
+ className="accent-fm-primary h-1 w-full"
572
+ />
871
573
  </div>
872
- </div>
574
+ ))}
873
575
  </div>
874
576
 
875
- {/* Quick Actions */}
876
- <div className="grid grid-cols-2 gap-2">
577
+ <div className="flex gap-2 pt-1">
877
578
  <PopoverClose asChild>
878
- <Button size="sm" variant="outline">
879
- Profile
579
+ <Button size="sm" className="flex-1">
580
+ Apply
880
581
  </Button>
881
582
  </PopoverClose>
882
583
  <PopoverClose asChild>
883
- <Button size="sm" variant="outline">
884
- Settings
584
+ <Button variant="outline" size="sm">
585
+ Cancel
885
586
  </Button>
886
587
  </PopoverClose>
887
588
  </div>
888
-
889
- {/* Menu Items */}
890
- <div className="space-y-1">
891
- <PopoverClose asChild>
892
- <button className="text-fm-primary hover:bg-fm-surface-secondary flex w-full items-center gap-2 rounded px-3 py-2 text-left text-sm">
893
- <svg
894
- className="h-4 w-4"
895
- fill="none"
896
- stroke="currentColor"
897
- viewBox="0 0 24 24"
898
- >
899
- <path
900
- strokeLinecap="round"
901
- strokeLinejoin="round"
902
- strokeWidth={2}
903
- d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"
904
- />
905
- </svg>
906
- My Documents
907
- </button>
908
- </PopoverClose>
909
- <PopoverClose asChild>
910
- <button className="text-fm-primary hover:bg-fm-surface-secondary flex w-full items-center gap-2 rounded px-3 py-2 text-left text-sm">
911
- <svg
912
- className="h-4 w-4"
913
- fill="none"
914
- stroke="currentColor"
915
- viewBox="0 0 24 24"
916
- >
917
- <path
918
- strokeLinecap="round"
919
- strokeLinejoin="round"
920
- strokeWidth={2}
921
- d="M3 10h18M7 15h1m4 0h1m-7 4h12a3 3 0 003-3V8a3 3 0 00-3-3H6a3 3 0 00-3 3v8a3 3 0 003 3z"
922
- />
923
- </svg>
924
- Billing
925
- </button>
926
- </PopoverClose>
927
- <PopoverClose asChild>
928
- <button className="text-fm-primary hover:bg-fm-surface-secondary flex w-full items-center gap-2 rounded px-3 py-2 text-left text-sm">
929
- <svg
930
- className="h-4 w-4"
931
- fill="none"
932
- stroke="currentColor"
933
- viewBox="0 0 24 24"
934
- >
935
- <path
936
- strokeLinecap="round"
937
- strokeLinejoin="round"
938
- strokeWidth={2}
939
- d="M18.364 5.636l-3.536 3.536m0 5.656l3.536 3.536M9.172 9.172L5.636 5.636m3.536 9.192l-3.536 3.536M21 12a9 9 0 11-18 0 9 9 0 0118 0zm-5 0a4 4 0 11-8 0 4 4 0 018 0z"
940
- />
941
- </svg>
942
- Help & Support
943
- </button>
944
- </PopoverClose>
945
- </div>
946
-
947
- {/* Sign Out */}
948
- <div className="border-fm-divider-secondary border-t pt-3">
949
- <PopoverClose asChild>
950
- <button className="text-fm-icon-negative hover:bg-fm-surface-secondary flex w-full items-center gap-2 rounded px-3 py-2 text-left text-sm">
951
- <svg
952
- className="h-4 w-4"
953
- fill="none"
954
- stroke="currentColor"
955
- viewBox="0 0 24 24"
956
- >
957
- <path
958
- strokeLinecap="round"
959
- strokeLinejoin="round"
960
- strokeWidth={2}
961
- d="M17 16l4-4m0 0l-4-4m4 4H7m6 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h4a3 3 0 013 3v1"
962
- />
963
- </svg>
964
- Sign Out
965
- </button>
966
- </PopoverClose>
967
- </div>
968
589
  </div>
969
590
  </PopoverContent>
970
591
  </Popover>
592
+ )
593
+ }
971
594
 
972
- {/* Complete Form Editor */}
973
- <Popover>
974
- <PopoverTrigger asChild>
975
- <Button>Edit Profile</Button>
976
- </PopoverTrigger>
977
- <PopoverContent className="border-fm-divider-secondary w-96 rounded-lg border shadow-2xl">
978
- <PopoverArrow className="fill-white/10" />
979
- <div className="space-y-4 p-4">
980
- {/* Header */}
981
- <div className="flex items-center justify-between">
982
- <h4 className="text-fm-primary font-medium">Edit Profile</h4>
983
- <PopoverClose asChild>
984
- <Button variant="text" size="sm">
985
-
986
- </Button>
987
- </PopoverClose>
595
+ return (
596
+ <div className="w-full p-8">
597
+ <div className="mx-auto max-w-3xl space-y-6">
598
+ <div className="grid grid-cols-1 gap-6 lg:grid-cols-3">
599
+ {/* Controls panel */}
600
+ <div className="border-fm-divider-secondary bg-fm-surface-secondary space-y-5 rounded-xl border p-5">
601
+ <p className="text-fm-primary font-fm-brand text-fm-sm leading-fm-sm font-semibold tracking-widest uppercase">
602
+ Track Actions
603
+ </p>
604
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
605
+ Open any popover to interact with a live action panel.
606
+ </p>
607
+ <div className="border-fm-divider-secondary border-t pt-4" />
608
+ <div className="space-y-3">
609
+ <AddToPlaylist />
610
+ <ShareOptions />
611
+ <EQSettings />
988
612
  </div>
613
+ </div>
989
614
 
990
- {/* Form Fields */}
991
- <div className="space-y-3">
992
- <div>
993
- <Label htmlFor="name" className="text-fm-primary text-sm">
994
- Full Name
995
- </Label>
996
- <Input
997
- id="name"
998
- defaultValue="John Doe"
999
- className="border-fm-divider-secondary bg-fm-surface-secondary text-fm-primary placeholder:text-fm-tertiary"
1000
- />
1001
- </div>
1002
- <div>
1003
- <Label htmlFor="email" className="text-fm-primary text-sm">
1004
- Email
1005
- </Label>
1006
- <Input
1007
- id="email"
1008
- defaultValue="john@example.com"
1009
- className="border-fm-divider-secondary bg-fm-surface-secondary text-fm-primary placeholder:text-fm-tertiary"
1010
- />
1011
- </div>
1012
- <div>
1013
- <Label htmlFor="role" className="text-fm-primary text-sm">
1014
- Role
1015
- </Label>
1016
- <select
1017
- id="role"
1018
- className="border-fm-divider-secondary bg-fm-surface-secondary text-fm-primary focus-visible:ring-fm-divider-secondary w-full rounded-md border px-3 py-2 text-sm focus-visible:ring-2 focus-visible:outline-none"
1019
- >
1020
- <option value="developer">Developer</option>
1021
- <option value="designer">Designer</option>
1022
- <option value="manager">Manager</option>
1023
- </select>
615
+ {/* Preview stage */}
616
+ <div className="flex flex-col gap-3 lg:col-span-2">
617
+ <div className="border-fm-divider-secondary bg-fm-surface-secondary flex-1 space-y-3 rounded-xl border p-5">
618
+ <p className="text-fm-tertiary font-fm-text text-fm-sm leading-fm-sm">
619
+ Now playing
620
+ </p>
621
+ <div className="space-y-1">
622
+ <p className="text-fm-primary font-fm-brand text-fm-xl leading-fm-xl font-semibold">
623
+ Midnight Rain
624
+ </p>
625
+ <p className="text-fm-secondary font-fm-text text-fm-md leading-fm-md">
626
+ Taylor Swift · Midnights · 2022
627
+ </p>
1024
628
  </div>
1025
- <div>
1026
- <Label htmlFor="bio" className="text-fm-primary text-sm">
1027
- Bio
1028
- </Label>
1029
- <textarea
1030
- id="bio"
1031
- rows={3}
1032
- className="border-fm-divider-secondary bg-fm-surface-secondary text-fm-primary placeholder:text-fm-tertiary focus-visible:ring-fm-divider-secondary w-full rounded-md border px-3 py-2 text-sm focus-visible:ring-2 focus-visible:outline-none"
1033
- defaultValue="Software developer passionate about creating great user experiences."
1034
- />
629
+ <div className="border-fm-divider-secondary border-t pt-3">
630
+ <p className="text-fm-tertiary font-fm-text text-fm-sm leading-fm-sm">
631
+ Use the action buttons on the left to open interactive
632
+ popovers: add this track to a playlist, share it, or adjust
633
+ the equalizer.
634
+ </p>
1035
635
  </div>
1036
636
  </div>
1037
-
1038
- {/* Action Buttons */}
1039
- <div className="flex gap-2 pt-2">
1040
- <PopoverClose asChild>
1041
- <Button size="sm">Save Changes</Button>
1042
- </PopoverClose>
1043
- <PopoverClose asChild>
1044
- <Button size="sm" variant="outline">
1045
- Cancel
1046
- </Button>
1047
- </PopoverClose>
637
+ <div className="border-fm-divider-secondary bg-fm-surface-secondary rounded-lg border px-4 py-3">
638
+ <code className="text-fm-secondary text-fm-md leading-fm-md font-(--font-fm-mono)">
639
+ {`<Popover><PopoverTrigger asChild>…</PopoverTrigger><PopoverContent>…<PopoverClose /></PopoverContent></Popover>`}
640
+ </code>
1048
641
  </div>
1049
642
  </div>
1050
- </PopoverContent>
1051
- </Popover>
643
+ </div>
644
+ </div>
1052
645
  </div>
1053
- </div>
1054
- ),
1055
- parameters: {
1056
- docs: {
1057
- description: {
1058
- story:
1059
- "Complete integration examples showing all popover components working together in realistic user interface scenarios.",
1060
- },
1061
- },
646
+ )
1062
647
  },
1063
648
  }