Implement popover component

Committed-by: Konstantin Schaper <konstantin.schaper@cloudogu.com>
Co-authored-by: Konstantin Schaper <konstantin.schaper@cloudogu.com>
This commit is contained in:
Thomas Zerr
2023-08-15 15:16:48 +02:00
parent 7a352295ab
commit 8d873a269e
10 changed files with 326 additions and 6 deletions

View File

@@ -0,0 +1,2 @@
- type: added
description: popover component

View File

@@ -18,6 +18,7 @@
"@scm-manager/tsconfig": "^2.13.0",
"@scm-manager/ui-styles": "2.45.3-SNAPSHOT",
"@storybook/addon-actions": "^6.5.10",
"@storybook/addon-docs": "^6.5.14",
"@storybook/addon-essentials": "^6.5.10",
"@storybook/addon-interactions": "^6.5.10",
"@storybook/addon-links": "^6.5.10",
@@ -25,24 +26,24 @@
"@storybook/manager-webpack5": "^6.5.10",
"@storybook/react": "^6.5.10",
"@storybook/testing-library": "^0.0.13",
"@storybook/addon-docs": "^6.5.14",
"babel-loader": "^8.2.5",
"storybook-addon-mock": "^3.2.0",
"storybook-addon-themes": "^6.1.0",
"tsup": "^6.2.3"
},
"peerDependencies": {
"classnames": "2",
"react": "17",
"react-dom": "17",
"react-i18next": "11",
"react-router-dom": "5",
"classnames": "2",
"styled-components": "5",
"react-i18next": "11"
"styled-components": "5"
},
"dependencies": {
"@radix-ui/react-tooltip": "1.0.2",
"@radix-ui/react-dialog": "1.0.2",
"@radix-ui/react-dropdown-menu": "2.0.1",
"@radix-ui/react-popover": "1.0.6",
"@radix-ui/react-tooltip": "1.0.2",
"@scm-manager/ui-buttons": "2.45.3-SNAPSHOT"
},
"prettier": "@scm-manager/prettier-config",
@@ -53,4 +54,3 @@
"access": "public"
}
}

View File

@@ -0,0 +1,62 @@
/*
* MIT License
*
* Copyright (c) 2020-present Cloudogu GmbH and Contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
import Popover from "./Popover";
import { ComponentMeta, ComponentStory } from "@storybook/react";
import React from "react";
export default {
title: "Popover",
component: Popover,
} as ComponentMeta<typeof Popover>;
const Template: ComponentStory<typeof Popover> = (args) => <Popover {...args} />;
export const CiStatus = Template.bind({});
CiStatus.args = {
trigger: (
<button className={"is-borderless has-background-transparent"}>
<i className={"fas fa-1x has-text-secondary fa-circle-notch"}></i>
</button>
),
title: <h1>Analyses: 0 error found</h1>,
children: (
<>
<hr className={"my-2"} />
<a className={"has-hover-background-blue is-flex is-flex-direction-row px-2 py-2 is-align-items-center"}>
<i className={"fas fa-1x has-text-secondary fa-circle-notch mr-2"}></i>
<span className="has-text-default">
<strong>jenkins:</strong> scm-manager » scm-manager » develop
</span>
</a>
<hr className={"my-2"} />
<a className={"has-hover-background-blue is-flex is-flex-direction-row px-2 py-2 is-align-items-center"}>
<i className={"fas fa-1x has-text-secondary fa-circle-notch mr-2"}></i>
<span className={"has-text-default"}>
<strong>Sonar:</strong> Sonar
</span>
</a>
</>
),
};

View File

@@ -0,0 +1,95 @@
/*
* MIT License
*
* Copyright (c) 2020-present Cloudogu GmbH and Contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
import React, { ReactElement, ReactNode } from "react";
import * as RadixPopover from "@radix-ui/react-popover";
import styled from "styled-components";
import classNames from "classnames";
import { useTranslation } from "react-i18next";
const StyledContent = styled(RadixPopover.Content)`
z-index: 1020;
`;
const StyledArrow = styled(RadixPopover.Arrow)`
fill: var(--scm-popover-border-color);
z-index: 1020;
`;
const TitleContainer = styled("div")`
flex: 1;
`;
type Props = {
/**
* Element to trigger the popover
*/
trigger: ReactElement;
/**
* Element for the content of the popover
*/
children: ReactElement;
/**
* Element for the title row of the popover
*/
title: ReactNode;
/**
* Classnames for the content of the popover
*/
className?: string;
};
/**
* @beta
* @since 2.46.0
*/
const Popover = React.forwardRef<HTMLDivElement, Props>(({ title, className, trigger, children }, ref) => {
const [t] = useTranslation("commons");
return (
<RadixPopover.Root>
<RadixPopover.Trigger asChild>{trigger}</RadixPopover.Trigger>
<RadixPopover.Portal>
<StyledContent
ref={ref}
className={classNames("has-rounded-border", "p-2", "popover-content", "box", "popover", className)}
>
<div className="is-flex">
<TitleContainer>{title}</TitleContainer>
<RadixPopover.Close asChild>
<button className="delete popover-close" aria-label={t("popover.closeButton.ariaLabel")} />
</RadixPopover.Close>
</div>
{children}
<StyledArrow className="popover-arrow" />
</StyledContent>
</RadixPopover.Portal>
</RadixPopover.Root>
);
});
export default Popover;

