mirror of
https://github.com/scm-manager/scm-manager.git
synced 2026-07-06 23:28:51 +02:00
Add new api for interactive card details
Committed-by: Rene Pfeuffer <rene.pfeuffer@cloudogu.com>
This commit is contained in:
2
gradle/changelog/card_click_targets.yaml
Normal file
2
gradle/changelog/card_click_targets.yaml
Normal file
@@ -0,0 +1,2 @@
|
||||
- type: added
|
||||
description: New api for interactive card details
|
||||
@@ -22,7 +22,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
import React from "react";
|
||||
import React, { ComponentProps } from "react";
|
||||
|
||||
import {
|
||||
Button as ButtonComponent,
|
||||
@@ -34,8 +34,6 @@ import {
|
||||
import StoryRouter from "storybook-react-router";
|
||||
import { StoryFn } from "@storybook/react";
|
||||
|
||||
type ExtractProps<T> = T extends React.ComponentType<infer U> ? U : never;
|
||||
|
||||
// More on default export: https://storybook.js.org/docs/react/writing-stories/introduction#default-export
|
||||
export default {
|
||||
title: "Components",
|
||||
@@ -58,11 +56,11 @@ export default {
|
||||
};
|
||||
|
||||
// More on component templates: https://storybook.js.org/docs/react/writing-stories/introduction#using-args
|
||||
const ButtonTemplate: StoryFn<ExtractProps<typeof ButtonComponent>> = (args) => <ButtonComponent {...args} />;
|
||||
const LinkButtonTemplate: StoryFn<ExtractProps<typeof LinkButtonComponent>> = (args) => (
|
||||
const ButtonTemplate: StoryFn<ComponentProps<typeof ButtonComponent>> = (args) => <ButtonComponent {...args} />;
|
||||
const LinkButtonTemplate: StoryFn<ComponentProps<typeof LinkButtonComponent>> = (args) => (
|
||||
<LinkButtonComponent {...args} />
|
||||
);
|
||||
const ExternalLinkButtonTemplate: StoryFn<ExtractProps<typeof ExternalLinkButtonComponent>> = (args) => (
|
||||
const ExternalLinkButtonTemplate: StoryFn<ComponentProps<typeof ExternalLinkButtonComponent>> = (args) => (
|
||||
<ExternalLinkButtonComponent {...args} />
|
||||
);
|
||||
|
||||
|
||||
@@ -71110,7 +71110,7 @@ exports[`Storyshots Repositories/RepositoryEntry Archived 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="is-flex is-flex-direction-column is-justify-content-center is-flex-grow-1 is-overflow-wrap-anywhere"
|
||||
className="sc-iBkjds idsAPT is-flex is-flex-direction-column is-justify-content-center is-flex-grow-1 is-overflow-hidden is-overflow-wrap-anywhere"
|
||||
style={
|
||||
Object {
|
||||
"gap": "0.25rem",
|
||||
@@ -71118,7 +71118,7 @@ exports[`Storyshots Repositories/RepositoryEntry Archived 1`] = `
|
||||
}
|
||||
>
|
||||
<div
|
||||
className="is-flex"
|
||||
className="is-flex ml-1"
|
||||
>
|
||||
<h4>
|
||||
<a
|
||||
@@ -71132,12 +71132,12 @@ exports[`Storyshots Repositories/RepositoryEntry Archived 1`] = `
|
||||
</h4>
|
||||
</div>
|
||||
<div
|
||||
className="RepositoryEntry__DescriptionRow-sc-6jys82-2 dzxasi is-size-7"
|
||||
className="RepositoryEntry__DescriptionRow-sc-6jys82-2 dzxasi is-size-7 ml-1"
|
||||
>
|
||||
The starship Heart of Gold was the first spacecraft to make use of the Infinite Improbability Drive
|
||||
</div>
|
||||
<div
|
||||
className="RepositoryEntry__DetailsRow-sc-6jys82-3 kXjiC is-flex is-align-items-center is-justify-content-space-between is-flex-wrap-wrap"
|
||||
className="RepositoryEntry__DetailsRow-sc-6jys82-3 kXjiC is-flex is-align-items-center is-justify-content-space-between is-flex-wrap-wrap ml-1"
|
||||
>
|
||||
<span
|
||||
className="is-size-7 has-text-secondary is-relative"
|
||||
@@ -71238,7 +71238,7 @@ exports[`Storyshots Repositories/RepositoryEntry Avatar EP 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="is-flex is-flex-direction-column is-justify-content-center is-flex-grow-1 is-overflow-wrap-anywhere"
|
||||
className="sc-iBkjds idsAPT is-flex is-flex-direction-column is-justify-content-center is-flex-grow-1 is-overflow-hidden is-overflow-wrap-anywhere"
|
||||
style={
|
||||
Object {
|
||||
"gap": "0.25rem",
|
||||
@@ -71246,7 +71246,7 @@ exports[`Storyshots Repositories/RepositoryEntry Avatar EP 1`] = `
|
||||
}
|
||||
>
|
||||
<div
|
||||
className="is-flex"
|
||||
className="is-flex ml-1"
|
||||
>
|
||||
<h4>
|
||||
<a
|
||||
@@ -71260,12 +71260,12 @@ exports[`Storyshots Repositories/RepositoryEntry Avatar EP 1`] = `
|
||||
</h4>
|
||||
</div>
|
||||
<div
|
||||
className="RepositoryEntry__DescriptionRow-sc-6jys82-2 dzxasi is-size-7"
|
||||
className="RepositoryEntry__DescriptionRow-sc-6jys82-2 dzxasi is-size-7 ml-1"
|
||||
>
|
||||
The starship Heart of Gold was the first spacecraft to make use of the Infinite Improbability Drive
|
||||
</div>
|
||||
<div
|
||||
className="RepositoryEntry__DetailsRow-sc-6jys82-3 kXjiC is-flex is-align-items-center is-justify-content-space-between is-flex-wrap-wrap"
|
||||
className="RepositoryEntry__DetailsRow-sc-6jys82-3 kXjiC is-flex is-align-items-center is-justify-content-space-between is-flex-wrap-wrap ml-1"
|
||||
>
|
||||
<span
|
||||
className="is-size-7 has-text-secondary is-relative"
|
||||
@@ -71354,7 +71354,7 @@ exports[`Storyshots Repositories/RepositoryEntry Before Title EP 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="is-flex is-flex-direction-column is-justify-content-center is-flex-grow-1 is-overflow-wrap-anywhere"
|
||||
className="sc-iBkjds idsAPT is-flex is-flex-direction-column is-justify-content-center is-flex-grow-1 is-overflow-hidden is-overflow-wrap-anywhere"
|
||||
style={
|
||||
Object {
|
||||
"gap": "0.25rem",
|
||||
@@ -71362,7 +71362,7 @@ exports[`Storyshots Repositories/RepositoryEntry Before Title EP 1`] = `
|
||||
}
|
||||
>
|
||||
<div
|
||||
className="is-flex"
|
||||
className="is-flex ml-1"
|
||||
>
|
||||
<i
|
||||
className="far fa-star"
|
||||
@@ -71379,12 +71379,12 @@ exports[`Storyshots Repositories/RepositoryEntry Before Title EP 1`] = `
|
||||
</h4>
|
||||
</div>
|
||||
<div
|
||||
className="RepositoryEntry__DescriptionRow-sc-6jys82-2 dzxasi is-size-7"
|
||||
className="RepositoryEntry__DescriptionRow-sc-6jys82-2 dzxasi is-size-7 ml-1"
|
||||
>
|
||||
The starship Heart of Gold was the first spacecraft to make use of the Infinite Improbability Drive
|
||||
</div>
|
||||
<div
|
||||
className="RepositoryEntry__DetailsRow-sc-6jys82-3 kXjiC is-flex is-align-items-center is-justify-content-space-between is-flex-wrap-wrap"
|
||||
className="RepositoryEntry__DetailsRow-sc-6jys82-3 kXjiC is-flex is-align-items-center is-justify-content-space-between is-flex-wrap-wrap ml-1"
|
||||
>
|
||||
<span
|
||||
className="is-size-7 has-text-secondary is-relative"
|
||||
@@ -71473,7 +71473,7 @@ exports[`Storyshots Repositories/RepositoryEntry Default 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="is-flex is-flex-direction-column is-justify-content-center is-flex-grow-1 is-overflow-wrap-anywhere"
|
||||
className="sc-iBkjds idsAPT is-flex is-flex-direction-column is-justify-content-center is-flex-grow-1 is-overflow-hidden is-overflow-wrap-anywhere"
|
||||
style={
|
||||
Object {
|
||||
"gap": "0.25rem",
|
||||
@@ -71481,7 +71481,7 @@ exports[`Storyshots Repositories/RepositoryEntry Default 1`] = `
|
||||
}
|
||||
>
|
||||
<div
|
||||
className="is-flex"
|
||||
className="is-flex ml-1"
|
||||
>
|
||||
<h4>
|
||||
<a
|
||||
@@ -71495,12 +71495,12 @@ exports[`Storyshots Repositories/RepositoryEntry Default 1`] = `
|
||||
</h4>
|
||||
</div>
|
||||
<div
|
||||
className="RepositoryEntry__DescriptionRow-sc-6jys82-2 dzxasi is-size-7"
|
||||
className="RepositoryEntry__DescriptionRow-sc-6jys82-2 dzxasi is-size-7 ml-1"
|
||||
>
|
||||
The starship Heart of Gold was the first spacecraft to make use of the Infinite Improbability Drive
|
||||
</div>
|
||||
<div
|
||||
className="RepositoryEntry__DetailsRow-sc-6jys82-3 kXjiC is-flex is-align-items-center is-justify-content-space-between is-flex-wrap-wrap"
|
||||
className="RepositoryEntry__DetailsRow-sc-6jys82-3 kXjiC is-flex is-align-items-center is-justify-content-space-between is-flex-wrap-wrap ml-1"
|
||||
>
|
||||
<span
|
||||
className="is-size-7 has-text-secondary is-relative"
|
||||
@@ -71589,7 +71589,7 @@ exports[`Storyshots Repositories/RepositoryEntry Exporting 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="is-flex is-flex-direction-column is-justify-content-center is-flex-grow-1 is-overflow-wrap-anywhere"
|
||||
className="sc-iBkjds idsAPT is-flex is-flex-direction-column is-justify-content-center is-flex-grow-1 is-overflow-hidden is-overflow-wrap-anywhere"
|
||||
style={
|
||||
Object {
|
||||
"gap": "0.25rem",
|
||||
@@ -71597,7 +71597,7 @@ exports[`Storyshots Repositories/RepositoryEntry Exporting 1`] = `
|
||||
}
|
||||
>
|
||||
<div
|
||||
className="is-flex"
|
||||
className="is-flex ml-1"
|
||||
>
|
||||
<h4>
|
||||
<a
|
||||
@@ -71611,12 +71611,12 @@ exports[`Storyshots Repositories/RepositoryEntry Exporting 1`] = `
|
||||
</h4>
|
||||
</div>
|
||||
<div
|
||||
className="RepositoryEntry__DescriptionRow-sc-6jys82-2 dzxasi is-size-7"
|
||||
className="RepositoryEntry__DescriptionRow-sc-6jys82-2 dzxasi is-size-7 ml-1"
|
||||
>
|
||||
The starship Heart of Gold was the first spacecraft to make use of the Infinite Improbability Drive
|
||||
</div>
|
||||
<div
|
||||
className="RepositoryEntry__DetailsRow-sc-6jys82-3 kXjiC is-flex is-align-items-center is-justify-content-space-between is-flex-wrap-wrap"
|
||||
className="RepositoryEntry__DetailsRow-sc-6jys82-3 kXjiC is-flex is-align-items-center is-justify-content-space-between is-flex-wrap-wrap ml-1"
|
||||
>
|
||||
<span
|
||||
className="is-size-7 has-text-secondary is-relative"
|
||||
@@ -71717,7 +71717,7 @@ exports[`Storyshots Repositories/RepositoryEntry HealthCheck Failure 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="is-flex is-flex-direction-column is-justify-content-center is-flex-grow-1 is-overflow-wrap-anywhere"
|
||||
className="sc-iBkjds idsAPT is-flex is-flex-direction-column is-justify-content-center is-flex-grow-1 is-overflow-hidden is-overflow-wrap-anywhere"
|
||||
style={
|
||||
Object {
|
||||
"gap": "0.25rem",
|
||||
@@ -71725,7 +71725,7 @@ exports[`Storyshots Repositories/RepositoryEntry HealthCheck Failure 1`] = `
|
||||
}
|
||||
>
|
||||
<div
|
||||
className="is-flex"
|
||||
className="is-flex ml-1"
|
||||
>
|
||||
<h4>
|
||||
<a
|
||||
@@ -71739,12 +71739,12 @@ exports[`Storyshots Repositories/RepositoryEntry HealthCheck Failure 1`] = `
|
||||
</h4>
|
||||
</div>
|
||||
<div
|
||||
className="RepositoryEntry__DescriptionRow-sc-6jys82-2 dzxasi is-size-7"
|
||||
className="RepositoryEntry__DescriptionRow-sc-6jys82-2 dzxasi is-size-7 ml-1"
|
||||
>
|
||||
The starship Heart of Gold was the first spacecraft to make use of the Infinite Improbability Drive
|
||||
</div>
|
||||
<div
|
||||
className="RepositoryEntry__DetailsRow-sc-6jys82-3 kXjiC is-flex is-align-items-center is-justify-content-space-between is-flex-wrap-wrap"
|
||||
className="RepositoryEntry__DetailsRow-sc-6jys82-3 kXjiC is-flex is-align-items-center is-justify-content-space-between is-flex-wrap-wrap ml-1"
|
||||
>
|
||||
<span
|
||||
className="is-size-7 has-text-secondary is-relative"
|
||||
@@ -71846,7 +71846,7 @@ exports[`Storyshots Repositories/RepositoryEntry MultiRepositoryTags 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="is-flex is-flex-direction-column is-justify-content-center is-flex-grow-1 is-overflow-wrap-anywhere"
|
||||
className="sc-iBkjds idsAPT is-flex is-flex-direction-column is-justify-content-center is-flex-grow-1 is-overflow-hidden is-overflow-wrap-anywhere"
|
||||
style={
|
||||
Object {
|
||||
"gap": "0.25rem",
|
||||
@@ -71854,7 +71854,7 @@ exports[`Storyshots Repositories/RepositoryEntry MultiRepositoryTags 1`] = `
|
||||
}
|
||||
>
|
||||
<div
|
||||
className="is-flex"
|
||||
className="is-flex ml-1"
|
||||
>
|
||||
<h4>
|
||||
<a
|
||||
@@ -71868,12 +71868,12 @@ exports[`Storyshots Repositories/RepositoryEntry MultiRepositoryTags 1`] = `
|
||||
</h4>
|
||||
</div>
|
||||
<div
|
||||
className="RepositoryEntry__DescriptionRow-sc-6jys82-2 dzxasi is-size-7"
|
||||
className="RepositoryEntry__DescriptionRow-sc-6jys82-2 dzxasi is-size-7 ml-1"
|
||||
>
|
||||
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.
|
||||
</div>
|
||||
<div
|
||||
className="RepositoryEntry__DetailsRow-sc-6jys82-3 kXjiC is-flex is-align-items-center is-justify-content-space-between is-flex-wrap-wrap"
|
||||
className="RepositoryEntry__DetailsRow-sc-6jys82-3 kXjiC is-flex is-align-items-center is-justify-content-space-between is-flex-wrap-wrap ml-1"
|
||||
>
|
||||
<span
|
||||
className="is-size-7 has-text-secondary is-relative"
|
||||
@@ -71986,7 +71986,7 @@ exports[`Storyshots Repositories/RepositoryEntry RepositoryFlag EP 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="is-flex is-flex-direction-column is-justify-content-center is-flex-grow-1 is-overflow-wrap-anywhere"
|
||||
className="sc-iBkjds idsAPT is-flex is-flex-direction-column is-justify-content-center is-flex-grow-1 is-overflow-hidden is-overflow-wrap-anywhere"
|
||||
style={
|
||||
Object {
|
||||
"gap": "0.25rem",
|
||||
@@ -71994,7 +71994,7 @@ exports[`Storyshots Repositories/RepositoryEntry RepositoryFlag EP 1`] = `
|
||||
}
|
||||
>
|
||||
<div
|
||||
className="is-flex"
|
||||
className="is-flex ml-1"
|
||||
>
|
||||
<h4>
|
||||
<a
|
||||
@@ -72008,12 +72008,12 @@ exports[`Storyshots Repositories/RepositoryEntry RepositoryFlag EP 1`] = `
|
||||
</h4>
|
||||
</div>
|
||||
<div
|
||||
className="RepositoryEntry__DescriptionRow-sc-6jys82-2 dzxasi is-size-7"
|
||||
className="RepositoryEntry__DescriptionRow-sc-6jys82-2 dzxasi is-size-7 ml-1"
|
||||
>
|
||||
The starship Heart of Gold was the first spacecraft to make use of the Infinite Improbability Drive
|
||||
</div>
|
||||
<div
|
||||
className="RepositoryEntry__DetailsRow-sc-6jys82-3 kXjiC is-flex is-align-items-center is-justify-content-space-between is-flex-wrap-wrap"
|
||||
className="RepositoryEntry__DetailsRow-sc-6jys82-3 kXjiC is-flex is-align-items-center is-justify-content-space-between is-flex-wrap-wrap ml-1"
|
||||
>
|
||||
<span
|
||||
className="is-size-7 has-text-secondary is-relative"
|
||||
@@ -72115,7 +72115,7 @@ exports[`Storyshots Repositories/RepositoryEntry With long texts 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="is-flex is-flex-direction-column is-justify-content-center is-flex-grow-1 is-overflow-wrap-anywhere"
|
||||
className="sc-iBkjds idsAPT is-flex is-flex-direction-column is-justify-content-center is-flex-grow-1 is-overflow-hidden is-overflow-wrap-anywhere"
|
||||
style={
|
||||
Object {
|
||||
"gap": "0.25rem",
|
||||
@@ -72123,7 +72123,7 @@ exports[`Storyshots Repositories/RepositoryEntry With long texts 1`] = `
|
||||
}
|
||||
>
|
||||
<div
|
||||
className="is-flex"
|
||||
className="is-flex ml-1"
|
||||
>
|
||||
<h4>
|
||||
<a
|
||||
@@ -72137,12 +72137,12 @@ exports[`Storyshots Repositories/RepositoryEntry With long texts 1`] = `
|
||||
</h4>
|
||||
</div>
|
||||
<div
|
||||
className="RepositoryEntry__DescriptionRow-sc-6jys82-2 dzxasi is-size-7"
|
||||
className="RepositoryEntry__DescriptionRow-sc-6jys82-2 dzxasi is-size-7 ml-1"
|
||||
>
|
||||
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.
|
||||
</div>
|
||||
<div
|
||||
className="RepositoryEntry__DetailsRow-sc-6jys82-3 kXjiC is-flex is-align-items-center is-justify-content-space-between is-flex-wrap-wrap"
|
||||
className="RepositoryEntry__DetailsRow-sc-6jys82-3 kXjiC is-flex is-align-items-center is-justify-content-space-between is-flex-wrap-wrap ml-1"
|
||||
>
|
||||
<span
|
||||
className="is-size-7 has-text-secondary is-relative"
|
||||
|
||||
@@ -21,9 +21,10 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
import { extensionPoints, ExtractProps } from "@scm-manager/ui-extensions";
|
||||
import { extensionPoints } from "@scm-manager/ui-extensions";
|
||||
import { ComponentProps } from "react";
|
||||
|
||||
export type ProtocolLinkRendererProps<Protocol extends string | undefined = undefined> = ExtractProps<
|
||||
export type ProtocolLinkRendererProps<Protocol extends string | undefined = undefined> = ComponentProps<
|
||||
extensionPoints.MarkdownLinkProtocolRenderer<Protocol>["type"]["renderer"]
|
||||
>;
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
import React, { ComponentType, FC, ReactNode } from "react";
|
||||
import React, { ComponentProps, ComponentType, FC, ReactNode } from "react";
|
||||
import {
|
||||
Branch,
|
||||
BranchDetails,
|
||||
@@ -49,8 +49,6 @@ import {
|
||||
} from "@scm-manager/ui-types";
|
||||
import { ExtensionPointDefinition } from "./binder";
|
||||
import { RenderableExtensionPointDefinition, SimpleRenderableDynamicExtensionPointDefinition } from "./ExtensionPoint";
|
||||
import ExtractProps from "./extractProps";
|
||||
import { useGeneratedId } from "@scm-manager/ui-components";
|
||||
|
||||
type RepositoryCreatorSubFormProps = {
|
||||
repository: RepositoryCreation;
|
||||
@@ -59,7 +57,7 @@ type RepositoryCreatorSubFormProps = {
|
||||
disabled?: boolean;
|
||||
};
|
||||
|
||||
export type RepositoryCreatorComponentProps = ExtractProps<RepositoryCreator["type"]["component"]>;
|
||||
export type RepositoryCreatorComponentProps = ComponentProps<RepositoryCreator["type"]["component"]>;
|
||||
|
||||
/**
|
||||
* @deprecated use {@link RepositoryCreator}`["type"]` instead
|
||||
|
||||
@@ -21,8 +21,11 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
import React from "react";
|
||||
import { ComponentProps, JSXElementConstructor } from "react";
|
||||
|
||||
type ExtractProps<T> = T extends React.ComponentType<infer U> ? U : never;
|
||||
/**
|
||||
* @deprecated Use {@link ComponentProps} directly instead
|
||||
*/
|
||||
type ExtractProps<T extends keyof JSX.IntrinsicElements | JSXElementConstructor<any>> = ComponentProps<T>;
|
||||
|
||||
export default ExtractProps;
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
"classnames": "2",
|
||||
"react": "17",
|
||||
"react-dom": "17",
|
||||
"react-router-dom": "5",
|
||||
"styled-components": "5",
|
||||
"@scm-manager/ui-components": "2.46.2-SNAPSHOT"
|
||||
},
|
||||
|
||||
@@ -23,16 +23,15 @@
|
||||
*/
|
||||
|
||||
import StoryRouter from "storybook-react-router";
|
||||
import { ComponentMeta, StoryFn } from "@storybook/react";
|
||||
import React, { ComponentProps } from "react";
|
||||
import { ExtractProps } from "@scm-manager/ui-extensions";
|
||||
import { ComponentMeta, ComponentStory } from "@storybook/react";
|
||||
import React from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
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 "../card/CardRow";
|
||||
import { CardDetail, CardDetailLabel, CardDetails, CardDetailTag } from "../card/CardDetail";
|
||||
import CardRow, { SecondaryRow } from "../card/CardRow";
|
||||
import { CardDetail, CardDetailLabel, CardDetails, CardDetailTag, CardLinkDetail } from "../card/CardDetail";
|
||||
|
||||
export default {
|
||||
title: "CardList",
|
||||
@@ -40,15 +39,8 @@ export default {
|
||||
decorators: [StoryRouter()],
|
||||
} as ComponentMeta<typeof CardList>;
|
||||
|
||||
const Template: StoryFn<ExtractProps<typeof CardListBox>> = (args) => <CardListBox {...args} />;
|
||||
|
||||
export const Default = Template.bind({});
|
||||
// More on args: https://storybook.js.org/docs/react/writing-stories/args
|
||||
Default.args = {
|
||||
children: [
|
||||
<CardListCard>
|
||||
<CardTitle>My favorite repository</CardTitle>
|
||||
</CardListCard>,
|
||||
export const Default: ComponentStory<typeof CardListBox> = () => (
|
||||
<CardListBox>
|
||||
<CardListCard
|
||||
action={
|
||||
<Menu>
|
||||
@@ -59,13 +51,20 @@ Default.args = {
|
||||
</Menu>
|
||||
}
|
||||
>
|
||||
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.
|
||||
</CardListCard>,
|
||||
<CardRow>
|
||||
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.
|
||||
</CardRow>
|
||||
</CardListCard>
|
||||
<CardListCard>
|
||||
<CardRow>
|
||||
<CardTitle>My favorite repository</CardTitle>
|
||||
</CardRow>
|
||||
</CardListCard>
|
||||
<CardListCard
|
||||
action={
|
||||
<Menu>
|
||||
@@ -76,19 +75,23 @@ Default.args = {
|
||||
</Menu>
|
||||
}
|
||||
>
|
||||
<CardTitle level={5}>
|
||||
<Link aria-label="Edit My least liked repo" to="/cards/1">
|
||||
My favorite repository with a very long title and some other things
|
||||
</Link>
|
||||
</CardTitle>
|
||||
</CardListCard>,
|
||||
<CardRow>
|
||||
<CardTitle level={5}>
|
||||
<Link aria-label="Edit My least liked repo" to="/cards/1">
|
||||
My favorite repository with a very long title and some other things
|
||||
</Link>
|
||||
</CardTitle>
|
||||
</CardRow>
|
||||
</CardListCard>
|
||||
<CardListCard>
|
||||
<CardTitle>
|
||||
<Link aria-label="Edit My least liked repo" to="/cards/1">
|
||||
My least liked repo
|
||||
</Link>
|
||||
</CardTitle>
|
||||
</CardListCard>,
|
||||
<CardRow>
|
||||
<CardTitle>
|
||||
<Link aria-label="Edit My least liked repo" to="/cards/1">
|
||||
My least liked repo
|
||||
</Link>
|
||||
</CardTitle>
|
||||
</CardRow>
|
||||
</CardListCard>
|
||||
<CardListCard
|
||||
action={
|
||||
<Menu>
|
||||
@@ -114,7 +117,7 @@ Default.args = {
|
||||
<CardRow className="is-size-6 is-flex is-justify-content-space-between">
|
||||
<span>This is a third row, lets see how this works out.</span>(MERGED)
|
||||
</CardRow>
|
||||
</CardListCard>,
|
||||
</CardListCard>
|
||||
<CardListCard>
|
||||
<CardRow className="is-flex is-align-items-center">
|
||||
<CardTitle>
|
||||
@@ -140,31 +143,59 @@ Default.args = {
|
||||
</div>
|
||||
<span>(OPEN)</span>
|
||||
</CardRow>
|
||||
</CardListCard>,
|
||||
</CardListCard>
|
||||
<CardListCard>
|
||||
<CardTitle>
|
||||
<Link aria-label="Edit My least liked repo" to="/cards/1">
|
||||
My least liked repo
|
||||
</Link>
|
||||
</CardTitle>
|
||||
<CardRow>
|
||||
<CardTitle>
|
||||
<Link aria-label="Edit My least liked repo" to="/cards/1">
|
||||
My least liked repo
|
||||
</Link>
|
||||
</CardTitle>
|
||||
</CardRow>
|
||||
<CardRow>
|
||||
<CardDetails>
|
||||
<CardDetail>
|
||||
{({ labelId }) => (
|
||||
<>
|
||||
<CardDetailLabel id={labelId}>Workers</CardDetailLabel>
|
||||
<CardDetailTag aria-labelledby={labelId}>2/3</CardDetailTag>
|
||||
</>
|
||||
)}
|
||||
</CardDetail>
|
||||
<CardDetail>
|
||||
<CardDetailLabel>MyCustomDetail</CardDetailLabel>
|
||||
<a className="is-relative" href="https://scm-manager.org">
|
||||
Docs
|
||||
</a>
|
||||
<CardDetailLabel>Workers</CardDetailLabel>
|
||||
<CardDetailTag>2/3</CardDetailTag>
|
||||
</CardDetail>
|
||||
<CardLinkDetail to="/my/detail">
|
||||
<CardDetailLabel>Go to docs</CardDetailLabel>
|
||||
</CardLinkDetail>
|
||||
</CardDetails>
|
||||
</CardRow>
|
||||
</CardListCard>,
|
||||
],
|
||||
} as ComponentProps<typeof CardListBox>;
|
||||
</CardListCard>
|
||||
<CardListCard avatar={<Icon>user</Icon>} action={<Icon>ellipsis-v</Icon>}>
|
||||
<CardRow>
|
||||
<CardTitle>
|
||||
3c991eec687444630c0929e4e23d8a1a2565011d4bea28d4338dd1d024bb74c8
|
||||
c076ca5eea66545ee227c8854acc8b9bf075676a6848d54fa0bc1fa291f78887
|
||||
72d7e2ef64c9575dd8ceeed8ed6b24f185646deb6595b13fd51c5705c61a2c46
|
||||
9127daa67e066bc49f39cca9670b92de3d576ac1fb9c916e9b44692923e12a9d
|
||||
14d07434e8c5b3d0ba2e752bc580888a30963d4e8021be573392bb625f6150da
|
||||
60fc6f2e7503b1ca5963afb627ef560f4e2191c0da4c9328ae4ab088e177fb41
|
||||
749e63a6af1731d5c599e960a2f6c8cb9a15d6cf6a82493f419d417829f7b2a8
|
||||
0ca9334aeda2e5dab101e4af13c9610839afc3b9dd2ec56ffb067d6914ce9b67
|
||||
b708983948a1750f79fbb91875399fcce453410dad6191c5dc5059f4b28aee1d
|
||||
0d13a4349270947bc79cfc59c7c2aa59960d847a49b40feccd3388fa9a600a68
|
||||
</CardTitle>
|
||||
</CardRow>
|
||||
<SecondaryRow className="is-ellipsis-overflow">
|
||||
7cab5486ab8cd946af71a77d37c84bac c05156ef54a1f0bfd5d4fa12f774148c 4f2964e1895470b6313e3264fef276d8
|
||||
8c57fdf7fde5fc227ea0c59a0f359122 3bc64067ff6fb9c64f4ae5ac15e4375d 91943ad0c020859ad6cc3723fe9bd325
|
||||
07bb6d93d9faf2df68d02949ec10e58e 0bee2b579b7ab5777683f3d5b5975960 4a3009269d971f555524374e7da745ad
|
||||
a693ffb57da89f191249de6480c2387b
|
||||
</SecondaryRow>
|
||||
<CardRow>
|
||||
<CardDetails>
|
||||
<CardDetail>
|
||||
<CardDetailLabel>Workers</CardDetailLabel>
|
||||
<CardDetailTag>2/3</CardDetailTag>
|
||||
</CardDetail>
|
||||
<CardLinkDetail to="/to/docs">
|
||||
<CardDetailLabel>Go to docs</CardDetailLabel>
|
||||
</CardLinkDetail>
|
||||
</CardDetails>
|
||||
</CardRow>
|
||||
</CardListCard>
|
||||
</CardListBox>
|
||||
);
|
||||
|
||||
@@ -23,14 +23,23 @@
|
||||
*/
|
||||
|
||||
import StoryRouter from "storybook-react-router";
|
||||
import { ComponentMeta, StoryFn } from "@storybook/react";
|
||||
import React, { ComponentProps } from "react";
|
||||
import { ExtractProps } from "@scm-manager/ui-extensions";
|
||||
import { ComponentMeta, ComponentStory } from "@storybook/react";
|
||||
import React from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
import CardTitle from "../card/CardTitle";
|
||||
import CardRow from "../card/CardRow";
|
||||
import { CardDetail, CardDetailLabel, CardDetails, CardDetailTag } from "./CardDetail";
|
||||
import CardRow, { SecondaryRow, TertiaryRow } from "../card/CardRow";
|
||||
import {
|
||||
CardButtonDetail,
|
||||
CardDetail,
|
||||
CardDetailIcon,
|
||||
CardDetailLabel,
|
||||
CardDetails,
|
||||
CardDetailTag,
|
||||
CardLinkDetail,
|
||||
} from "./CardDetail";
|
||||
import Card from "./Card";
|
||||
import { Popover } from "@scm-manager/ui-overlays";
|
||||
import { Icon } from "@scm-manager/ui-buttons";
|
||||
|
||||
export default {
|
||||
title: "Card",
|
||||
@@ -38,35 +47,67 @@ export default {
|
||||
decorators: [StoryRouter()],
|
||||
} as ComponentMeta<typeof Card>;
|
||||
|
||||
const Template: StoryFn<ExtractProps<typeof Card>> = (args) => <Card {...args} />;
|
||||
|
||||
export const Default = Template.bind({});
|
||||
// More on args: https://storybook.js.org/docs/react/writing-stories/args
|
||||
Default.args = {
|
||||
className: "box",
|
||||
children: [
|
||||
<CardTitle>
|
||||
<Link aria-label="Edit My least liked repo" to="/cards/1">
|
||||
My least liked repo
|
||||
</Link>
|
||||
</CardTitle>,
|
||||
export const Default: ComponentStory<typeof Card> = () => (
|
||||
<Card
|
||||
className="box"
|
||||
avatar={<Icon className="is-large">user</Icon>}
|
||||
action={<Icon className="is-medium">ellipsis-v</Icon>}
|
||||
>
|
||||
<CardRow>
|
||||
<CardTitle>
|
||||
<Link aria-label="Edit My least liked repo" to="/cards/1">
|
||||
3c991eec687444630c0929e4e23d8a1a2565011d4bea28d4338dd1d024bb74c8
|
||||
c076ca5eea66545ee227c8854acc8b9bf075676a6848d54fa0bc1fa291f78887
|
||||
72d7e2ef64c9575dd8ceeed8ed6b24f185646deb6595b13fd51c5705c61a2c46
|
||||
9127daa67e066bc49f39cca9670b92de3d576ac1fb9c916e9b44692923e12a9d
|
||||
14d07434e8c5b3d0ba2e752bc580888a30963d4e8021be573392bb625f6150da
|
||||
60fc6f2e7503b1ca5963afb627ef560f4e2191c0da4c9328ae4ab088e177fb41
|
||||
749e63a6af1731d5c599e960a2f6c8cb9a15d6cf6a82493f419d417829f7b2a8
|
||||
0ca9334aeda2e5dab101e4af13c9610839afc3b9dd2ec56ffb067d6914ce9b67
|
||||
b708983948a1750f79fbb91875399fcce453410dad6191c5dc5059f4b28aee1d
|
||||
0d13a4349270947bc79cfc59c7c2aa59960d847a49b40feccd3388fa9a600a68
|
||||
</Link>
|
||||
</CardTitle>
|
||||
</CardRow>
|
||||
<SecondaryRow className="is-ellipsis-overflow">
|
||||
7cab5486ab8cd946af71a77d37c84bac c05156ef54a1f0bfd5d4fa12f774148c 4f2964e1895470b6313e3264fef276d8
|
||||
8c57fdf7fde5fc227ea0c59a0f359122 3bc64067ff6fb9c64f4ae5ac15e4375d 91943ad0c020859ad6cc3723fe9bd325
|
||||
07bb6d93d9faf2df68d02949ec10e58e 0bee2b579b7ab5777683f3d5b5975960 4a3009269d971f555524374e7da745ad
|
||||
a693ffb57da89f191249de6480c2387b
|
||||
</SecondaryRow>
|
||||
<TertiaryRow>This is information is not important</TertiaryRow>
|
||||
<CardRow>
|
||||
<CardDetails>
|
||||
<Popover
|
||||
trigger={
|
||||
<CardButtonDetail>
|
||||
<CardDetailLabel>Popover Detail with Tag</CardDetailLabel>
|
||||
<CardDetailTag>3</CardDetailTag>
|
||||
</CardButtonDetail>
|
||||
}
|
||||
title="My Popover Details"
|
||||
>
|
||||
<>This is some additional detail for my Popover.</>
|
||||
</Popover>
|
||||
<CardDetail>
|
||||
{({ labelId }) => (
|
||||
<>
|
||||
<CardDetailLabel id={labelId}>Workers</CardDetailLabel>
|
||||
<CardDetailTag aria-labelledby={labelId}>2/3</CardDetailTag>
|
||||
</>
|
||||
)}
|
||||
</CardDetail>
|
||||
<CardDetail>
|
||||
<CardDetailLabel>MyCustomDetail</CardDetailLabel>
|
||||
<a className="is-relative" href="https://scm-manager.org">
|
||||
Docs
|
||||
</a>
|
||||
<CardDetailLabel>Normal Detail with Tag</CardDetailLabel>
|
||||
<CardDetailTag>2/3</CardDetailTag>
|
||||
</CardDetail>
|
||||
<CardLinkDetail to="/workers">
|
||||
<CardDetailLabel>Link Detail</CardDetailLabel>
|
||||
</CardLinkDetail>
|
||||
<Popover
|
||||
trigger={
|
||||
<CardButtonDetail>
|
||||
<CardDetailLabel>Popover Detail with Icon</CardDetailLabel>
|
||||
<CardDetailIcon className="has-text-success">check-circle</CardDetailIcon>
|
||||
</CardButtonDetail>
|
||||
}
|
||||
title="My Popover Details"
|
||||
>
|
||||
<>This is some additional detail for my Popover.</>
|
||||
</Popover>
|
||||
</CardDetails>
|
||||
</CardRow>,
|
||||
],
|
||||
} as ComponentProps<typeof Card>;
|
||||
</CardRow>
|
||||
</Card>
|
||||
);
|
||||
|
||||
@@ -25,6 +25,11 @@
|
||||
import React, { ComponentType, HTMLAttributes, ReactHTML, Ref } from "react";
|
||||
import classNames from "classnames";
|
||||
import CSS from "csstype";
|
||||
import styled from "styled-components";
|
||||
|
||||
const RowsContainer = styled.div`
|
||||
margin-left: -0.25rem;
|
||||
`;
|
||||
|
||||
type Props = HTMLAttributes<HTMLElement> & {
|
||||
action?: React.ReactElement;
|
||||
@@ -49,7 +54,7 @@ type Props = HTMLAttributes<HTMLElement> & {
|
||||
* @since 2.44.0
|
||||
*/
|
||||
const Card = React.forwardRef<HTMLElement, Props>(
|
||||
({ className, avatar, rowGap = "0.5rem", children, as: Comp = "div", action, ...props }, ref) =>
|
||||
({ className, avatar, rowGap = "0.25rem", children, as: Comp = "div", action, ...props }, ref) =>
|
||||
React.createElement(
|
||||
Comp,
|
||||
{
|
||||
@@ -58,12 +63,12 @@ const Card = React.forwardRef<HTMLElement, Props>(
|
||||
...props,
|
||||
},
|
||||
avatar ? avatar : null,
|
||||
<div
|
||||
className="is-flex is-flex-direction-column is-justify-content-center is-flex-grow-1 is-overflow-wrap-anywhere"
|
||||
<RowsContainer
|
||||
className="is-flex is-flex-direction-column is-justify-content-center is-flex-grow-1 is-overflow-hidden is-overflow-wrap-anywhere"
|
||||
style={{ gap: rowGap }}
|
||||
>
|
||||
{children}
|
||||
</div>,
|
||||
</RowsContainer>,
|
||||
action ? action : null
|
||||
)
|
||||
);
|
||||
|
||||
@@ -22,10 +22,18 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
import React, { HTMLAttributes, ReactNode } from "react";
|
||||
import React, {
|
||||
ButtonHTMLAttributes,
|
||||
ComponentProps,
|
||||
ComponentPropsWithoutRef,
|
||||
HTMLAttributes,
|
||||
ReactNode,
|
||||
} from "react";
|
||||
import classNames from "classnames";
|
||||
import { useGeneratedId } from "@scm-manager/ui-components";
|
||||
import styled from "styled-components";
|
||||
import { Link } from "react-router-dom";
|
||||
import { Icon } from "@scm-manager/ui-buttons";
|
||||
|
||||
export const CardVariants = {
|
||||
LIGHT: "light",
|
||||
@@ -56,13 +64,73 @@ export const CardDetail = React.forwardRef<HTMLSpanElement, CardDetailProps>(
|
||||
({ children, className, ...props }, ref) => {
|
||||
const labelId = useGeneratedId();
|
||||
return (
|
||||
<span {...props} className={classNames("is-flex is-align-items-center has-gap-1", className)} ref={ref}>
|
||||
<span {...props} className={classNames("is-flex is-align-items-center has-gap-1 p-1", className)} ref={ref}>
|
||||
{typeof children === "function" ? children({ labelId }) : children}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
const InteractiveDetailStyles = `
|
||||
&:focus {
|
||||
outline-offset: -0.125rem;
|
||||
outline-width: 0.125rem;
|
||||
}
|
||||
`;
|
||||
|
||||
const StyledCardButtonDetail = styled.button`
|
||||
${InteractiveDetailStyles}
|
||||
|
||||
&[aria-expanded="true"] {
|
||||
outline: var(--scm-border-color) solid 0.125rem;
|
||||
outline-offset: -0.125rem;
|
||||
}
|
||||
`;
|
||||
|
||||
/**
|
||||
* @beta
|
||||
* @since 2.47.0
|
||||
*/
|
||||
export const CardButtonDetail = React.forwardRef<HTMLButtonElement, ButtonHTMLAttributes<HTMLButtonElement>>(
|
||||
({ children, className, ...props }, ref) => (
|
||||
<StyledCardButtonDetail
|
||||
{...props}
|
||||
className={classNames(
|
||||
"is-flex is-align-items-center has-gap-1 p-1 is-borderless has-background-transparent is-relative has-hover-background-blue has-rounded-border is-clickable",
|
||||
className
|
||||
)}
|
||||
ref={ref}
|
||||
>
|
||||
{children}
|
||||
</StyledCardButtonDetail>
|
||||
)
|
||||
);
|
||||
|
||||
const StyledCardLinkDetail = styled(Link)`
|
||||
${InteractiveDetailStyles}
|
||||
|
||||
min-height: 2rem;
|
||||
`;
|
||||
|
||||
/**
|
||||
* @beta
|
||||
* @since 2.47.0
|
||||
*/
|
||||
export const CardLinkDetail = React.forwardRef<HTMLAnchorElement, ComponentPropsWithoutRef<typeof Link>>(
|
||||
({ children, className, ...props }, ref) => (
|
||||
<StyledCardLinkDetail
|
||||
{...props}
|
||||
className={classNames(
|
||||
"is-flex is-align-items-center has-gap-1 p-1 is-borderless has-background-transparent is-relative has-hover-background-blue has-rounded-border is-clickable",
|
||||
className
|
||||
)}
|
||||
ref={ref}
|
||||
>
|
||||
{children}
|
||||
</StyledCardLinkDetail>
|
||||
)
|
||||
);
|
||||
|
||||
/**
|
||||
* @beta
|
||||
* @since 2.46.0
|
||||
@@ -91,8 +159,24 @@ export const CardDetailTag = React.forwardRef<HTMLSpanElement, HTMLAttributes<HT
|
||||
)
|
||||
);
|
||||
|
||||
/**
|
||||
* @beta
|
||||
* @since 2.47.0
|
||||
*/
|
||||
export const CardDetailIcon = React.forwardRef<HTMLElement, ComponentProps<typeof Icon>>(
|
||||
({ children, className, ...props }, ref) => (
|
||||
<Icon {...props} className={classNames("is-size-5", className)} ref={ref}>
|
||||
{children}
|
||||
</Icon>
|
||||
)
|
||||
);
|
||||
|
||||
const CardDetailsRowContainer = styled.div`
|
||||
gap: 0.5rem 1rem;
|
||||
gap: 0.125rem 1rem;
|
||||
|
||||
&:first-child {
|
||||
margin-left: -0.25rem;
|
||||
}
|
||||
`;
|
||||
|
||||
/**
|
||||
|
||||
@@ -22,14 +22,16 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
import React, { ComponentProps } from "react";
|
||||
import React, { ComponentProps, HTMLAttributes } from "react";
|
||||
import classNames from "classnames";
|
||||
|
||||
/**
|
||||
* @beta
|
||||
* @since 2.44.0
|
||||
*/
|
||||
const CardRow = "div" as const;
|
||||
const CardRow = React.forwardRef<HTMLDivElement, HTMLAttributes<HTMLDivElement>>(({ className, ...props }, ref) => (
|
||||
<div className={classNames(className, "ml-1")} {...props} ref={ref} />
|
||||
));
|
||||
|
||||
export default CardRow;
|
||||
|
||||
|
||||
@@ -25,11 +25,6 @@
|
||||
import StoryRouter from "storybook-react-router";
|
||||
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 { Menu } from "@scm-manager/ui-overlays";
|
||||
import { Icon } from "@scm-manager/ui-buttons";
|
||||
import CardRow from "../card/CardRow";
|
||||
import Collapsible from "./Collapsible";
|
||||
|
||||
export default {
|
||||
@@ -38,7 +33,7 @@ export default {
|
||||
decorators: [StoryRouter()],
|
||||
} as ComponentMeta<typeof Collapsible>;
|
||||
|
||||
const Template: StoryFn<ExtractProps<typeof Collapsible>> = (args) => <Collapsible {...args} />;
|
||||
const Template: StoryFn<ComponentProps<typeof Collapsible>> = (args) => <Collapsible {...args} />;
|
||||
|
||||
export const Default = Template.bind({});
|
||||
// More on args: https://storybook.js.org/docs/react/writing-stories/args
|
||||
|
||||
@@ -25,7 +25,14 @@
|
||||
import CardListComponent, { CardListBox as CardListBoxComponent, CardListCard } from "./card-list/CardList";
|
||||
import CardTitle from "./card/CardTitle";
|
||||
import CardRow, { SecondaryRow, TertiaryRow } from "./card/CardRow";
|
||||
import { CardDetail, CardDetailLabel, CardDetails, CardDetailTag } from "./card/CardDetail";
|
||||
import {
|
||||
CardButtonDetail,
|
||||
CardDetail,
|
||||
CardDetailLabel,
|
||||
CardDetails,
|
||||
CardDetailTag,
|
||||
CardLinkDetail,
|
||||
} from "./card/CardDetail";
|
||||
import CardComponent from "./card/Card";
|
||||
import {
|
||||
DataPageHeader as DataPageHeaderComponent,
|
||||
@@ -38,16 +45,20 @@ import {
|
||||
|
||||
export { default as Collapsible } from "./collapsible/Collapsible";
|
||||
|
||||
const CardDetailExports = {
|
||||
Label: CardDetailLabel,
|
||||
Tag: CardDetailTag,
|
||||
};
|
||||
|
||||
const CardExport = {
|
||||
Title: CardTitle,
|
||||
Row: CardRow,
|
||||
SecondaryRow: SecondaryRow,
|
||||
TertiaryRow: TertiaryRow,
|
||||
Details: Object.assign(CardDetails, {
|
||||
Detail: Object.assign(CardDetail, {
|
||||
Label: CardDetailLabel,
|
||||
Tag: CardDetailTag,
|
||||
}),
|
||||
Detail: Object.assign(CardDetail, CardDetailExports),
|
||||
ButtonDetail: Object.assign(CardButtonDetail, CardDetailExports),
|
||||
LinkDetail: Object.assign(CardLinkDetail, CardDetailExports),
|
||||
}),
|
||||
};
|
||||
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
import StoryRouter from "storybook-react-router";
|
||||
import { ComponentMeta, StoryFn } from "@storybook/react";
|
||||
import React, { ComponentProps } from "react";
|
||||
import { ExtractProps } from "@scm-manager/ui-extensions";
|
||||
import { Button } from "@scm-manager/ui-buttons";
|
||||
import Dialog from "./Dialog";
|
||||
|
||||
@@ -36,7 +35,7 @@ export default {
|
||||
render: (story) => <div style={{ height: "100vh" }}>{story}</div>,
|
||||
} as ComponentMeta<typeof Dialog>;
|
||||
|
||||
const Template: StoryFn<ExtractProps<typeof Dialog>> = (args) => <Dialog {...args} />;
|
||||
const Template: StoryFn<ComponentProps<typeof Dialog>> = (args) => <Dialog {...args} />;
|
||||
|
||||
export const Default = Template.bind({});
|
||||
// More on args: https://storybook.js.org/docs/react/writing-stories/args
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
import StoryRouter from "storybook-react-router";
|
||||
import { ComponentMeta, StoryFn } from "@storybook/react";
|
||||
import React, { ComponentProps } from "react";
|
||||
import { ExtractProps } from "@scm-manager/ui-extensions";
|
||||
import Menu, { MenuButton, MenuDialog, MenuExternalLink, MenuLink } from "./Menu";
|
||||
import { Button, Icon } from "@scm-manager/ui-buttons";
|
||||
import { CloseButton } from "../dialog/Dialog";
|
||||
@@ -36,7 +35,7 @@ export default {
|
||||
decorators: [StoryRouter()],
|
||||
} as ComponentMeta<typeof Menu>;
|
||||
|
||||
const Template: StoryFn<ExtractProps<typeof Menu>> = (args) => <Menu {...args} />;
|
||||
const Template: StoryFn<ComponentProps<typeof Menu>> = (args) => <Menu {...args} />;
|
||||
|
||||
export const Default = Template.bind({});
|
||||
// More on args: https://storybook.js.org/docs/react/writing-stories/args
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
import React, {
|
||||
ComponentProps,
|
||||
Dispatch,
|
||||
FC,
|
||||
KeyboardEvent as ReactKeyboardEvent,
|
||||
@@ -66,10 +67,9 @@ const namespaceAndName = (hit: Hit) => {
|
||||
const name = (hit.fields["name"] as ValueHitField).value as string;
|
||||
return `${namespace}/${name}`;
|
||||
};
|
||||
type ExtractProps<T> = T extends React.ComponentType<infer U> ? U : never;
|
||||
|
||||
type HitsProps = {
|
||||
entries: ReactElement<ExtractProps<typeof HitEntry>>[];
|
||||
entries: ReactElement<ComponentProps<typeof HitEntry>>[];
|
||||
hits: Hit[];
|
||||
showHelp: () => void;
|
||||
ariaId: string;
|
||||
|
||||
@@ -33,7 +33,6 @@ import { SmallLoadingSpinner } from "@scm-manager/ui-components";
|
||||
type Props = {
|
||||
branch: Branch;
|
||||
details?: BranchDetails;
|
||||
labelId?: string;
|
||||
};
|
||||
|
||||
const Count = styled.span`
|
||||
@@ -41,7 +40,7 @@ const Count = styled.span`
|
||||
width: max-content;
|
||||
`;
|
||||
|
||||
const AheadBehindTag: FC<Props> = ({ branch, details, labelId }) => {
|
||||
const AheadBehindTag: FC<Props> = ({ branch, details }) => {
|
||||
const [t] = useTranslation("repos");
|
||||
|
||||
if (branch.defaultBranch) {
|
||||
@@ -56,7 +55,7 @@ const AheadBehindTag: FC<Props> = ({ branch, details, labelId }) => {
|
||||
<Tooltip
|
||||
message={t("branch.aheadBehind.tooltip", { ahead: details.changesetsAhead, behind: details.changesetsBehind })}
|
||||
>
|
||||
<span aria-labelledby={labelId} className="is-inline-flex is-align-items-center">
|
||||
<span className="is-inline-flex is-align-items-center">
|
||||
<Icon className={details.changesetsAhead > 0 ? "has-text-success" : "has-text-grey-light"}>arrow-up</Icon>
|
||||
<Count aria-label={t("branch.aheadBehind.ahead")} className="is-size-7 pl-0">
|
||||
{details.changesetsAhead}
|
||||
|
||||
@@ -122,12 +122,8 @@ const BranchListItem: FC<Props> = ({ branch, remove, isLoading, branchesDetails,
|
||||
<Card.Details>
|
||||
{!branch.defaultBranch ? (
|
||||
<Card.Details.Detail>
|
||||
{({ labelId }) => (
|
||||
<>
|
||||
<Card.Details.Detail.Label id={labelId}>{t("branch.aheadBehind.label")}</Card.Details.Detail.Label>
|
||||
<AheadBehindTag branch={branch} details={branchDetails} labelId={labelId} />
|
||||
</>
|
||||
)}
|
||||
<Card.Details.Detail.Label>{t("branch.aheadBehind.label")}</Card.Details.Detail.Label>
|
||||
<AheadBehindTag branch={branch} details={branchDetails} />
|
||||
</Card.Details.Detail>
|
||||
) : null}
|
||||
<ExtensionPoint<extensionPoints.BranchListDetail>
|
||||
|
||||
Reference in New Issue
Block a user