diff --git a/scm-ui/ui-layout/src/card-list/CardList.stories.tsx b/scm-ui/ui-layout/src/card-list/CardList.stories.tsx index 2d9b7aa9d2..1166e7c351 100644 --- a/scm-ui/ui-layout/src/card-list/CardList.stories.tsx +++ b/scm-ui/ui-layout/src/card-list/CardList.stories.tsx @@ -27,12 +27,11 @@ import { ComponentMeta, StoryFn } from "@storybook/react"; import React, { ComponentProps } from "react"; import { ExtractProps } from "@scm-manager/ui-extensions"; import { Link } from "react-router-dom"; -import CardList, { CardListBox } from "./CardList"; -import Card from "./Card"; -import CardTitle from "./CardTitle"; +import CardList, { CardListBox, CardListCard } from "./CardList"; +import CardTitle from "../card/CardTitle"; import { Menu } from "@scm-manager/ui-overlays"; import { Icon } from "@scm-manager/ui-buttons"; -import CardRow from "./CardRow"; +import CardRow from "../card/CardRow"; export default { title: "CardList", @@ -46,22 +45,50 @@ export const Default = Template.bind({}); // More on args: https://storybook.js.org/docs/react/writing-stories/args Default.args = { children: [ - // eslint-disable-next-line no-console - - - My favorite repository - - , - - - - - My least liked repo - - - - , - + My favorite repository + , + + + trash + Delete + + + } + > + Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et + dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita + kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur + sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam + voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata + sanctus est Lorem ipsum dolor sit amet. + , + + + trash + Delete + + + } + > + + + My favorite repository with a very long title and some other things + + + , + + + + My least liked repo + + + , + @@ -86,8 +113,8 @@ Default.args = { This is a third row, lets see how this works out.(MERGED) - , - + , + (OPEN) - , + , ], } as ComponentProps; diff --git a/scm-ui/ui-layout/src/card-list/CardList.tsx b/scm-ui/ui-layout/src/card-list/CardList.tsx index a34837efc1..f75c3dd70a 100644 --- a/scm-ui/ui-layout/src/card-list/CardList.tsx +++ b/scm-ui/ui-layout/src/card-list/CardList.tsx @@ -22,18 +22,30 @@ * SOFTWARE. */ -import React, { HTMLAttributes } from "react"; +import React, { ComponentProps, HTMLAttributes } from "react"; import classNames from "classnames"; import styled from "styled-components"; +import Card from "../card/Card"; + +/** + * @beta + * @since 2.44.0 + */ +export const CardListCard = React.forwardRef, "as">>((props, ref) => ( + +)); const CardListElement = styled.ul` > * + * { - border-top: var(--scm-border); - margin-top: 0.5rem; - padding-top: 1rem !important; + margin-top: calc(0.5rem + 1px); - *:is(h1, h2, h3, h4, h5, h6) a::after { - top: 0.5rem !important; + &::before { + content: ""; + position: absolute; + width: 100%; + border-top: var(--scm-border); + left: 0; + top: calc(-0.25rem - 1px); } } `; @@ -41,8 +53,6 @@ const CardListElement = styled.ul` type Props = HTMLAttributes; /** - * The {@link CardList.Card.Title} is currently represented as a `h3`, which means the list can only be used on the top level of the page without breaking accessibility. - * * @beta * @since 2.44.0 */ @@ -53,8 +63,6 @@ const CardList = React.forwardRef(({ children, classNam )); /** - * The {@link CardList.Card.Title} is currently represented as a `h3`, which means the list can only be used on the top level of the page without breaking accessibility. - * * @beta * @since 2.44.0 */ diff --git a/scm-ui/ui-layout/src/card-list/Card.tsx b/scm-ui/ui-layout/src/card/Card.tsx similarity index 62% rename from scm-ui/ui-layout/src/card-list/Card.tsx rename to scm-ui/ui-layout/src/card/Card.tsx index b0365c5bb7..d11fbb8593 100644 --- a/scm-ui/ui-layout/src/card-list/Card.tsx +++ b/scm-ui/ui-layout/src/card/Card.tsx @@ -22,36 +22,39 @@ * SOFTWARE. */ -import React, { LiHTMLAttributes } from "react"; +import React, { ComponentType, HTMLAttributes, ReactHTML, Ref } from "react"; import styled from "styled-components"; import classNames from "classnames"; -const CardElement = styled.li` - display: grid; - grid-template-columns: minmax(0, 1fr) min-content; - grid-template-rows: auto; +const CardRowsContainer = styled.div` + overflow: hidden; `; -const CardActionContainer = styled.span` - grid-column: -1; - grid-row: 1; - margin-top: -0.5rem; - margin-right: -0.5rem; -`; - -type Props = LiHTMLAttributes & { +type Props = HTMLAttributes & { action?: React.ReactElement; + /** + * @default 'div' + */ + as?: keyof ReactHTML | ComponentType & { ref?: Ref }>; }; /** * @beta * @since 2.44.0 */ -const Card = React.forwardRef(({ className, children, action, ...props }, ref) => ( - - {children} - {action ? {action} : null} - -)); +const Card = React.forwardRef(({ className, children, as: Comp = "div", action, ...props }, ref) => + React.createElement( + Comp, + { + className: classNames(className, "is-relative", "is-flex", "scmm-card"), + ref, + ...props, + }, + + {children} + , + action ? {action} : null + ) +); export default Card; diff --git a/scm-ui/ui-layout/src/card-list/CardRow.tsx b/scm-ui/ui-layout/src/card/CardRow.tsx similarity index 73% rename from scm-ui/ui-layout/src/card-list/CardRow.tsx rename to scm-ui/ui-layout/src/card/CardRow.tsx index 68c52c2a2f..0e78882339 100644 --- a/scm-ui/ui-layout/src/card-list/CardRow.tsx +++ b/scm-ui/ui-layout/src/card/CardRow.tsx @@ -22,24 +22,10 @@ * SOFTWARE. */ -import React, { HTMLAttributes } from "react"; -import styled from "styled-components"; -import classNames from "classnames"; - -const CardRowElement = styled.div` - grid-column: 1 / 2; -`; - -type Props = HTMLAttributes; - /** * @beta * @since 2.44.0 */ -const CardRow = React.forwardRef(({ className, children, ...props }, ref) => ( - - {children} - -)); +const CardRow = "div"; export default CardRow; diff --git a/scm-ui/ui-layout/src/card-list/CardTitle.tsx b/scm-ui/ui-layout/src/card/CardTitle.tsx similarity index 72% rename from scm-ui/ui-layout/src/card-list/CardTitle.tsx rename to scm-ui/ui-layout/src/card/CardTitle.tsx index 7316bbc506..a9a627738b 100644 --- a/scm-ui/ui-layout/src/card-list/CardTitle.tsx +++ b/scm-ui/ui-layout/src/card/CardTitle.tsx @@ -23,38 +23,14 @@ */ import React, { HTMLAttributes } from "react"; -import styled from "styled-components"; import classNames from "classnames"; -const CardTitleElement = styled.h3` - a { - color: var(--scm-secondary-text); - - &:focus { - outline: none; - &::after { - outline: #af3ee7 3px solid; - outline-offset: 0px; - } - } - - &:hover::after { - background-color: var(--scm-hover-color-blue); - } - - &::after { - content: ""; - position: absolute; - top: 0; - left: 0; - bottom: 0; - right: 0; - border-radius: 4px; - } - } -`; - -type Props = HTMLAttributes; +type Props = HTMLAttributes & { + /** + * @default 3 + */ + level?: number; +}; /** * A card title may contain a link as its only child which will be automatically stretched to cover the whole card area. @@ -70,10 +46,16 @@ type Props = HTMLAttributes; * @beta * @since 2.44.0 */ -const CardTitle = React.forwardRef(({ children, className, ...props }, ref) => ( - - {children} - -)); +const CardTitle = React.forwardRef(({ children, level = 3, className, ...props }, ref) => + React.createElement( + `h${level}`, + { + className: classNames(className, "is-ellipsis-overflow"), + ref, + ...props, + }, + children + ) +); export default CardTitle; diff --git a/scm-ui/ui-layout/src/index.ts b/scm-ui/ui-layout/src/index.ts index 89e23fd883..7acf771d2d 100644 --- a/scm-ui/ui-layout/src/index.ts +++ b/scm-ui/ui-layout/src/index.ts @@ -22,13 +22,12 @@ * SOFTWARE. */ -import CardListComponent, { CardListBox as CardListBoxComponent } from "./card-list/CardList"; -import CardRow from "./card-list/CardRow"; -import Card from "./card-list/Card"; -import CardTitle from "./card-list/CardTitle"; +import CardListComponent, { CardListBox as CardListBoxComponent, CardListCard } from "./card-list/CardList"; +import CardTitle from "./card/CardTitle"; +import CardRow from "./card/CardRow"; const CardListExport = { - Card: Object.assign(Card, { + Card: Object.assign(CardListCard, { Row: CardRow, Title: CardTitle, }), diff --git a/scm-ui/ui-styles/src/components/_card.scss b/scm-ui/ui-styles/src/components/_card.scss new file mode 100644 index 0000000000..898a69a535 --- /dev/null +++ b/scm-ui/ui-styles/src/components/_card.scss @@ -0,0 +1,54 @@ +/* + * 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. + */ + +.scmm-card { + padding: 0.5rem; + + *:is(h1, h2, h3, h4, h5, h6) a { + color: var(--scm-secondary-text); + + &:focus { + outline: none; + + &::after { + outline: #af3ee7 2px solid; + outline-offset: 0; + } + } + + &:hover::after { + background-color: var(--scm-hover-color-blue); + } + + &::after { + content: ""; + position: absolute; + top: 0; + left: 0; + bottom: 0; + right: 0; + border-radius: 4px; + } + } +} diff --git a/scm-ui/ui-styles/src/utils/_post.scss b/scm-ui/ui-styles/src/utils/_post.scss index 098d2eeeec..f132a914c6 100644 --- a/scm-ui/ui-styles/src/utils/_post.scss +++ b/scm-ui/ui-styles/src/utils/_post.scss @@ -26,3 +26,4 @@ @import "bulma-popover/css/bulma-popover"; @import "../components/_main.scss"; @import "../components/_tooltip.scss"; +@import "../components/_card.scss";