@fpkit/acss 6.2.0 → 6.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/libs/chunk-25KCUE3R.cjs +17 -0
- package/libs/chunk-25KCUE3R.cjs.map +1 -0
- package/libs/chunk-34NWHFHP.js +10 -0
- package/libs/chunk-34NWHFHP.js.map +1 -0
- package/libs/{chunk-SQ44OCJ2.js → chunk-6NMLU5FA.js} +2 -2
- package/libs/{chunk-GVVCXXKI.cjs → chunk-6YVR4TDM.cjs} +3 -3
- package/libs/chunk-DSQ2TUCR.js +7 -0
- package/libs/chunk-DSQ2TUCR.js.map +1 -0
- package/libs/{chunk-H6A2CUWA.js → chunk-VQTCTLFN.js} +2 -2
- package/libs/chunk-ZJ4RUKI2.cjs +14 -0
- package/libs/chunk-ZJ4RUKI2.cjs.map +1 -0
- package/libs/{chunk-H4JRUNKU.cjs → chunk-ZOPHCNFD.cjs} +3 -3
- package/libs/components/button.cjs +3 -3
- package/libs/components/button.d.cts +34 -1
- package/libs/components/button.d.ts +34 -1
- package/libs/components/button.js +1 -1
- package/libs/components/buttons/button.css +1 -1
- package/libs/components/buttons/button.css.map +1 -1
- package/libs/components/buttons/button.min.css +2 -2
- package/libs/components/buttons/icon-button.css +1 -0
- package/libs/components/buttons/icon-button.css.map +1 -0
- package/libs/components/buttons/icon-button.min.css +3 -0
- package/libs/components/dialog/dialog.cjs +4 -4
- package/libs/components/dialog/dialog.js +2 -2
- package/libs/components/icons/icon.d.cts +1 -1
- package/libs/components/icons/icon.d.ts +1 -1
- package/libs/components/link/link.css +1 -1
- package/libs/components/link/link.min.css +1 -1
- package/libs/components/modal.cjs +3 -3
- package/libs/components/modal.js +2 -2
- package/libs/components/popover/popover.cjs +3 -8
- package/libs/components/popover/popover.css +1 -0
- package/libs/components/popover/popover.css.map +1 -0
- package/libs/components/popover/popover.d.cts +54 -26
- package/libs/components/popover/popover.d.ts +54 -26
- package/libs/components/popover/popover.js +1 -2
- package/libs/components/popover/popover.min.css +3 -0
- package/libs/hooks.cjs +3 -6
- package/libs/hooks.cjs.map +1 -1
- package/libs/hooks.d.cts +30 -10
- package/libs/hooks.d.ts +30 -10
- package/libs/hooks.js +5 -1
- package/libs/hooks.js.map +1 -1
- package/libs/{icons-48788561.d.ts → icons-2c09535c.d.ts} +32 -32
- package/libs/icons.d.cts +1 -1
- package/libs/icons.d.ts +1 -1
- package/libs/index.cjs +35 -35
- package/libs/index.cjs.map +1 -1
- package/libs/index.css +1 -1
- package/libs/index.css.map +1 -1
- package/libs/index.d.cts +64 -5
- package/libs/index.d.ts +64 -5
- package/libs/index.js +9 -10
- package/libs/index.js.map +1 -1
- package/package.json +2 -2
- package/src/components/buttons/README.mdx +107 -11
- package/src/components/buttons/STYLES.mdx +182 -47
- package/src/components/buttons/button.scss +93 -16
- package/src/components/buttons/button.stories.tsx +149 -0
- package/src/components/buttons/button.test.tsx +12 -0
- package/src/components/buttons/button.tsx +50 -6
- package/src/components/buttons/icon-button.scss +45 -0
- package/src/components/buttons/icon-button.stories.tsx +200 -0
- package/src/components/buttons/icon-button.test.tsx +132 -0
- package/src/components/buttons/icon-button.tsx +72 -0
- package/src/components/form/select.tsx +55 -51
- package/src/components/link/link.scss +2 -2
- package/src/components/popover/README.mdx +478 -0
- package/src/components/popover/STYLES.mdx +389 -0
- package/src/components/popover/index.ts +3 -0
- package/src/components/popover/popover.scss +249 -0
- package/src/components/popover/popover.stories.tsx +315 -15
- package/src/components/popover/popover.test.tsx +249 -37
- package/src/components/popover/popover.tsx +165 -62
- package/src/hooks/popover/popover.tsx +26 -10
- package/src/hooks/popover/use-popover.tsx +30 -10
- package/src/hooks.ts +5 -0
- package/src/index.scss +1 -0
- package/src/index.ts +1 -0
- package/src/styles/buttons/button.css +78 -16
- package/src/styles/buttons/button.css.map +1 -1
- package/src/styles/buttons/icon-button.css +32 -0
- package/src/styles/buttons/icon-button.css.map +1 -0
- package/src/styles/index.css +268 -18
- package/src/styles/index.css.map +1 -1
- package/src/styles/link/link.css +2 -2
- package/src/styles/popover/popover.css +190 -0
- package/src/styles/popover/popover.css.map +1 -0
- package/src/types/popover.d.ts +64 -0
- package/libs/chunk-4I5MF54P.js +0 -8
- package/libs/chunk-4I5MF54P.js.map +0 -1
- package/libs/chunk-GCGKYLDG.js +0 -7
- package/libs/chunk-GCGKYLDG.js.map +0 -1
- package/libs/chunk-NZVSXRTB.cjs +0 -16
- package/libs/chunk-NZVSXRTB.cjs.map +0 -1
- package/libs/chunk-PDD4N5P5.cjs +0 -10
- package/libs/chunk-PDD4N5P5.cjs.map +0 -1
- package/libs/chunk-S7NIA6PI.cjs +0 -17
- package/libs/chunk-S7NIA6PI.cjs.map +0 -1
- package/libs/chunk-X2RDXWH5.js +0 -10
- package/libs/chunk-X2RDXWH5.js.map +0 -1
- /package/libs/{chunk-SQ44OCJ2.js.map → chunk-6NMLU5FA.js.map} +0 -0
- /package/libs/{chunk-GVVCXXKI.cjs.map → chunk-6YVR4TDM.cjs.map} +0 -0
- /package/libs/{chunk-H6A2CUWA.js.map → chunk-VQTCTLFN.js.map} +0 -0
- /package/libs/{chunk-H4JRUNKU.cjs.map → chunk-ZOPHCNFD.cjs.map} +0 -0
|
@@ -0,0 +1,389 @@
|
|
|
1
|
+
import { Meta } from '@storybook/addon-docs/blocks';
|
|
2
|
+
|
|
3
|
+
<Meta title="FP.React Components/Popover/Styling" />
|
|
4
|
+
|
|
5
|
+
# Popover Styling Guide
|
|
6
|
+
|
|
7
|
+
Complete reference for theming and customizing the Popover component using CSS custom properties.
|
|
8
|
+
|
|
9
|
+
## CSS Custom Properties
|
|
10
|
+
|
|
11
|
+
### Background & Border
|
|
12
|
+
|
|
13
|
+
| Property | Default | Description |
|
|
14
|
+
|----------|---------|-------------|
|
|
15
|
+
| `--popover-bg` | `#ffffff` | Background color |
|
|
16
|
+
| `--popover-border` | `0.0625rem solid #ccc` | Border style |
|
|
17
|
+
| `--popover-border-radius` | `0.5rem` | Corner rounding |
|
|
18
|
+
|
|
19
|
+
### Spacing
|
|
20
|
+
|
|
21
|
+
| Property | Default | Description |
|
|
22
|
+
|----------|---------|-------------|
|
|
23
|
+
| `--popover-padding` | `1rem` | Internal padding |
|
|
24
|
+
| `--popover-margin` | `0.5rem` | Distance from trigger |
|
|
25
|
+
| `--popover-max-width` | `20rem` | Maximum width |
|
|
26
|
+
|
|
27
|
+
### Shadow
|
|
28
|
+
|
|
29
|
+
| Property | Default | Description |
|
|
30
|
+
|----------|---------|-------------|
|
|
31
|
+
| `--popover-shadow` | Box shadow value | Drop shadow effect |
|
|
32
|
+
|
|
33
|
+
### Arrow
|
|
34
|
+
|
|
35
|
+
| Property | Default | Description |
|
|
36
|
+
|----------|---------|-------------|
|
|
37
|
+
| `--popover-arrow-size` | `0.5rem` | Arrow dimensions |
|
|
38
|
+
| `--popover-arrow-color` | `var(--popover-bg)` | Arrow color |
|
|
39
|
+
|
|
40
|
+
### Close Button
|
|
41
|
+
|
|
42
|
+
| Property | Default | Description |
|
|
43
|
+
|----------|---------|-------------|
|
|
44
|
+
| `--popover-close-size` | `1.5rem` | Button dimensions |
|
|
45
|
+
| `--popover-close-color` | `#666` | Icon color |
|
|
46
|
+
| `--popover-close-hover-color` | `#000` | Hover icon color |
|
|
47
|
+
| `--popover-close-hover-bg` | `rgba(0, 0, 0, 0.05)` | Hover background |
|
|
48
|
+
|
|
49
|
+
## Theme Examples
|
|
50
|
+
|
|
51
|
+
### Dark Theme
|
|
52
|
+
|
|
53
|
+
```tsx
|
|
54
|
+
<Popover
|
|
55
|
+
id="dark-popover"
|
|
56
|
+
styles={{
|
|
57
|
+
'--popover-bg': '#1a1a2e',
|
|
58
|
+
'--popover-border': '0.0625rem solid #16213e',
|
|
59
|
+
'--popover-padding': '1.5rem',
|
|
60
|
+
'--popover-shadow': '0 0.5rem 1rem rgba(0, 0, 0, 0.5)',
|
|
61
|
+
'--popover-arrow-color': '#1a1a2e',
|
|
62
|
+
'--popover-close-color': '#aaa',
|
|
63
|
+
'--popover-close-hover-color': '#fff',
|
|
64
|
+
'--popover-close-hover-bg': 'rgba(255, 255, 255, 0.1)',
|
|
65
|
+
color: '#eee',
|
|
66
|
+
}}
|
|
67
|
+
>
|
|
68
|
+
<p>Dark themed popover</p>
|
|
69
|
+
</Popover>
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Colorful Accent
|
|
73
|
+
|
|
74
|
+
```tsx
|
|
75
|
+
<Popover
|
|
76
|
+
id="accent-popover"
|
|
77
|
+
styles={{
|
|
78
|
+
'--popover-bg': '#fff3e0',
|
|
79
|
+
'--popover-border': '0.125rem solid #ff9800',
|
|
80
|
+
'--popover-border-radius': '0.75rem',
|
|
81
|
+
'--popover-shadow': '0 0.25rem 0.75rem rgba(255, 152, 0, 0.2)',
|
|
82
|
+
'--popover-arrow-color': '#fff3e0',
|
|
83
|
+
}}
|
|
84
|
+
>
|
|
85
|
+
<p>Accent colored popover</p>
|
|
86
|
+
</Popover>
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Minimal (No Border/Shadow)
|
|
90
|
+
|
|
91
|
+
```tsx
|
|
92
|
+
<Popover
|
|
93
|
+
id="minimal-popover"
|
|
94
|
+
styles={{
|
|
95
|
+
'--popover-bg': '#f5f5f5',
|
|
96
|
+
'--popover-border': 'none',
|
|
97
|
+
'--popover-border-radius': '0.25rem',
|
|
98
|
+
'--popover-padding': '0.75rem',
|
|
99
|
+
'--popover-shadow': 'none',
|
|
100
|
+
}}
|
|
101
|
+
showArrow={false}
|
|
102
|
+
>
|
|
103
|
+
<p>Minimal popover</p>
|
|
104
|
+
</Popover>
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Large Content
|
|
108
|
+
|
|
109
|
+
```tsx
|
|
110
|
+
<Popover
|
|
111
|
+
id="large-popover"
|
|
112
|
+
styles={{
|
|
113
|
+
'--popover-max-width': '30rem',
|
|
114
|
+
'--popover-padding': '2rem',
|
|
115
|
+
'--popover-border-radius': '1rem',
|
|
116
|
+
}}
|
|
117
|
+
>
|
|
118
|
+
<article>Large content here...</article>
|
|
119
|
+
</Popover>
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## Global Theming
|
|
123
|
+
|
|
124
|
+
Define CSS variables globally to theme all popovers:
|
|
125
|
+
|
|
126
|
+
```css
|
|
127
|
+
:root {
|
|
128
|
+
/* Light theme */
|
|
129
|
+
--popover-bg: #ffffff;
|
|
130
|
+
--popover-border: 0.0625rem solid #e0e0e0;
|
|
131
|
+
--popover-border-radius: 0.5rem;
|
|
132
|
+
--popover-shadow: 0 0.25rem 0.5rem rgba(0, 0, 0, 0.1);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
[data-theme='dark'] {
|
|
136
|
+
/* Dark theme */
|
|
137
|
+
--popover-bg: #2d2d2d;
|
|
138
|
+
--popover-border: 0.0625rem solid #404040;
|
|
139
|
+
--popover-shadow: 0 0.25rem 0.5rem rgba(0, 0, 0, 0.3);
|
|
140
|
+
--popover-close-color: #aaa;
|
|
141
|
+
--popover-close-hover-color: #fff;
|
|
142
|
+
}
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
## Custom CSS Classes
|
|
146
|
+
|
|
147
|
+
Add custom styles via the `className` prop:
|
|
148
|
+
|
|
149
|
+
```tsx
|
|
150
|
+
<Popover
|
|
151
|
+
id="custom-class-popover"
|
|
152
|
+
className="my-custom-popover"
|
|
153
|
+
>
|
|
154
|
+
<p>Content</p>
|
|
155
|
+
</Popover>
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
```css
|
|
159
|
+
.my-custom-popover {
|
|
160
|
+
/* Override or extend default styles */
|
|
161
|
+
border: 0.125rem dashed #0066cc;
|
|
162
|
+
animation: pulse 2s infinite;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
.my-custom-popover .fpkit-popover-content {
|
|
166
|
+
/* Style content wrapper */
|
|
167
|
+
font-family: monospace;
|
|
168
|
+
}
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
## Arrow Customization
|
|
172
|
+
|
|
173
|
+
### Hide Arrow
|
|
174
|
+
|
|
175
|
+
```tsx
|
|
176
|
+
<Popover showArrow={false}>
|
|
177
|
+
<p>No arrow</p>
|
|
178
|
+
</Popover>
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
### Style Arrow
|
|
182
|
+
|
|
183
|
+
```tsx
|
|
184
|
+
<Popover
|
|
185
|
+
styles={{
|
|
186
|
+
'--popover-arrow-size': '0.75rem',
|
|
187
|
+
'--popover-arrow-color': '#ff5722',
|
|
188
|
+
}}
|
|
189
|
+
>
|
|
190
|
+
<p>Custom arrow</p>
|
|
191
|
+
</Popover>
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
## Close Button Customization
|
|
195
|
+
|
|
196
|
+
### Hide Close Button
|
|
197
|
+
|
|
198
|
+
```tsx
|
|
199
|
+
<Popover mode="auto" showCloseButton={false}>
|
|
200
|
+
<p>No close button</p>
|
|
201
|
+
</Popover>
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
### Style Close Button
|
|
205
|
+
|
|
206
|
+
```tsx
|
|
207
|
+
<Popover
|
|
208
|
+
mode="manual"
|
|
209
|
+
styles={{
|
|
210
|
+
'--popover-close-size': '2rem',
|
|
211
|
+
'--popover-close-color': '#d32f2f',
|
|
212
|
+
'--popover-close-hover-bg': '#ffebee',
|
|
213
|
+
}}
|
|
214
|
+
>
|
|
215
|
+
<p>Custom close button</p>
|
|
216
|
+
</Popover>
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
## Trigger Button Styling
|
|
220
|
+
|
|
221
|
+
The default trigger can be styled via CSS:
|
|
222
|
+
|
|
223
|
+
```css
|
|
224
|
+
.fpkit-popover-trigger {
|
|
225
|
+
/* Custom trigger styles */
|
|
226
|
+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
227
|
+
border-radius: 2rem;
|
|
228
|
+
padding: 0.75rem 1.5rem;
|
|
229
|
+
font-weight: 600;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
.fpkit-popover-trigger:hover {
|
|
233
|
+
transform: translateY(-0.125rem);
|
|
234
|
+
box-shadow: 0 0.25rem 0.5rem rgba(102, 126, 234, 0.3);
|
|
235
|
+
}
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
Or use a custom trigger element:
|
|
239
|
+
|
|
240
|
+
```tsx
|
|
241
|
+
<Popover
|
|
242
|
+
trigger={
|
|
243
|
+
<button className="my-trigger">
|
|
244
|
+
Custom Trigger
|
|
245
|
+
</button>
|
|
246
|
+
}
|
|
247
|
+
>
|
|
248
|
+
<p>Content</p>
|
|
249
|
+
</Popover>
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
## Animation Customization
|
|
253
|
+
|
|
254
|
+
The popover uses CSS transitions. Customize via inline styles:
|
|
255
|
+
|
|
256
|
+
```tsx
|
|
257
|
+
<Popover
|
|
258
|
+
id="animated-popover"
|
|
259
|
+
styles={{
|
|
260
|
+
transition: 'opacity 0.4s cubic-bezier(0.4, 0, 0.2, 1), transform 0.4s cubic-bezier(0.4, 0, 0.2, 1)',
|
|
261
|
+
}}
|
|
262
|
+
>
|
|
263
|
+
<p>Custom animation timing</p>
|
|
264
|
+
</Popover>
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
## Backdrop Styling (Manual Mode)
|
|
268
|
+
|
|
269
|
+
Style the backdrop overlay using `::backdrop`:
|
|
270
|
+
|
|
271
|
+
```css
|
|
272
|
+
.fpkit-popover::backdrop {
|
|
273
|
+
background: rgba(0, 0, 0, 0.5);
|
|
274
|
+
backdrop-filter: blur(0.25rem);
|
|
275
|
+
}
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
Or via inline styles:
|
|
279
|
+
|
|
280
|
+
```tsx
|
|
281
|
+
<Popover
|
|
282
|
+
mode="manual"
|
|
283
|
+
className="custom-backdrop"
|
|
284
|
+
>
|
|
285
|
+
<p>Content</p>
|
|
286
|
+
</Popover>
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
```css
|
|
290
|
+
.custom-backdrop::backdrop {
|
|
291
|
+
background: linear-gradient(to bottom, rgba(0, 0, 0, 0.3), rgba(0, 0, 0, 0.6));
|
|
292
|
+
}
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
## Responsive Sizing
|
|
296
|
+
|
|
297
|
+
Adjust sizing based on viewport:
|
|
298
|
+
|
|
299
|
+
```css
|
|
300
|
+
.fpkit-popover {
|
|
301
|
+
--popover-max-width: 90vw;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
@media (min-width: 48rem) {
|
|
305
|
+
.fpkit-popover {
|
|
306
|
+
--popover-max-width: 30rem;
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
@media (min-width: 64rem) {
|
|
311
|
+
.fpkit-popover {
|
|
312
|
+
--popover-max-width: 40rem;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
## Best Practices
|
|
318
|
+
|
|
319
|
+
1. **Use rem units**: All spacing uses rem for accessibility
|
|
320
|
+
2. **Maintain contrast**: Ensure text/background contrast meets WCAG AA
|
|
321
|
+
3. **Test animations**: Verify animations work across browsers
|
|
322
|
+
4. **Consider reduced motion**: Respect `prefers-reduced-motion`
|
|
323
|
+
5. **Avoid over-styling**: Keep popovers simple and focused
|
|
324
|
+
|
|
325
|
+
## CSS Variables Reference
|
|
326
|
+
|
|
327
|
+
Full list of available CSS custom properties:
|
|
328
|
+
|
|
329
|
+
```css
|
|
330
|
+
.fpkit-popover {
|
|
331
|
+
/* Background & Border */
|
|
332
|
+
--popover-bg: #ffffff;
|
|
333
|
+
--popover-border: 0.0625rem solid #ccc;
|
|
334
|
+
--popover-border-radius: 0.5rem;
|
|
335
|
+
|
|
336
|
+
/* Spacing */
|
|
337
|
+
--popover-padding: 1rem;
|
|
338
|
+
--popover-margin: 0.5rem;
|
|
339
|
+
--popover-max-width: 20rem;
|
|
340
|
+
|
|
341
|
+
/* Shadow */
|
|
342
|
+
--popover-shadow: 0 0.25rem 0.5rem rgba(0, 0, 0, 0.1),
|
|
343
|
+
0 0.125rem 0.25rem rgba(0, 0, 0, 0.06);
|
|
344
|
+
|
|
345
|
+
/* Arrow */
|
|
346
|
+
--popover-arrow-size: 0.5rem;
|
|
347
|
+
--popover-arrow-color: var(--popover-bg);
|
|
348
|
+
|
|
349
|
+
/* Close Button */
|
|
350
|
+
--popover-close-size: 1.5rem;
|
|
351
|
+
--popover-close-color: #666;
|
|
352
|
+
--popover-close-hover-color: #000;
|
|
353
|
+
--popover-close-hover-bg: rgba(0, 0, 0, 0.05);
|
|
354
|
+
}
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
## Debugging Tips
|
|
358
|
+
|
|
359
|
+
### Inspect Styles
|
|
360
|
+
|
|
361
|
+
Use browser DevTools to inspect and modify CSS variables:
|
|
362
|
+
|
|
363
|
+
```javascript
|
|
364
|
+
// Get computed value
|
|
365
|
+
getComputedStyle(popover).getPropertyValue('--popover-bg');
|
|
366
|
+
|
|
367
|
+
// Set value
|
|
368
|
+
popover.style.setProperty('--popover-bg', '#ff0000');
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
### Check Browser Support
|
|
372
|
+
|
|
373
|
+
Verify native popover support:
|
|
374
|
+
|
|
375
|
+
```javascript
|
|
376
|
+
if ('popover' in HTMLElement.prototype) {
|
|
377
|
+
console.log('Popover API supported');
|
|
378
|
+
}
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
### Positioning Issues
|
|
382
|
+
|
|
383
|
+
If positioning seems off, check CSS anchor positioning support:
|
|
384
|
+
|
|
385
|
+
```javascript
|
|
386
|
+
if (CSS.supports('anchor-name', '--test')) {
|
|
387
|
+
console.log('Anchor positioning supported');
|
|
388
|
+
}
|
|
389
|
+
```
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Popover Component Styles
|
|
3
|
+
* Uses native HTML popover API with CSS custom properties
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// CSS Custom Properties
|
|
7
|
+
.fpkit-popover {
|
|
8
|
+
// Background and border
|
|
9
|
+
--popover-bg: #ffffff;
|
|
10
|
+
--popover-border: 0.0625rem solid #ccc;
|
|
11
|
+
--popover-border-radius: 0.5rem;
|
|
12
|
+
|
|
13
|
+
// Spacing
|
|
14
|
+
--popover-padding: 1rem;
|
|
15
|
+
--popover-margin: 0.5rem;
|
|
16
|
+
--popover-max-width: 20rem;
|
|
17
|
+
|
|
18
|
+
// Shadow
|
|
19
|
+
--popover-shadow: 0 0.25rem 0.5rem rgba(0, 0, 0, 0.1),
|
|
20
|
+
0 0.125rem 0.25rem rgba(0, 0, 0, 0.06);
|
|
21
|
+
|
|
22
|
+
// Arrow
|
|
23
|
+
--popover-arrow-size: 0.5rem;
|
|
24
|
+
--popover-arrow-color: var(--popover-bg);
|
|
25
|
+
|
|
26
|
+
// Close button
|
|
27
|
+
--popover-close-size: 1.5rem;
|
|
28
|
+
--popover-close-color: #666;
|
|
29
|
+
--popover-close-hover-color: #000;
|
|
30
|
+
--popover-close-hover-bg: rgba(0, 0, 0, 0.05);
|
|
31
|
+
|
|
32
|
+
// Base styles
|
|
33
|
+
background: var(--popover-bg);
|
|
34
|
+
border: var(--popover-border);
|
|
35
|
+
border-radius: var(--popover-border-radius);
|
|
36
|
+
padding: var(--popover-padding);
|
|
37
|
+
max-width: var(--popover-max-width);
|
|
38
|
+
box-shadow: var(--popover-shadow);
|
|
39
|
+
|
|
40
|
+
// Remove default popover styles
|
|
41
|
+
margin: 0;
|
|
42
|
+
|
|
43
|
+
// Positioning margin
|
|
44
|
+
&[data-placement='top'] {
|
|
45
|
+
margin-bottom: var(--popover-margin);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
&[data-placement='bottom'] {
|
|
49
|
+
margin-top: var(--popover-margin);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
&[data-placement='left'] {
|
|
53
|
+
margin-right: var(--popover-margin);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
&[data-placement='right'] {
|
|
57
|
+
margin-left: var(--popover-margin);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Animation for popover open/close
|
|
62
|
+
.fpkit-popover:popover-open {
|
|
63
|
+
opacity: 1;
|
|
64
|
+
transform: scale(1);
|
|
65
|
+
transition:
|
|
66
|
+
opacity 0.2s ease-out,
|
|
67
|
+
transform 0.2s ease-out,
|
|
68
|
+
overlay 0.2s ease-out allow-discrete,
|
|
69
|
+
display 0.2s ease-out allow-discrete;
|
|
70
|
+
|
|
71
|
+
@starting-style {
|
|
72
|
+
opacity: 0;
|
|
73
|
+
transform: scale(0.95);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Closing animation
|
|
78
|
+
.fpkit-popover:not(:popover-open) {
|
|
79
|
+
opacity: 0;
|
|
80
|
+
transform: scale(0.95);
|
|
81
|
+
transition:
|
|
82
|
+
opacity 0.2s ease-in,
|
|
83
|
+
transform 0.2s ease-in,
|
|
84
|
+
overlay 0.2s ease-in allow-discrete,
|
|
85
|
+
display 0.2s ease-in allow-discrete;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Backdrop for manual mode
|
|
89
|
+
.fpkit-popover::backdrop {
|
|
90
|
+
background: rgba(0, 0, 0, 0.3);
|
|
91
|
+
backdrop-filter: blur(0.125rem);
|
|
92
|
+
transition:
|
|
93
|
+
background 0.2s ease-out,
|
|
94
|
+
backdrop-filter 0.2s ease-out,
|
|
95
|
+
overlay 0.2s ease-out allow-discrete,
|
|
96
|
+
display 0.2s ease-out allow-discrete;
|
|
97
|
+
|
|
98
|
+
@starting-style {
|
|
99
|
+
background: rgba(0, 0, 0, 0);
|
|
100
|
+
backdrop-filter: blur(0);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Popover content wrapper
|
|
105
|
+
.fpkit-popover-content {
|
|
106
|
+
position: relative;
|
|
107
|
+
display: block;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Close button
|
|
111
|
+
.fpkit-popover-close {
|
|
112
|
+
position: absolute;
|
|
113
|
+
top: 0.5rem;
|
|
114
|
+
right: 0.5rem;
|
|
115
|
+
width: var(--popover-close-size);
|
|
116
|
+
height: var(--popover-close-size);
|
|
117
|
+
display: flex;
|
|
118
|
+
align-items: center;
|
|
119
|
+
justify-content: center;
|
|
120
|
+
background: transparent;
|
|
121
|
+
border: none;
|
|
122
|
+
border-radius: 0.25rem;
|
|
123
|
+
color: var(--popover-close-color);
|
|
124
|
+
font-size: 1rem;
|
|
125
|
+
line-height: 1;
|
|
126
|
+
cursor: pointer;
|
|
127
|
+
transition:
|
|
128
|
+
background-color 0.15s ease,
|
|
129
|
+
color 0.15s ease;
|
|
130
|
+
|
|
131
|
+
&:hover {
|
|
132
|
+
background: var(--popover-close-hover-bg);
|
|
133
|
+
color: var(--popover-close-hover-color);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
&:focus-visible {
|
|
137
|
+
outline: 0.125rem solid currentColor;
|
|
138
|
+
outline-offset: 0.125rem;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// Arrow styles
|
|
143
|
+
.fpkit-popover-arrow {
|
|
144
|
+
position: absolute;
|
|
145
|
+
width: var(--popover-arrow-size);
|
|
146
|
+
height: var(--popover-arrow-size);
|
|
147
|
+
background: var(--popover-arrow-color);
|
|
148
|
+
transform: rotate(45deg);
|
|
149
|
+
border: inherit;
|
|
150
|
+
|
|
151
|
+
// Top placement - arrow at bottom
|
|
152
|
+
&[data-placement='top'] {
|
|
153
|
+
bottom: calc(var(--popover-arrow-size) / -2);
|
|
154
|
+
left: 50%;
|
|
155
|
+
margin-left: calc(var(--popover-arrow-size) / -2);
|
|
156
|
+
border-top: none;
|
|
157
|
+
border-left: none;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// Bottom placement - arrow at top
|
|
161
|
+
&[data-placement='bottom'] {
|
|
162
|
+
top: calc(var(--popover-arrow-size) / -2);
|
|
163
|
+
left: 50%;
|
|
164
|
+
margin-left: calc(var(--popover-arrow-size) / -2);
|
|
165
|
+
border-bottom: none;
|
|
166
|
+
border-right: none;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// Left placement - arrow at right
|
|
170
|
+
&[data-placement='left'] {
|
|
171
|
+
right: calc(var(--popover-arrow-size) / -2);
|
|
172
|
+
top: 50%;
|
|
173
|
+
margin-top: calc(var(--popover-arrow-size) / -2);
|
|
174
|
+
border-left: none;
|
|
175
|
+
border-bottom: none;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// Right placement - arrow at left
|
|
179
|
+
&[data-placement='right'] {
|
|
180
|
+
left: calc(var(--popover-arrow-size) / -2);
|
|
181
|
+
top: 50%;
|
|
182
|
+
margin-top: calc(var(--popover-arrow-size) / -2);
|
|
183
|
+
border-right: none;
|
|
184
|
+
border-top: none;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// Default trigger button
|
|
189
|
+
.fpkit-popover-trigger {
|
|
190
|
+
padding: 0.5rem 1rem;
|
|
191
|
+
background: #0066cc;
|
|
192
|
+
color: #ffffff;
|
|
193
|
+
border: none;
|
|
194
|
+
border-radius: 0.25rem;
|
|
195
|
+
font-size: 1rem;
|
|
196
|
+
cursor: pointer;
|
|
197
|
+
transition:
|
|
198
|
+
background-color 0.15s ease,
|
|
199
|
+
transform 0.1s ease;
|
|
200
|
+
|
|
201
|
+
&:hover {
|
|
202
|
+
background: #0052a3;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
&:active {
|
|
206
|
+
transform: scale(0.98);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
&:focus-visible {
|
|
210
|
+
outline: 0.125rem solid currentColor;
|
|
211
|
+
outline-offset: 0.125rem;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// CSS Anchor Positioning (Progressive Enhancement)
|
|
216
|
+
// Only applies when browser supports anchor positioning
|
|
217
|
+
@supports (anchor-name: --trigger) {
|
|
218
|
+
.fpkit-popover-trigger {
|
|
219
|
+
anchor-name: --trigger;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
.fpkit-popover {
|
|
223
|
+
position-anchor: --trigger;
|
|
224
|
+
|
|
225
|
+
&[data-placement='top'] {
|
|
226
|
+
bottom: anchor(top);
|
|
227
|
+
left: anchor(center);
|
|
228
|
+
translate: -50% 0;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
&[data-placement='bottom'] {
|
|
232
|
+
top: anchor(bottom);
|
|
233
|
+
left: anchor(center);
|
|
234
|
+
translate: -50% 0;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
&[data-placement='left'] {
|
|
238
|
+
right: anchor(left);
|
|
239
|
+
top: anchor(center);
|
|
240
|
+
translate: 0 -50%;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
&[data-placement='right'] {
|
|
244
|
+
left: anchor(right);
|
|
245
|
+
top: anchor(center);
|
|
246
|
+
translate: 0 -50%;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
}
|