View File

@@ -304,3 +304,7 @@ $danger-25: scale-color($danger, $lightness: -75%);
input[type="date"].input::-webkit-calendar-picker-indicator {
filter: invert(100%);
}
.popover-close {
background: $background;
}

View File

@@ -376,3 +376,7 @@ td:first-child.diff-gutter-conflict:before {
input[type="date"].input::-webkit-calendar-picker-indicator {
filter: invert(100%);
}
.popover-close {
background: $white-ter;
}

View File

@@ -50,6 +50,7 @@ $menu-item-color: #333;
/* Extensions */
$popover-background-color: $grey-light;
$popover-border-color: $grey-lightest;
@import "utils/_post.scss";

View File

@@ -4,6 +4,11 @@
"ariaLabel": "Dialog schließen"
}
},
"popover": {
"closeButton": {
"ariaLabel": "Popover schließen"
}
},
"menu": {
"defaultTriggerLabel": "Menü"
},

View File

@@ -4,6 +4,11 @@
"ariaLabel": "Close Dialog"
}
},
"popover": {
"closeButton": {
"ariaLabel": "Close Popover"
}
},
"menu": {
"defaultTriggerLabel": "Menu"
},

142
yarn.lock
View File

@@ -1560,6 +1560,13 @@
resolved "https://registry.npmjs.org/@floating-ui/core/-/core-0.7.3.tgz"
integrity sha512-buc8BXHmG9l82+OQXOFU3Kr2XQx9ys01U/Q9HMIrZ300iLc8HLMgh7dcCqgYzAzf4BkoQvDcXf5Y+CuEZ5JBYg==
"@floating-ui/core@^1.4.1":
version "1.4.1"
resolved "https://registry.yarnpkg.com/@floating-ui/core/-/core-1.4.1.tgz#0d633f4b76052668afb932492ac452f7ebe97f17"
integrity sha512-jk3WqquEJRlcyu7997NtR5PibI+y5bi+LS3hPmguVClypenMsCY3CBa3LAQnozRCtCrYWSEtAdiskpamuJRFOQ==
dependencies:
"@floating-ui/utils" "^0.1.1"
"@floating-ui/dom@^0.5.3":
version "0.5.4"
resolved "https://registry.npmjs.org/@floating-ui/dom/-/dom-0.5.4.tgz"
@@ -1567,6 +1574,14 @@
dependencies:
"@floating-ui/core" "^0.7.3"
"@floating-ui/dom@^1.3.0":
version "1.5.1"
resolved "https://registry.yarnpkg.com/@floating-ui/dom/-/dom-1.5.1.tgz#88b70defd002fe851f17b4a25efb2d3c04d7a8d7"
integrity sha512-KwvVcPSXg6mQygvA1TjbN/gh///36kKtllIF8SUm0qpFj8+rvYrpvlYdL1JoA71SHpDqgSSdGOSoQ0Mp3uY5aw==
dependencies:
"@floating-ui/core" "^1.4.1"
"@floating-ui/utils" "^0.1.1"
"@floating-ui/react-dom@0.7.2":
version "0.7.2"
resolved "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-0.7.2.tgz"
@@ -1575,6 +1590,18 @@
"@floating-ui/dom" "^0.5.3"
use-isomorphic-layout-effect "^1.1.1"
"@floating-ui/react-dom@^2.0.0":
version "2.0.1"
resolved "https://registry.yarnpkg.com/@floating-ui/react-dom/-/react-dom-2.0.1.tgz#7972a4fc488a8c746cded3cfe603b6057c308a91"
integrity sha512-rZtAmSht4Lry6gdhAJDrCp/6rKN7++JnL1/Anbr/DdeyYXQPxvg/ivrbYvJulbRf4vL8b212suwMM2lxbv+RQA==
dependencies:
"@floating-ui/dom" "^1.3.0"
"@floating-ui/utils@^0.1.1":
version "0.1.1"
resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.1.1.tgz#1a5b1959a528e374e8037c4396c3e825d6cf4a83"
integrity sha512-m0G6wlnhm/AX0H12IOWtK8gASEMffnX08RtKkCgTdHb9JpHKGloI7icFfLg9ZmQeavcvR0PKmzxClyuFPSjKWw==
"@fortawesome/fontawesome-free@^5.11.2":
version "5.15.4"
resolved "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-5.15.4.tgz"
@@ -2430,6 +2457,14 @@
"@babel/runtime" "^7.13.10"
"@radix-ui/react-primitive" "1.0.1"
"@radix-ui/react-arrow@1.0.3":
version "1.0.3"
resolved "https://registry.yarnpkg.com/@radix-ui/react-arrow/-/react-arrow-1.0.3.tgz#c24f7968996ed934d57fe6cde5d6ec7266e1d25d"
integrity sha512-wSP+pHsB/jQRaL6voubsQ/ZlrGBHHrOjmBnr19hxYgtS0WvAFwZhK2WP/YY5yF9uKECCEEDGxuLxq1NBK51wFA==
dependencies:
"@babel/runtime" "^7.13.10"
"@radix-ui/react-primitive" "1.0.3"
"@radix-ui/react-collapsible@^1.0.3":
version "1.0.3"
resolved "https://registry.npmjs.org/@radix-ui/react-collapsible/-/react-collapsible-1.0.3.tgz"
@@ -2524,6 +2559,18 @@
"@radix-ui/react-use-callback-ref" "1.0.0"
"@radix-ui/react-use-escape-keydown" "1.0.2"
"@radix-ui/react-dismissable-layer@1.0.4":
version "1.0.4"
resolved "https://registry.yarnpkg.com/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.0.4.tgz#883a48f5f938fa679427aa17fcba70c5494c6978"
integrity sha512-7UpBa/RKMoHJYjie1gkF1DlK8l1fdU/VKDpoS3rCCo8YBJR294GwcEHyxHw72yvphJ7ld0AXEcSLAzY2F/WyCg==
dependencies:
"@babel/runtime" "^7.13.10"
"@radix-ui/primitive" "1.0.1"
"@radix-ui/react-compose-refs" "1.0.1"
"@radix-ui/react-primitive" "1.0.3"
"@radix-ui/react-use-callback-ref" "1.0.1"
"@radix-ui/react-use-escape-keydown" "1.0.3"
"@radix-ui/react-dropdown-menu@2.0.1":
version "2.0.1"
resolved "https://registry.npmjs.org/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-2.0.1.tgz"
@@ -2545,6 +2592,13 @@
dependencies:
"@babel/runtime" "^7.13.10"
"@radix-ui/react-focus-guards@1.0.1":
version "1.0.1"
resolved "https://registry.yarnpkg.com/@radix-ui/react-focus-guards/-/react-focus-guards-1.0.1.tgz#1ea7e32092216b946397866199d892f71f7f98ad"
integrity sha512-Rect2dWbQ8waGzhMavsIbmSVCgYxkXLxxR3ZvCX79JOglzdEy4JXMb98lq4hPxUbLr77nP0UOGf4rcMU+s1pUA==
dependencies:
"@babel/runtime" "^7.13.10"
"@radix-ui/react-focus-scope@1.0.1":
version "1.0.1"
resolved "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.0.1.tgz"
@@ -2555,6 +2609,16 @@
"@radix-ui/react-primitive" "1.0.1"
"@radix-ui/react-use-callback-ref" "1.0.0"
"@radix-ui/react-focus-scope@1.0.3":
version "1.0.3"
resolved "https://registry.yarnpkg.com/@radix-ui/react-focus-scope/-/react-focus-scope-1.0.3.tgz#9c2e8d4ed1189a1d419ee61edd5c1828726472f9"
integrity sha512-upXdPfqI4islj2CslyfUBNlaJCPybbqRHAi1KER7Isel9Q2AtSJ0zRBZv8mWQiFXD2nyAJ4BhC3yXgZ6kMBSrQ==
dependencies:
"@babel/runtime" "^7.13.10"
"@radix-ui/react-compose-refs" "1.0.1"
"@radix-ui/react-primitive" "1.0.3"
"@radix-ui/react-use-callback-ref" "1.0.1"
"@radix-ui/react-id@1.0.0":
version "1.0.0"
resolved "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.0.0.tgz"
@@ -2596,6 +2660,28 @@
aria-hidden "^1.1.1"
react-remove-scroll "2.5.5"
"@radix-ui/react-popover@1.0.6":
version "1.0.6"
resolved "https://registry.yarnpkg.com/@radix-ui/react-popover/-/react-popover-1.0.6.tgz#19bb81e7450482c625b8cd05bf4dcd1d2cd91a8b"
integrity sha512-cZ4defGpkZ0qTRtlIBzJLSzL6ht7ofhhW4i1+pkemjV1IKXm0wgCRnee154qlV6r9Ttunmh2TNZhMfV2bavUyA==
dependencies:
"@babel/runtime" "^7.13.10"
"@radix-ui/primitive" "1.0.1"
"@radix-ui/react-compose-refs" "1.0.1"
"@radix-ui/react-context" "1.0.1"
"@radix-ui/react-dismissable-layer" "1.0.4"
"@radix-ui/react-focus-guards" "1.0.1"
"@radix-ui/react-focus-scope" "1.0.3"
"@radix-ui/react-id" "1.0.1"
"@radix-ui/react-popper" "1.1.2"
"@radix-ui/react-portal" "1.0.3"
"@radix-ui/react-presence" "1.0.1"
"@radix-ui/react-primitive" "1.0.3"
"@radix-ui/react-slot" "1.0.2"
"@radix-ui/react-use-controllable-state" "1.0.1"
aria-hidden "^1.1.1"
react-remove-scroll "2.5.5"
"@radix-ui/react-popper@1.0.1":
version "1.0.1"
resolved "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.0.1.tgz"
@@ -2612,6 +2698,23 @@
"@radix-ui/react-use-size" "1.0.0"
"@radix-ui/rect" "1.0.0"
"@radix-ui/react-popper@1.1.2":
version "1.1.2"
resolved "https://registry.yarnpkg.com/@radix-ui/react-popper/-/react-popper-1.1.2.tgz#4c0b96fcd188dc1f334e02dba2d538973ad842e9"
integrity sha512-1CnGGfFi/bbqtJZZ0P/NQY20xdG3E0LALJaLUEoKwPLwl6PPPfbeiCqMVQnhoFRAxjJj4RpBRJzDmUgsex2tSg==
dependencies:
"@babel/runtime" "^7.13.10"
"@floating-ui/react-dom" "^2.0.0"
"@radix-ui/react-arrow" "1.0.3"
"@radix-ui/react-compose-refs" "1.0.1"
"@radix-ui/react-context" "1.0.1"
"@radix-ui/react-primitive" "1.0.3"
"@radix-ui/react-use-callback-ref" "1.0.1"
"@radix-ui/react-use-layout-effect" "1.0.1"
"@radix-ui/react-use-rect" "1.0.1"
"@radix-ui/react-use-size" "1.0.1"
"@radix-ui/rect" "1.0.1"
"@radix-ui/react-portal@1.0.1":
version "1.0.1"
resolved "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.0.1.tgz"
@@ -2620,6 +2723,14 @@
"@babel/runtime" "^7.13.10"
"@radix-ui/react-primitive" "1.0.1"
"@radix-ui/react-portal@1.0.3":
version "1.0.3"
resolved "https://registry.yarnpkg.com/@radix-ui/react-portal/-/react-portal-1.0.3.tgz#ffb961244c8ed1b46f039e6c215a6c4d9989bda1"
integrity sha512-xLYZeHrWoPmA5mEKEfZZevoVRK/Q43GfzRXkWV6qawIWWK8t6ifIiLQdd7rmQ4Vk1bmI21XhqF9BN3jWf+phpA==
dependencies:
"@babel/runtime" "^7.13.10"
"@radix-ui/react-primitive" "1.0.3"
"@radix-ui/react-presence@1.0.0":
version "1.0.0"
resolved "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.0.0.tgz"
@@ -2743,6 +2854,14 @@
"@babel/runtime" "^7.13.10"
"@radix-ui/react-use-callback-ref" "1.0.0"
"@radix-ui/react-use-escape-keydown@1.0.3":
version "1.0.3"
resolved "https://registry.yarnpkg.com/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.0.3.tgz#217b840c250541609c66f67ed7bab2b733620755"
integrity sha512-vyL82j40hcFicA+M4Ex7hVkB9vHgSse1ZWomAqV2Je3RleKGO5iM8KMOEtfoSB0PnIelMd2lATjTGMYqN5ylTg==
dependencies:
"@babel/runtime" "^7.13.10"
"@radix-ui/react-use-callback-ref" "1.0.1"
"@radix-ui/react-use-layout-effect@1.0.0":
version "1.0.0"
resolved "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.0.0.tgz"
@@ -2765,6 +2884,14 @@
"@babel/runtime" "^7.13.10"
"@radix-ui/rect" "1.0.0"
"@radix-ui/react-use-rect@1.0.1":
version "1.0.1"
resolved "https://registry.yarnpkg.com/@radix-ui/react-use-rect/-/react-use-rect-1.0.1.tgz#fde50b3bb9fd08f4a1cd204572e5943c244fcec2"
integrity sha512-Cq5DLuSiuYVKNU8orzJMbl15TXilTnJKUCltMVQg53BQOF1/C5toAaGrowkgksdBQ9H+SRL23g0HDmg9tvmxXw==
dependencies:
"@babel/runtime" "^7.13.10"
"@radix-ui/rect" "1.0.1"
"@radix-ui/react-use-size@1.0.0":
version "1.0.0"
resolved "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.0.0.tgz"
@@ -2773,6 +2900,14 @@
"@babel/runtime" "^7.13.10"
"@radix-ui/react-use-layout-effect" "1.0.0"
"@radix-ui/react-use-size@1.0.1":
version "1.0.1"
resolved "https://registry.yarnpkg.com/@radix-ui/react-use-size/-/react-use-size-1.0.1.tgz#1c5f5fea940a7d7ade77694bb98116fb49f870b2"
integrity sha512-ibay+VqrgcaI6veAojjofPATwledXiSmX+C0KrBk/xgpX9rBzPV3OsfwlhQdUOFbh+LKQorLYT+xTXW9V8yd0g==
dependencies:
"@babel/runtime" "^7.13.10"
"@radix-ui/react-use-layout-effect" "1.0.1"
"@radix-ui/react-visually-hidden@1.0.1":
version "1.0.1"
resolved "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.0.1.tgz"
@@ -2796,6 +2931,13 @@
dependencies:
"@babel/runtime" "^7.13.10"
"@radix-ui/rect@1.0.1":
version "1.0.1"
resolved "https://registry.yarnpkg.com/@radix-ui/rect/-/rect-1.0.1.tgz#bf8e7d947671996da2e30f4904ece343bc4a883f"
integrity sha512-fyrgCaedtvMg9NK3en0pnOYJdtfwxUcNolezkNPUsoX57X8oQk+NkqcvzHXD2uKNij6GXmWU9NDru2IWjrO4BQ==
dependencies:
"@babel/runtime" "^7.13.10"
"@reach/router@^1.2.1":
version "1.3.4"
resolved "https://registry.npmjs.org/@reach/router/-/router-1.3.4.tgz"