mirror of
https://github.com/webstudio-is/webstudio.git
synced 2026-11-09 22:14:29 +09:00
feat: add close button for popover element (#5205)
fixes #3988 ## Description This PR adds `PopoverClose` button to `Popover` element. Just exported and added the component from `@radix-ui/popover`. Which is where all the rest of the elements are being used. Existing project on staging - https://p-33460026-be01-4d80-8f4f-1d6677c38fe0-dot-pop-close.staging.webstudio.is Deployed project on staging - https://jk-popover-close-1ph18.wstd.work  ## Steps for reproduction - You can go to staging, and create a project with popover. - Deploy the project and checked the rendered popover ## Code Review - [ ] hi @kof, I need you to do - conceptual review (architecture, feature-correctness) - detailed review (read every line) - test it on preview ## Before requesting a review - [x] made a self-review ## Before merging - [x] tested locally and on preview environment (preview dev login: 0000)
This commit is contained in:
1 parent
a44530b068
commit
24efd92764
8 files changed
+130
-4
No files matched your search
@@ -61,3 +61,4 @@ export const propsPopoverContent: Record<string, PropMeta> = {
|
||||
options: ["always", "optimized"],
|
||||
},
|
||||
};
|
||||
export const propsPopoverClose: Record<string, PropMeta> = {};
|
||||
@@ -2,11 +2,13 @@ import {
|
||||
Box as Box,
|
||||
Button as Button,
|
||||
Text as Text,
|
||||
HtmlEmbed as HtmlEmbed,
|
||||
} from "@webstudio-is/sdk-components-react";
|
||||
import {
|
||||
Popover as Popover,
|
||||
PopoverTrigger as PopoverTrigger,
|
||||
PopoverContent as PopoverContent,
|
||||
PopoverClose as PopoverClose,
|
||||
} from "../components";
|
||||
|
||||
const Component = () => {
|
||||
@@ -18,6 +20,14 @@ const Component = () => {
|
||||
</PopoverTrigger>
|
||||
<PopoverContent className={"w-popover-content w-popover-content-1"}>
|
||||
<Text className={"w-text"}>{"The text you can edit"}</Text>
|
||||
<PopoverClose className={"w-close-button w-close-button-1"}>
|
||||
<HtmlEmbed
|
||||
code={
|
||||
'<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 16 16" width="100%" height="100%" style="display: block;"><path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" d="M12.5 3 3 12.5M3 3l9.5 9.5"/></svg>'
|
||||
}
|
||||
className={"w-html-embed"}
|
||||
/>
|
||||
</PopoverClose>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
</Box>
|
||||
@@ -131,6 +141,11 @@ const Story = {
|
||||
text-transform: none;
|
||||
margin: 0
|
||||
}
|
||||
:where(div.w-html-embed) {
|
||||
display: contents;
|
||||
white-space: normal;
|
||||
white-space-collapse: collapse
|
||||
}
|
||||
:where(div.w-text) {
|
||||
box-sizing: border-box;
|
||||
border-top-width: 1px;
|
||||
@@ -140,6 +155,18 @@ const Story = {
|
||||
outline-width: 1px;
|
||||
min-height: 1em
|
||||
}
|
||||
:where(button.w-close-button) {
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
font-family: inherit;
|
||||
font-size: 100%;
|
||||
line-height: 1.15;
|
||||
box-sizing: border-box;
|
||||
text-transform: none;
|
||||
border: 1px solid rgba(226, 232, 240, 1);
|
||||
margin: 0;
|
||||
padding: 0px
|
||||
}
|
||||
:where(div.w-popover-content) {
|
||||
box-sizing: border-box;
|
||||
border-top-width: 1px;
|
||||
@@ -196,6 +223,30 @@ const Story = {
|
||||
border: 1px solid rgba(226, 232, 240, 1);
|
||||
padding: 1rem
|
||||
}
|
||||
.w-close-button-1 {
|
||||
position: absolute;
|
||||
right: 1rem;
|
||||
top: 1rem;
|
||||
border-top-left-radius: 0.125rem;
|
||||
border-top-right-radius: 0.125rem;
|
||||
border-bottom-right-radius: 0.125rem;
|
||||
border-bottom-left-radius: 0.125rem;
|
||||
opacity: 0.7;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 1rem;
|
||||
width: 1rem;
|
||||
background-color: transparent;
|
||||
outline: medium none currentcolor;
|
||||
border: 0 none currentcolor
|
||||
}
|
||||
.w-close-button-1:focus-visible {
|
||||
box-shadow: 0 0 0 2px rgba(255, 255, 255, 1), 0 0 0 calc(2px + 2px) rgba(148, 163, 184, 1)
|
||||
}
|
||||
.w-close-button-1:hover {
|
||||
opacity: 1
|
||||
}
|
||||
}
|
||||
`}
|
||||
</style>
|
||||
|
||||
@@ -12,7 +12,12 @@ export {
|
||||
DialogTitle,
|
||||
DialogDescription,
|
||||
} from "./dialog";
|
||||
export { Popover, PopoverTrigger, PopoverContent } from "./popover";
|
||||
export {
|
||||
Popover,
|
||||
PopoverTrigger,
|
||||
PopoverContent,
|
||||
PopoverClose,
|
||||
} from "./popover";
|
||||
export { Tooltip, TooltipTrigger, TooltipContent } from "./tooltip";
|
||||
export { Tabs, TabsList, TabsTrigger, TabsContent } from "./tabs";
|
||||
export { Label } from "./label";
|
||||
|
||||
@@ -16,6 +16,7 @@ export {
|
||||
metaPopover as Popover,
|
||||
metaPopoverTrigger as PopoverTrigger,
|
||||
metaPopoverContent as PopoverContent,
|
||||
metaPopoverClose as PopoverClose,
|
||||
} from "./popover.ws";
|
||||
export {
|
||||
metaTooltip as Tooltip,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { LargeXIcon } from "@webstudio-is/icons/svg";
|
||||
import {
|
||||
$,
|
||||
css,
|
||||
@@ -14,6 +15,8 @@ import {
|
||||
spacing,
|
||||
width,
|
||||
zIndex,
|
||||
height,
|
||||
opacity,
|
||||
} from "./shared/theme";
|
||||
|
||||
/**
|
||||
@@ -52,6 +55,38 @@ export const meta: TemplateMeta = {
|
||||
`}
|
||||
>
|
||||
<$.Text>{new PlaceholderValue("The text you can edit")}</$.Text>
|
||||
<radix.PopoverClose
|
||||
ws:label="Close Button"
|
||||
/**
|
||||
* absolute right-4 top-4
|
||||
* rounded-sm opacity-70
|
||||
* ring-offset-background
|
||||
* hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2
|
||||
* flex items-center justify-center h-4 w-4
|
||||
**/
|
||||
ws:style={css`
|
||||
position: absolute;
|
||||
right: ${spacing[4]};
|
||||
top: ${spacing[4]};
|
||||
border-radius: ${borderRadius.sm};
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: ${height[4]};
|
||||
width: ${height[4]};
|
||||
border: 0;
|
||||
background-color: transparent;
|
||||
outline: none;
|
||||
&:hover {
|
||||
opacity: ${opacity[100]};
|
||||
}
|
||||
&:focus-visible {
|
||||
box-shadow: ${boxShadow.ring};
|
||||
}
|
||||
`}
|
||||
>
|
||||
<$.HtmlEmbed ws:label="Close Icon" code={LargeXIcon} />
|
||||
</radix.PopoverClose>
|
||||
</radix.PopoverContent>
|
||||
</radix.Popover>
|
||||
),
|
||||
|
||||
@@ -54,6 +54,8 @@ export const PopoverContent = forwardRef<
|
||||
)
|
||||
);
|
||||
|
||||
export const PopoverClose = PopoverPrimitive.Close;
|
||||
|
||||
/* BUILDER HOOKS */
|
||||
|
||||
const namespace = "@webstudio-is/sdk-components-react-radix";
|
||||
|
||||
@@ -1,12 +1,23 @@
|
||||
import { PopoverIcon, TriggerIcon, ContentIcon } from "@webstudio-is/icons/svg";
|
||||
import type { WsComponentMeta, WsComponentPropsMeta } from "@webstudio-is/sdk";
|
||||
import { div } from "@webstudio-is/sdk/normalize.css";
|
||||
import {
|
||||
PopoverIcon,
|
||||
TriggerIcon,
|
||||
ContentIcon,
|
||||
ButtonElementIcon,
|
||||
} from "@webstudio-is/icons/svg";
|
||||
import {
|
||||
defaultStates,
|
||||
type WsComponentMeta,
|
||||
type WsComponentPropsMeta,
|
||||
} from "@webstudio-is/sdk";
|
||||
import { button, div } from "@webstudio-is/sdk/normalize.css";
|
||||
import { radix } from "./shared/meta";
|
||||
import {
|
||||
propsPopover,
|
||||
propsPopoverContent,
|
||||
propsPopoverTrigger,
|
||||
propsPopoverClose,
|
||||
} from "./__generated__/popover.props";
|
||||
import { buttonReset } from "./shared/preset-styles";
|
||||
|
||||
// @todo add [data-state] to button and link
|
||||
export const metaPopoverTrigger: WsComponentMeta = {
|
||||
@@ -22,6 +33,7 @@ export const metaPopoverContent: WsComponentMeta = {
|
||||
contentModel: {
|
||||
category: "none",
|
||||
children: ["instance"],
|
||||
descendants: [radix.PopoverClose],
|
||||
},
|
||||
presetStyle: {
|
||||
div,
|
||||
@@ -37,6 +49,19 @@ export const metaPopover: WsComponentMeta = {
|
||||
},
|
||||
};
|
||||
|
||||
export const metaPopoverClose: WsComponentMeta = {
|
||||
icon: ButtonElementIcon,
|
||||
label: "Close Button",
|
||||
contentModel: {
|
||||
category: "none",
|
||||
children: ["instance", "rich-text"],
|
||||
},
|
||||
states: defaultStates,
|
||||
presetStyle: {
|
||||
button: [buttonReset, button].flat(),
|
||||
},
|
||||
};
|
||||
|
||||
export const propsMetaPopover: WsComponentPropsMeta = {
|
||||
props: propsPopover,
|
||||
initialProps: ["open"],
|
||||
@@ -50,3 +75,8 @@ export const propsMetaPopoverContent: WsComponentPropsMeta = {
|
||||
props: propsPopoverContent,
|
||||
initialProps: ["side", "sideOffset", "align", "alignOffset"],
|
||||
};
|
||||
|
||||
export const propsMetaPopoverClose: WsComponentPropsMeta = {
|
||||
props: propsPopoverClose,
|
||||
initialProps: [],
|
||||
};
|
||||
@@ -16,6 +16,7 @@ export {
|
||||
propsMetaPopover as Popover,
|
||||
propsMetaPopoverTrigger as PopoverTrigger,
|
||||
propsMetaPopoverContent as PopoverContent,
|
||||
propsMetaPopoverClose as PopoverClose,
|
||||
} from "./popover.ws";
|
||||
export {
|
||||
propsMetaTooltip as Tooltip,
|
||||
|
||||
Reference in new issue
Block a user