@scm-manager/ui-components 4.0.0-REACT18-20250701-125025 → 4.0.0-REACT19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +46 -51
- package/src/BranchSelector.stories.tsx +60 -11
- package/src/Breadcrumb.stories.tsx +131 -57
- package/src/Breadcrumb.tsx +3 -3
- package/src/CardColumn.stories.tsx +94 -27
- package/src/CardColumnSmall.stories.tsx +102 -27
- package/src/CommaSeparatedList.tsx +2 -2
- package/src/Date.stories.tsx +64 -17
- package/src/Duration.stories.tsx +92 -45
- package/src/ErrorBoundary.tsx +38 -58
- package/src/ErrorNotification.tsx +1 -1
- package/src/Help.stories.tsx +61 -17
- package/src/Help.tsx +5 -11
- package/src/Icon.stories.tsx +93 -13
- package/src/LinkPaginator.tsx +9 -6
- package/src/Loading.stories.tsx +26 -6
- package/src/Logo.stories.tsx +44 -13
- package/src/Notification.stories.tsx +111 -23
- package/src/OverviewPageActions.tsx +5 -5
- package/src/Paginator.test.tsx +115 -94
- package/src/PdfViewer.stories.tsx +83 -5
- package/src/PreformattedCodeBlock.stories.tsx +97 -26
- package/src/ProtectedRoute.tsx +14 -39
- package/src/SmallLoadingSpinner.stories.tsx +26 -6
- package/src/SyntaxHighlighter.stories.tsx +122 -40
- package/src/SyntaxHighlighterRenderer.tsx +7 -7
- package/src/Tag.stories.tsx +135 -18
- package/src/Tag.tsx +2 -1
- package/src/Tooltip.stories.tsx +147 -34
- package/src/__snapshots__/storyshots.test.ts.snap +6 -112
- package/src/avatar/Avatar.ts +1 -1
- package/src/avatar/AvatarImage.tsx +1 -1
- package/src/avatar/AvatarWrapper.tsx +2 -2
- package/src/buttons/Button.stories.tsx +159 -0
- package/src/buttons/Button.tsx +5 -5
- package/src/config/ConfigurationBinder.tsx +39 -39
- package/src/config/ConfigurationForm.tsx +2 -1
- package/src/config/TitledSettings.tsx +4 -1
- package/src/forms/AddKeyValueEntryToTableField.stories.tsx +60 -25
- package/src/forms/Checkbox.stories.tsx +165 -27
- package/src/forms/Checkbox.tsx +1 -0
- package/src/forms/DropDown.stories.tsx +81 -35
- package/src/forms/FileInput.stories.tsx +85 -10
- package/src/forms/InputField.stories.tsx +210 -37
- package/src/forms/InputField.tsx +1 -0
- package/src/forms/Radio.stories.tsx +181 -34
- package/src/forms/Radio.tsx +1 -0
- package/src/forms/Select.stories.tsx +266 -46
- package/src/forms/Select.tsx +1 -0
- package/src/forms/Textarea.stories.tsx +99 -53
- package/src/forms/Textarea.tsx +1 -0
- package/src/forms/index.ts +3 -1
- package/src/index.ts +5 -5
- package/src/jest-dom.d.ts +17 -0
- package/src/layout/Footer.stories.tsx +114 -22
- package/src/layout/FooterSection.tsx +1 -0
- package/src/layout/Header.tsx +2 -1
- package/src/layout/Page.tsx +1 -3
- package/src/layout/PrimaryContentColumn.tsx +2 -2
- package/src/layout/SecondaryNavigationColumn.tsx +3 -3
- package/src/layout/SubSubtitle.tsx +2 -1
- package/src/layout/Subtitle.tsx +2 -1
- package/src/layout/Title.tsx +2 -5
- package/src/markdown/LazyMarkdownView.tsx +16 -5
- package/src/markdown/MarkdownHeadingRenderer.test.ts +9 -1
- package/src/markdown/MarkdownHeadingRenderer.tsx +3 -3
- package/src/markdown/MarkdownImageRenderer.test.ts +8 -1
- package/src/markdown/MarkdownImageRenderer.tsx +2 -1
- package/src/markdown/MarkdownLinkRenderer.test.tsx +9 -0
- package/src/markdown/MarkdownLinkRenderer.tsx +6 -4
- package/src/markdown/MarkdownView.stories.tsx +224 -72
- package/src/markdown/markdownExtensions.ts +6 -4
- package/src/modals/ConfirmAlert.stories.tsx +133 -44
- package/src/modals/ConfirmAlert.tsx +5 -4
- package/src/modals/Modal.stories.tsx +461 -252
- package/src/modals/Modal.tsx +12 -11
- package/src/modals/useRegisterModal.test.tsx +5 -4
- package/src/navigation/MenuContext.tsx +2 -2
- package/src/navigation/NavLink.tsx +4 -7
- package/src/navigation/PrimaryNavigation.tsx +2 -2
- package/src/navigation/PrimaryNavigationLink.tsx +6 -5
- package/src/navigation/RoutingProps.ts +1 -3
- package/src/navigation/SecondaryNavigation.stories.tsx +157 -45
- package/src/navigation/SecondaryNavigation.tsx +17 -16
- package/src/navigation/SecondaryNavigationItem.tsx +2 -1
- package/src/navigation/SubNavigation.tsx +4 -8
- package/src/navigation/useActiveMatch.ts +20 -22
- package/src/navigation/useNavigationLock.ts +1 -0
- package/src/popover/Popover.stories.tsx +111 -41
- package/src/popover/Popover.tsx +2 -5
- package/src/repos/Diff.stories.tsx +418 -223
- package/src/repos/Diff.tsx +1 -5
- package/src/repos/HunkExpandDivider.tsx +2 -2
- package/src/repos/LoadingDiff.tsx +11 -6
- package/src/repos/RepositoryEntry.stories.tsx +217 -53
- package/src/repos/RepositoryFlag.tsx +2 -1
- package/src/repos/TokenizedDiffView.tsx +4 -2
- package/src/repos/annotate/Annotate.stories.tsx +225 -111
- package/src/repos/annotate/AnnotateLine.tsx +2 -1
- package/src/repos/changesets/ChangesetAuthor.tsx +2 -2
- package/src/repos/changesets/ChangesetButtonGroup.test.tsx +9 -5
- package/src/repos/changesets/ChangesetDiff.test.ts +10 -2
- package/src/repos/changesets/Changesets.stories.tsx +388 -197
- package/src/repos/changesets/ContributorRow.tsx +2 -2
- package/src/repos/changesets/SignatureIcon.tsx +1 -0
- package/src/repos/diff/DiffFileTree.tsx +1 -1
- package/src/repos/diff/styledElements.tsx +4 -3
- package/src/repos/index.ts +15 -15
- package/src/search/Hit.tsx +3 -2
- package/src/search/TextHitField.stories.tsx +131 -43
- package/src/search/TextHitField.tsx +3 -2
- package/src/search/index.ts +1 -1
- package/src/storyshots.test.ts +66 -60
- package/src/table/Table.stories.tsx +146 -48
- package/src/table/Table.tsx +7 -8
- package/src/table/TextColumn.tsx +0 -9
- package/src/toast/Toast.tsx +2 -1
- package/src/toast/ToastArea.tsx +2 -2
- package/src/toast/ToastButton.tsx +2 -1
- package/src/toast/ToastButtons.tsx +4 -2
- package/src/toast/ToastNotification.tsx +2 -1
- package/src/toast/index.stories.tsx +144 -39
- package/src/toast/index.ts +1 -1
- package/src/buttons/index.stories.tsx +0 -85
|
@@ -14,10 +14,136 @@
|
|
|
14
14
|
* along with this program. If not, see https://www.gnu.org/licenses/.
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
+
// import React, { FC } from "react";
|
|
18
|
+
// import { storiesOf } from "@storybook/react";
|
|
19
|
+
// import MarkdownView from "./MarkdownView";
|
|
20
|
+
// import styled from "styled-components";
|
|
21
|
+
//
|
|
22
|
+
// import TestPage from "../__resources__/test-page.md";
|
|
23
|
+
// import MarkdownWithoutLang from "../__resources__/markdown-without-lang.md";
|
|
24
|
+
// import MarkdownXmlCodeBlock from "../__resources__/markdown-xml-codeblock.md";
|
|
25
|
+
// import MarkdownUmlCodeBlock from "../__resources__/markdown-uml-codeblock.md";
|
|
26
|
+
// import MarkdownInlineXml from "../__resources__/markdown-inline-xml.md";
|
|
27
|
+
// import MarkdownLinks from "../__resources__/markdown-links.md";
|
|
28
|
+
// import MarkdownImages from "../__resources__/markdown-images.md";
|
|
29
|
+
// import MarkdownCommitLinks from "../__resources__/markdown-commit-link.md";
|
|
30
|
+
// import MarkdownXss from "../__resources__/markdown-xss.md";
|
|
31
|
+
// import MarkdownChangelog from "../__resources__/markdown-changelog.md";
|
|
32
|
+
// import Title from "../layout/Title";
|
|
33
|
+
// import { Subtitle } from "../layout";
|
|
34
|
+
// import { MemoryRouter } from "react-router-dom";
|
|
35
|
+
// import { Binder, BinderContext, extensionPoints } from "@scm-manager/ui-extensions";
|
|
36
|
+
// import { ProtocolLinkRendererProps } from "./markdownExtensions";
|
|
37
|
+
// import { RepositoryContextProvider, RepositoryRevisionContextProvider } from "@scm-manager/ui-api";
|
|
38
|
+
//
|
|
39
|
+
// const Spacing = styled.div`
|
|
40
|
+
// padding: 2em;
|
|
41
|
+
// `;
|
|
42
|
+
//
|
|
43
|
+
// storiesOf("MarkdownView", module)
|
|
44
|
+
// .addDecorator(story => <MemoryRouter initialEntries={["/"]}>{story()}</MemoryRouter>)
|
|
45
|
+
// .addDecorator(story => <Spacing>{story()}</Spacing>)
|
|
46
|
+
// // Add async parameter, because the tests needs to render async before snapshot is taken so that
|
|
47
|
+
// // code fragments get highlighted properly
|
|
48
|
+
// .addParameters({ storyshots: { async: true } })
|
|
49
|
+
// .add("Default", () => <MarkdownView content={TestPage} skipHtml={false} />)
|
|
50
|
+
// .add("Skip Html", () => <MarkdownView content={TestPage} skipHtml={true} />)
|
|
51
|
+
// .add("Code without Lang", () => <MarkdownView content={MarkdownWithoutLang} skipHtml={false} />)
|
|
52
|
+
// .add("Xml Code Block", () => <MarkdownView content={MarkdownXmlCodeBlock} />)
|
|
53
|
+
// .add("Inline Xml", () => (
|
|
54
|
+
// <>
|
|
55
|
+
// <Title title="Inline Xml" />
|
|
56
|
+
// <Subtitle subtitle="Inline xml outside of a code block is not supported" />
|
|
57
|
+
// <MarkdownView content={MarkdownInlineXml} />
|
|
58
|
+
// </>
|
|
59
|
+
// ))
|
|
60
|
+
// .add("Links", () => {
|
|
61
|
+
// const binder = new Binder("custom protocol link renderer");
|
|
62
|
+
// binder.bind<extensionPoints.MarkdownLinkProtocolRenderer<"scw">>("markdown-renderer.link.protocol", {
|
|
63
|
+
// protocol: "scw",
|
|
64
|
+
// renderer: ProtocolLinkRenderer
|
|
65
|
+
// });
|
|
66
|
+
// return (
|
|
67
|
+
// <BinderContext.Provider value={binder}>
|
|
68
|
+
// <MarkdownView content={MarkdownLinks} basePath="/scm/" />
|
|
69
|
+
// </BinderContext.Provider>
|
|
70
|
+
// );
|
|
71
|
+
// })
|
|
72
|
+
// .add("Links without Base Path", () => {
|
|
73
|
+
// const binder = new Binder("custom protocol link renderer");
|
|
74
|
+
// binder.bind<extensionPoints.MarkdownLinkProtocolRenderer<"scw">>("markdown-renderer.link.protocol", {
|
|
75
|
+
// protocol: "scw",
|
|
76
|
+
// renderer: ProtocolLinkRenderer
|
|
77
|
+
// });
|
|
78
|
+
// return (
|
|
79
|
+
// <BinderContext.Provider value={binder}>
|
|
80
|
+
// <MarkdownView content={MarkdownLinks} />
|
|
81
|
+
// </BinderContext.Provider>
|
|
82
|
+
// );
|
|
83
|
+
// })
|
|
84
|
+
// .add("Header Anchor Links", () => (
|
|
85
|
+
// <MarkdownView
|
|
86
|
+
// content={MarkdownChangelog}
|
|
87
|
+
// basePath={"/"}
|
|
88
|
+
// permalink={"/?path=/story/markdownview--header-anchor-links"}
|
|
89
|
+
// enableAnchorHeadings={true}
|
|
90
|
+
// />
|
|
91
|
+
// ))
|
|
92
|
+
// .add("Commit Links", () => <MarkdownView content={MarkdownCommitLinks} />)
|
|
93
|
+
// .add("Custom code renderer", () => {
|
|
94
|
+
// const binder = new Binder("custom code renderer");
|
|
95
|
+
// const Container: FC<{ value: string }> = ({ value }) => {
|
|
96
|
+
// return (
|
|
97
|
+
// <div>
|
|
98
|
+
// <h4 style={{ border: "1px dashed lightgray", padding: "2px" }}>
|
|
99
|
+
// To render plantuml as images within markdown, please install the scm-markdown-plantuml-plugin
|
|
100
|
+
// </h4>
|
|
101
|
+
// <pre>{value}</pre>
|
|
102
|
+
// </div>
|
|
103
|
+
// );
|
|
104
|
+
// };
|
|
105
|
+
// binder.bind<extensionPoints.MarkdownCodeRenderer<"uml">>("markdown-renderer.code.uml", Container);
|
|
106
|
+
// return (
|
|
107
|
+
// <BinderContext.Provider value={binder}>
|
|
108
|
+
// <MarkdownView content={MarkdownUmlCodeBlock} />
|
|
109
|
+
// </BinderContext.Provider>
|
|
110
|
+
// );
|
|
111
|
+
// })
|
|
112
|
+
// .add("XSS Prevention", () => <MarkdownView content={MarkdownXss} skipHtml={false} />)
|
|
113
|
+
// .add("Images", () => (
|
|
114
|
+
// <RepositoryContextProvider
|
|
115
|
+
// // @ts-ignore We do not need a valid repository here, only one with a content link
|
|
116
|
+
// repository={{
|
|
117
|
+
// _links: { content: { href: "https://my.scm/scm/api/v2/some/repository/content/{revision}/{path}" } }
|
|
118
|
+
// }}
|
|
119
|
+
// >
|
|
120
|
+
// <RepositoryRevisionContextProvider revision={"42"}>
|
|
121
|
+
// <MarkdownView basePath={"/scm/"} content={MarkdownImages} />
|
|
122
|
+
// </RepositoryRevisionContextProvider>
|
|
123
|
+
// </RepositoryContextProvider>
|
|
124
|
+
// ));
|
|
125
|
+
//
|
|
126
|
+
// export const ProtocolLinkRenderer: FC<ProtocolLinkRendererProps<"scw">> = ({ protocol, href, children }) => {
|
|
127
|
+
// return (
|
|
128
|
+
// <div style={{ border: "1px dashed lightgray", padding: "2px" }}>
|
|
129
|
+
// <h4>
|
|
130
|
+
// Link: {href} [Protocol: {protocol}]
|
|
131
|
+
// </h4>
|
|
132
|
+
// <div>children: {children}</div>
|
|
133
|
+
// </div>
|
|
134
|
+
// );
|
|
135
|
+
// };
|
|
136
|
+
|
|
17
137
|
import React, { FC } from "react";
|
|
18
|
-
import { storiesOf } from "@storybook/react";
|
|
19
|
-
import MarkdownView from "./MarkdownView";
|
|
20
138
|
import styled from "styled-components";
|
|
139
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
140
|
+
import { Binder, BinderContext, extensionPoints } from "@scm-manager/ui-extensions";
|
|
141
|
+
import { RepositoryContextProvider, RepositoryRevisionContextProvider } from "@scm-manager/ui-api";
|
|
142
|
+
|
|
143
|
+
import MarkdownView from "./MarkdownView";
|
|
144
|
+
import Title from "../layout/Title";
|
|
145
|
+
import { Subtitle } from "../layout";
|
|
146
|
+
import { ProtocolLinkRendererProps } from "./markdownExtensions";
|
|
21
147
|
|
|
22
148
|
import TestPage from "../__resources__/test-page.md";
|
|
23
149
|
import MarkdownWithoutLang from "../__resources__/markdown-without-lang.md";
|
|
@@ -29,107 +155,133 @@ import MarkdownImages from "../__resources__/markdown-images.md";
|
|
|
29
155
|
import MarkdownCommitLinks from "../__resources__/markdown-commit-link.md";
|
|
30
156
|
import MarkdownXss from "../__resources__/markdown-xss.md";
|
|
31
157
|
import MarkdownChangelog from "../__resources__/markdown-changelog.md";
|
|
32
|
-
import Title from "../layout/Title";
|
|
33
|
-
import { Subtitle } from "../layout";
|
|
34
158
|
import { MemoryRouter } from "react-router-dom";
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
import { RepositoryContextProvider, RepositoryRevisionContextProvider } from "@scm-manager/ui-api";
|
|
159
|
+
|
|
160
|
+
// --- Helfer-Komponenten und Mock-Daten (aus der Original-Story übernommen) ---
|
|
38
161
|
|
|
39
162
|
const Spacing = styled.div`
|
|
40
163
|
padding: 2em;
|
|
41
164
|
`;
|
|
42
165
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
166
|
+
const ProtocolLinkRenderer: FC<ProtocolLinkRendererProps<"scw">> = ({ protocol, href, children }) => (
|
|
167
|
+
<div style={{ border: "1px dashed lightgray", padding: "2px" }}>
|
|
168
|
+
<h4>
|
|
169
|
+
Link: {href} [Protocol: {protocol}]
|
|
170
|
+
</h4>
|
|
171
|
+
<div>children: {children}</div>
|
|
172
|
+
</div>
|
|
173
|
+
);
|
|
174
|
+
|
|
175
|
+
// --- Storybook Metadaten ---
|
|
176
|
+
|
|
177
|
+
const meta: Meta<typeof MarkdownView> = {
|
|
178
|
+
title: "Global/MarkdownView",
|
|
179
|
+
component: MarkdownView,
|
|
180
|
+
decorators: [
|
|
181
|
+
(Story) => <MemoryRouter initialEntries={["/"]}>{Story()}</MemoryRouter>,
|
|
182
|
+
(Story) => <Spacing>{Story()}</Spacing>],
|
|
183
|
+
tags: ["autodocs"],
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
export default meta;
|
|
187
|
+
|
|
188
|
+
// --- Story-Definitionen ---
|
|
189
|
+
|
|
190
|
+
type Story = StoryObj<typeof meta>;
|
|
191
|
+
|
|
192
|
+
// Einfache Stories, die `args` verwenden
|
|
193
|
+
export const Default: Story = {
|
|
194
|
+
args: { content: TestPage, skipHtml: false },
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
export const SkipHtml: Story = {
|
|
198
|
+
args: { content: TestPage, skipHtml: true },
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
export const CodeWithoutLanguage: Story = {
|
|
202
|
+
name: "Code Without Language",
|
|
203
|
+
args: { content: MarkdownWithoutLang, skipHtml: false },
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
export const XmlCodeBlock: Story = {
|
|
207
|
+
args: { content: MarkdownXmlCodeBlock },
|
|
208
|
+
};
|
|
209
|
+
|
|
210
|
+
export const CommitLinks: Story = {
|
|
211
|
+
args: { content: MarkdownCommitLinks },
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
export const HeaderAnchorLinks: Story = {
|
|
215
|
+
args: {
|
|
216
|
+
content: MarkdownChangelog,
|
|
217
|
+
basePath: "/",
|
|
218
|
+
permalink: "/?path=/story/markdownview--header-anchor-links",
|
|
219
|
+
enableAnchorHeadings: true,
|
|
220
|
+
},
|
|
221
|
+
};
|
|
222
|
+
|
|
223
|
+
export const XSSPrevention: Story = {
|
|
224
|
+
args: { content: MarkdownXss, skipHtml: false },
|
|
225
|
+
};
|
|
226
|
+
|
|
227
|
+
// Komplexe Stories, die eine `render`-Funktion benötigen
|
|
228
|
+
export const InlineXml: Story = {
|
|
229
|
+
render: () => (
|
|
54
230
|
<>
|
|
55
231
|
<Title title="Inline Xml" />
|
|
56
232
|
<Subtitle subtitle="Inline xml outside of a code block is not supported" />
|
|
57
233
|
<MarkdownView content={MarkdownInlineXml} />
|
|
58
234
|
</>
|
|
59
|
-
)
|
|
60
|
-
|
|
235
|
+
),
|
|
236
|
+
};
|
|
237
|
+
|
|
238
|
+
export const Links: Story = {
|
|
239
|
+
render: () => {
|
|
61
240
|
const binder = new Binder("custom protocol link renderer");
|
|
62
241
|
binder.bind<extensionPoints.MarkdownLinkProtocolRenderer<"scw">>("markdown-renderer.link.protocol", {
|
|
63
242
|
protocol: "scw",
|
|
64
|
-
renderer: ProtocolLinkRenderer
|
|
243
|
+
renderer: ProtocolLinkRenderer,
|
|
65
244
|
});
|
|
66
245
|
return (
|
|
67
246
|
<BinderContext.Provider value={binder}>
|
|
68
247
|
<MarkdownView content={MarkdownLinks} basePath="/scm/" />
|
|
69
248
|
</BinderContext.Provider>
|
|
70
249
|
);
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
});
|
|
78
|
-
return (
|
|
79
|
-
<BinderContext.Provider value={binder}>
|
|
80
|
-
<MarkdownView content={MarkdownLinks} />
|
|
81
|
-
</BinderContext.Provider>
|
|
82
|
-
);
|
|
83
|
-
})
|
|
84
|
-
.add("Header Anchor Links", () => (
|
|
85
|
-
<MarkdownView
|
|
86
|
-
content={MarkdownChangelog}
|
|
87
|
-
basePath={"/"}
|
|
88
|
-
permalink={"/?path=/story/markdownview--header-anchor-links"}
|
|
89
|
-
enableAnchorHeadings={true}
|
|
90
|
-
/>
|
|
91
|
-
))
|
|
92
|
-
.add("Commit Links", () => <MarkdownView content={MarkdownCommitLinks} />)
|
|
93
|
-
.add("Custom code renderer", () => {
|
|
250
|
+
},
|
|
251
|
+
};
|
|
252
|
+
|
|
253
|
+
export const CustomCodeRenderer: Story = {
|
|
254
|
+
name: "Custom Code Renderer (UML)",
|
|
255
|
+
render: () => {
|
|
94
256
|
const binder = new Binder("custom code renderer");
|
|
95
|
-
const Container: FC<{ value: string }> = ({ value }) =>
|
|
96
|
-
|
|
97
|
-
<
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
);
|
|
104
|
-
};
|
|
257
|
+
const Container: FC<{ value: string }> = ({ value }) => (
|
|
258
|
+
<div>
|
|
259
|
+
<h4 style={{ border: "1px dashed lightgray", padding: "2px" }}>
|
|
260
|
+
To render plantuml as images within markdown, please install the scm-markdown-plantuml-plugin
|
|
261
|
+
</h4>
|
|
262
|
+
<pre>{value}</pre>
|
|
263
|
+
</div>
|
|
264
|
+
);
|
|
105
265
|
binder.bind<extensionPoints.MarkdownCodeRenderer<"uml">>("markdown-renderer.code.uml", Container);
|
|
106
266
|
return (
|
|
107
267
|
<BinderContext.Provider value={binder}>
|
|
108
268
|
<MarkdownView content={MarkdownUmlCodeBlock} />
|
|
109
269
|
</BinderContext.Provider>
|
|
110
270
|
);
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
|
|
271
|
+
},
|
|
272
|
+
};
|
|
273
|
+
|
|
274
|
+
export const Images: Story = {
|
|
275
|
+
render: () => (
|
|
114
276
|
<RepositoryContextProvider
|
|
115
|
-
// @ts-ignore We do not need a valid repository here
|
|
277
|
+
// @ts-ignore We do not need a valid repository here
|
|
116
278
|
repository={{
|
|
117
|
-
_links: { content: { href: "https://my.scm/scm/api/v2/some/repository/content/{revision}/{path}" } }
|
|
279
|
+
_links: { content: { href: "https://my.scm/scm/api/v2/some/repository/content/{revision}/{path}" } },
|
|
118
280
|
}}
|
|
119
281
|
>
|
|
120
|
-
<RepositoryRevisionContextProvider revision=
|
|
121
|
-
<MarkdownView basePath=
|
|
282
|
+
<RepositoryRevisionContextProvider revision="42">
|
|
283
|
+
<MarkdownView basePath="/scm/" content={MarkdownImages} />
|
|
122
284
|
</RepositoryRevisionContextProvider>
|
|
123
285
|
</RepositoryContextProvider>
|
|
124
|
-
)
|
|
125
|
-
|
|
126
|
-
export const ProtocolLinkRenderer: FC<ProtocolLinkRendererProps<"scw">> = ({ protocol, href, children }) => {
|
|
127
|
-
return (
|
|
128
|
-
<div style={{ border: "1px dashed lightgray", padding: "2px" }}>
|
|
129
|
-
<h4>
|
|
130
|
-
Link: {href} [Protocol: {protocol}]
|
|
131
|
-
</h4>
|
|
132
|
-
<div>children: {children}</div>
|
|
133
|
-
</div>
|
|
134
|
-
);
|
|
286
|
+
),
|
|
135
287
|
};
|
|
@@ -15,17 +15,19 @@
|
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
17
|
import { extensionPoints } from "@scm-manager/ui-extensions";
|
|
18
|
-
import { ComponentProps } from "react";
|
|
18
|
+
import { ComponentProps, FC, ReactNode } from "react";
|
|
19
|
+
|
|
20
|
+
type WithChildren<T> = T extends FC<infer P> ? FC<P & { children?: ReactNode }> : never;
|
|
19
21
|
|
|
20
22
|
export type ProtocolLinkRendererProps<Protocol extends string | undefined = undefined> = ComponentProps<
|
|
21
|
-
extensionPoints.MarkdownLinkProtocolRenderer<Protocol>["type"]["renderer"]
|
|
23
|
+
WithChildren<extensionPoints.MarkdownLinkProtocolRenderer<Protocol>["type"]["renderer"]>
|
|
22
24
|
>;
|
|
23
25
|
|
|
24
26
|
/**
|
|
25
27
|
* @deprecated use {@link MarkdownLinkProtocolRenderer}`["type"]` instead
|
|
26
28
|
*/
|
|
27
|
-
export type ProtocolLinkRendererExtension = extensionPoints.MarkdownLinkProtocolRenderer["type"]
|
|
29
|
+
export type ProtocolLinkRendererExtension = WithChildren<extensionPoints.MarkdownLinkProtocolRenderer["type"]>;
|
|
28
30
|
|
|
29
31
|
export type ProtocolLinkRendererExtensionMap = {
|
|
30
|
-
[protocol: string]: extensionPoints.MarkdownLinkProtocolRenderer["type"]["renderer"] | undefined;
|
|
32
|
+
[protocol: string]: WithChildren<extensionPoints.MarkdownLinkProtocolRenderer["type"]["renderer"]> | undefined;
|
|
31
33
|
};
|
|
@@ -14,64 +14,153 @@
|
|
|
14
14
|
* along with this program. If not, see https://www.gnu.org/licenses/.
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
-
import { storiesOf } from "@storybook/react";
|
|
18
|
-
import { MemoryRouter } from "react-router-dom";
|
|
19
|
-
import * as React from "react";
|
|
17
|
+
// import { storiesOf } from "@storybook/react";
|
|
18
|
+
// import { MemoryRouter } from "react-router-dom";
|
|
19
|
+
// import * as React from "react";
|
|
20
|
+
// import ConfirmAlert, { confirmAlert } from "./ConfirmAlert";
|
|
21
|
+
// import ActiveModalCountContext from "./activeModalCountContext";
|
|
22
|
+
//
|
|
23
|
+
// const body =
|
|
24
|
+
// "Mind-paralyzing change needed improbability vortex machine sorts sought same theory upending job just allows\n " +
|
|
25
|
+
// "hostess’s really oblong Infinite Improbability thing into the starship against which behavior accordance with\n " +
|
|
26
|
+
// "Kakrafoon humanoid undergarment ship powered by GPP-guided bowl of petunias nothing was frequently away incredibly\n " +
|
|
27
|
+
// "ordinary mob.";
|
|
28
|
+
//
|
|
29
|
+
// const buttons = [
|
|
30
|
+
// {
|
|
31
|
+
// className: "is-outlined",
|
|
32
|
+
// label: "Cancel",
|
|
33
|
+
// onClick: () => null,
|
|
34
|
+
// },
|
|
35
|
+
// {
|
|
36
|
+
// label: "Submit",
|
|
37
|
+
// },
|
|
38
|
+
// ];
|
|
39
|
+
//
|
|
40
|
+
// const buttonsWithAutofocus = [
|
|
41
|
+
// {
|
|
42
|
+
// label: "Cancel",
|
|
43
|
+
// onClick: () => null,
|
|
44
|
+
// },
|
|
45
|
+
// {
|
|
46
|
+
// className: "is-info",
|
|
47
|
+
// label: "I should be focused",
|
|
48
|
+
// autofocus: true,
|
|
49
|
+
// },
|
|
50
|
+
// ];
|
|
51
|
+
//
|
|
52
|
+
// const doNothing = () => {
|
|
53
|
+
// // Do nothing
|
|
54
|
+
// };
|
|
55
|
+
//
|
|
56
|
+
// storiesOf("Modal/ConfirmAlert", module)
|
|
57
|
+
// .addDecorator((story) => <MemoryRouter initialEntries={["/"]}>{story()}</MemoryRouter>)
|
|
58
|
+
// .addDecorator((story) => (
|
|
59
|
+
// <ActiveModalCountContext.Provider value={{ value: 0, increment: doNothing, decrement: doNothing }}>
|
|
60
|
+
// {story()}
|
|
61
|
+
// </ActiveModalCountContext.Provider>
|
|
62
|
+
// ))
|
|
63
|
+
// .add("Default", () => <ConfirmAlert message={body} title={"Are you sure about that?"} buttons={buttons} />)
|
|
64
|
+
// .add("WithButton", () => {
|
|
65
|
+
// const buttonClick = () => {
|
|
66
|
+
// confirmAlert({ message: body, title: "Are you sure about that?", buttons });
|
|
67
|
+
// };
|
|
68
|
+
// return (
|
|
69
|
+
// <>
|
|
70
|
+
// <button onClick={buttonClick}>Open ConfirmAlert</button>
|
|
71
|
+
// <div id="modalRoot" />
|
|
72
|
+
// </>
|
|
73
|
+
// );
|
|
74
|
+
// })
|
|
75
|
+
// .add("Autofocus", () => (
|
|
76
|
+
// <ConfirmAlert message={body} title={"Are you sure about that?"} buttons={buttonsWithAutofocus} />
|
|
77
|
+
// ));
|
|
78
|
+
|
|
79
|
+
import React from "react";
|
|
80
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
20
81
|
import ConfirmAlert, { confirmAlert } from "./ConfirmAlert";
|
|
21
82
|
import ActiveModalCountContext from "./activeModalCountContext";
|
|
22
83
|
|
|
84
|
+
// --- Helfer-Funktionen und Mock-Daten (aus der Original-Story übernommen) ---
|
|
85
|
+
|
|
23
86
|
const body =
|
|
24
87
|
"Mind-paralyzing change needed improbability vortex machine sorts sought same theory upending job just allows\n " +
|
|
25
88
|
"hostess’s really oblong Infinite Improbability thing into the starship against which behavior accordance with\n " +
|
|
26
89
|
"Kakrafoon humanoid undergarment ship powered by GPP-guided bowl of petunias nothing was frequently away incredibly\n " +
|
|
27
90
|
"ordinary mob.";
|
|
28
91
|
|
|
29
|
-
const buttons = [
|
|
30
|
-
{
|
|
31
|
-
className: "is-outlined",
|
|
32
|
-
label: "Cancel",
|
|
33
|
-
onClick: () => null,
|
|
34
|
-
},
|
|
35
|
-
{
|
|
36
|
-
label: "Submit",
|
|
37
|
-
},
|
|
38
|
-
];
|
|
92
|
+
const buttons = [{ className: "is-outlined", label: "Cancel", onClick: () => null }, { label: "Submit" }];
|
|
39
93
|
|
|
40
94
|
const buttonsWithAutofocus = [
|
|
41
|
-
{
|
|
42
|
-
|
|
43
|
-
onClick: () => null,
|
|
44
|
-
},
|
|
45
|
-
{
|
|
46
|
-
className: "is-info",
|
|
47
|
-
label: "I should be focused",
|
|
48
|
-
autofocus: true,
|
|
49
|
-
},
|
|
95
|
+
{ label: "Cancel", onClick: () => null },
|
|
96
|
+
{ className: "is-info", label: "I should be focused", autofocus: true },
|
|
50
97
|
];
|
|
51
98
|
|
|
52
99
|
const doNothing = () => {
|
|
53
100
|
// Do nothing
|
|
54
101
|
};
|
|
55
102
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
103
|
+
// Helfer-Komponente für die Story, die den Alert per Klick auslöst
|
|
104
|
+
const TriggerConfirmAlertExample = () => {
|
|
105
|
+
const handleClick = () => {
|
|
106
|
+
confirmAlert({ message: body, title: "Are you sure about that?", buttons });
|
|
107
|
+
};
|
|
108
|
+
return (
|
|
109
|
+
<>
|
|
110
|
+
<p>
|
|
111
|
+
Klicken Sie auf den Button, um den Bestätigungsdialog imperativ auszulösen. Der Dialog wird in{" "}
|
|
112
|
+
<code>#modalRoot</code> gerendert.
|
|
113
|
+
</p>
|
|
114
|
+
<button className="button" onClick={handleClick}>
|
|
115
|
+
Open ConfirmAlert
|
|
116
|
+
</button>
|
|
117
|
+
{/* Das ist notwendig, damit die `confirmAlert`-Funktion ein Einhängepunkt im DOM findet. */}
|
|
118
|
+
<div id="modalRoot" />
|
|
119
|
+
</>
|
|
120
|
+
);
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
// --- Storybook Metadaten ---
|
|
124
|
+
|
|
125
|
+
const meta: Meta<typeof ConfirmAlert> = {
|
|
126
|
+
title: "Modal/ConfirmAlert",
|
|
127
|
+
component: ConfirmAlert,
|
|
128
|
+
// Der ActiveModalCountContext.Provider wird als Decorator für alle Stories beibehalten.
|
|
129
|
+
decorators: [
|
|
130
|
+
(Story) => (
|
|
131
|
+
<ActiveModalCountContext.Provider value={{ value: 0, increment: doNothing, decrement: doNothing }}>
|
|
132
|
+
<div style={{ margin: "2rem" }}>
|
|
133
|
+
<Story />
|
|
134
|
+
</div>
|
|
135
|
+
</ActiveModalCountContext.Provider>
|
|
136
|
+
),
|
|
137
|
+
],
|
|
138
|
+
tags: ["autodocs"],
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
export default meta;
|
|
142
|
+
|
|
143
|
+
// --- Story-Definitionen ---
|
|
144
|
+
|
|
145
|
+
type Story = StoryObj<typeof meta>;
|
|
146
|
+
|
|
147
|
+
export const Default: Story = {
|
|
148
|
+
args: {
|
|
149
|
+
message: body,
|
|
150
|
+
title: "Are you sure about that?",
|
|
151
|
+
buttons: buttons,
|
|
152
|
+
},
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
export const Autofocus: Story = {
|
|
156
|
+
args: {
|
|
157
|
+
...Default.args,
|
|
158
|
+
buttons: buttonsWithAutofocus,
|
|
159
|
+
},
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
// Diese Story verwendet eine `render`-Funktion, um die imperative API zu demonstrieren.
|
|
163
|
+
export const TriggeredByButton: Story = {
|
|
164
|
+
name: "Triggered by Button",
|
|
165
|
+
render: () => <TriggerConfirmAlertExample />,
|
|
166
|
+
};
|
|
@@ -14,9 +14,9 @@
|
|
|
14
14
|
* along with this program. If not, see https://www.gnu.org/licenses/.
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
+
import { createRoot } from "react-dom/client";
|
|
17
18
|
import * as React from "react";
|
|
18
|
-
import { FC, useRef, useState } from "react";
|
|
19
|
-
import ReactDOM from "react-dom";
|
|
19
|
+
import { FC, ReactNode, useRef, useState } from "react";
|
|
20
20
|
import Modal from "./Modal";
|
|
21
21
|
import classNames from "classnames";
|
|
22
22
|
|
|
@@ -34,6 +34,7 @@ type Props = {
|
|
|
34
34
|
message?: string;
|
|
35
35
|
buttons: Button[];
|
|
36
36
|
close?: () => void;
|
|
37
|
+
children?: ReactNode;
|
|
37
38
|
};
|
|
38
39
|
|
|
39
40
|
export const ConfirmAlert: FC<Props> = ({ title, message, buttons, close, children }) => {
|
|
@@ -102,11 +103,11 @@ export function confirmAlert(properties: Props) {
|
|
|
102
103
|
const close = () => {
|
|
103
104
|
const container = document.getElementById("modalRoot");
|
|
104
105
|
if (container) {
|
|
105
|
-
|
|
106
|
+
createRoot(container).unmount();
|
|
106
107
|
}
|
|
107
108
|
};
|
|
108
109
|
const props = { ...properties, close };
|
|
109
|
-
|
|
110
|
+
createRoot(root).render(<ConfirmAlert {...props} />);
|
|
110
111
|
}
|
|
111
112
|
}
|
|
112
113
|
|