mirror of
https://github.com/supabase/supabase.git
synced 2026-10-10 20:05:06 +03:00
## What kind of change does this PR introduce? Feature ## What is the current behavior? - Platform webhooks have a ‘tap target on tap target’ pattern with `DropdownMenu` being on top of a clickable `TableRow` - Misclicks are common (at least for me) - @jordienr recently added the `hit-area` Tailwind plugin that helps with misclicks - https://github.com/supabase/supabase/pull/43636 ## What is the new behavior? - The aforementioned `DropdownMenu` in platform webhooks now uses `hit-area` to avoid misclicks - Design system documentation - Extracted `hit-area` Tailwind plugin to shared packages so it can be used in design-system as well as studio ## Preview https://github.com/user-attachments/assets/89f9110a-6c99-4eed-a386-a6f646b1f4f6
144 lines
3.7 KiB
JavaScript
144 lines
3.7 KiB
JavaScript
const plugin = require('tailwindcss/plugin')
|
|
|
|
/**
|
|
* Hit Area plugin (Tailwind v3)
|
|
*
|
|
* Expands the interactive hit area of an element using a ::before pseudo-element,
|
|
* without affecting the visual layout.
|
|
*
|
|
* Usage:
|
|
* hit-area — adds invisible ::before that fills the element (0px expansion)
|
|
* hit-area-debug — same but with a visible blue dashed border overlay (hover turns green)
|
|
* hit-area-{n} — expands all sides by spacing value n (e.g. hit-area-2 → -0.5rem on each side)
|
|
* hit-area-x-{n} — expands left + right
|
|
* hit-area-y-{n} — expands top + bottom
|
|
* hit-area-t-{n} — expands top only
|
|
* hit-area-b-{n} — expands bottom only
|
|
* hit-area-l-{n} — expands left only
|
|
* hit-area-r-{n} — expands right only
|
|
*
|
|
* Arbitrary values are also supported, e.g. hit-area-[12px], hit-area-x-[1rem].
|
|
*/
|
|
module.exports = plugin(function ({ addUtilities, matchUtilities, theme }) {
|
|
const beforeBase = {
|
|
content: '""',
|
|
position: 'absolute',
|
|
top: 'var(--hit-area-t, 0px)',
|
|
right: 'var(--hit-area-r, 0px)',
|
|
bottom: 'var(--hit-area-b, 0px)',
|
|
left: 'var(--hit-area-l, 0px)',
|
|
pointerEvents: 'inherit',
|
|
}
|
|
|
|
// Static utilities
|
|
addUtilities({
|
|
'.hit-area': {
|
|
position: 'relative',
|
|
'&::before': { ...beforeBase },
|
|
},
|
|
'.hit-area-debug': {
|
|
position: 'relative',
|
|
'&::before': {
|
|
...beforeBase,
|
|
border: '1px dashed #3b82f6',
|
|
backgroundColor: 'rgb(59 130 246 / 0.1)',
|
|
},
|
|
'&:hover::before': {
|
|
border: '1px dashed #22c55e',
|
|
backgroundColor: 'rgb(34 197 94 / 0.1)',
|
|
},
|
|
},
|
|
})
|
|
|
|
const spacingConfig = { values: theme('spacing'), supportsNegativeValues: false }
|
|
|
|
// hit-area-{value} — all sides
|
|
matchUtilities(
|
|
{
|
|
'hit-area': (value) => ({
|
|
position: 'relative',
|
|
'--hit-area-t': `calc(${value} * -1)`,
|
|
'--hit-area-b': `calc(${value} * -1)`,
|
|
'--hit-area-l': `calc(${value} * -1)`,
|
|
'--hit-area-r': `calc(${value} * -1)`,
|
|
'&::before': { ...beforeBase },
|
|
}),
|
|
},
|
|
spacingConfig
|
|
)
|
|
|
|
// hit-area-x-{value} — left + right
|
|
matchUtilities(
|
|
{
|
|
'hit-area-x': (value) => ({
|
|
position: 'relative',
|
|
'--hit-area-l': `calc(${value} * -1)`,
|
|
'--hit-area-r': `calc(${value} * -1)`,
|
|
'&::before': { ...beforeBase },
|
|
}),
|
|
},
|
|
spacingConfig
|
|
)
|
|
|
|
// hit-area-y-{value} — top + bottom
|
|
matchUtilities(
|
|
{
|
|
'hit-area-y': (value) => ({
|
|
position: 'relative',
|
|
'--hit-area-t': `calc(${value} * -1)`,
|
|
'--hit-area-b': `calc(${value} * -1)`,
|
|
'&::before': { ...beforeBase },
|
|
}),
|
|
},
|
|
spacingConfig
|
|
)
|
|
|
|
// hit-area-t-{value} — top only
|
|
matchUtilities(
|
|
{
|
|
'hit-area-t': (value) => ({
|
|
position: 'relative',
|
|
'--hit-area-t': `calc(${value} * -1)`,
|
|
'&::before': { ...beforeBase },
|
|
}),
|
|
},
|
|
spacingConfig
|
|
)
|
|
|
|
// hit-area-b-{value} — bottom only
|
|
matchUtilities(
|
|
{
|
|
'hit-area-b': (value) => ({
|
|
position: 'relative',
|
|
'--hit-area-b': `calc(${value} * -1)`,
|
|
'&::before': { ...beforeBase },
|
|
}),
|
|
},
|
|
spacingConfig
|
|
)
|
|
|
|
// hit-area-l-{value} — left only
|
|
matchUtilities(
|
|
{
|
|
'hit-area-l': (value) => ({
|
|
position: 'relative',
|
|
'--hit-area-l': `calc(${value} * -1)`,
|
|
'&::before': { ...beforeBase },
|
|
}),
|
|
},
|
|
spacingConfig
|
|
)
|
|
|
|
// hit-area-r-{value} — right only
|
|
matchUtilities(
|
|
{
|
|
'hit-area-r': (value) => ({
|
|
position: 'relative',
|
|
'--hit-area-r': `calc(${value} * -1)`,
|
|
'&::before': { ...beforeBase },
|
|
}),
|
|
},
|
|
spacingConfig
|
|
)
|
|
})
|