diff --git a/scm-ui/ui-buttons/.storybook/.babelrc b/scm-ui/ui-buttons/.storybook/.babelrc
deleted file mode 100644
index 2fa1f1e174..0000000000
--- a/scm-ui/ui-buttons/.storybook/.babelrc
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "presets": ["@scm-manager/babel-preset"],
- "plugins": ["@babel/plugin-syntax-dynamic-import"]
-}
diff --git a/scm-ui/ui-buttons/.storybook/RemoveThemesPlugin.js b/scm-ui/ui-buttons/.storybook/RemoveThemesPlugin.js
deleted file mode 100644
index 9976554354..0000000000
--- a/scm-ui/ui-buttons/.storybook/RemoveThemesPlugin.js
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * 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.
- */
-
-const HtmlWebpackPlugin = require('html-webpack-plugin');
-
-class RemoveThemesPlugin {
- apply (compiler) {
- compiler.hooks.compilation.tap('RemoveThemesPlugin', (compilation) => {
-
- HtmlWebpackPlugin.getHooks(compilation).beforeAssetTagGeneration.tapAsync(
- 'RemoveThemesPlugin',
- (data, cb) => {
-
- // remove generated style-loader bundles from the page
- // there should be a better way, which does not generate the bundles at all
- // but for now it works
- if (data.assets.js) {
- data.assets.js = data.assets.js.filter(bundle => !bundle.startsWith("ui-theme-"))
- .filter(bundle => !bundle.startsWith("runtime~ui-theme-"))
- }
-
- // remove css links to avoid conflicts with the themes
- // so we remove all and add our own via preview-head.html
- if (data.assets.css) {
- data.assets.css = data.assets.css.filter(css => !css.startsWith("ui-theme-"))
- }
-
- // Tell webpack to move on
- cb(null, data)
- }
- )
- })
- }
-}
-
-module.exports = RemoveThemesPlugin
diff --git a/scm-ui/ui-buttons/.storybook/preview-head.html b/scm-ui/ui-buttons/.storybook/preview-head.html
deleted file mode 100644
index d1c34ac7ef..0000000000
--- a/scm-ui/ui-buttons/.storybook/preview-head.html
+++ /dev/null
@@ -1,26 +0,0 @@
-
-
-
-
diff --git a/scm-ui/ui-buttons/README.md b/scm-ui/ui-buttons/README.md
deleted file mode 100644
index 8be9d65a53..0000000000
--- a/scm-ui/ui-buttons/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-## Bulma
-
-See Bulma element: https://bulma.io/documentation/elements/button
diff --git a/scm-ui/ui-text/.storybook/main.js b/scm-ui/ui-buttons/index.ts
similarity index 89%
rename from scm-ui/ui-text/.storybook/main.js
rename to scm-ui/ui-buttons/index.ts
index 87d3241ed0..e727f1b8ff 100644
--- a/scm-ui/ui-text/.storybook/main.js
+++ b/scm-ui/ui-buttons/index.ts
@@ -22,10 +22,4 @@
* SOFTWARE.
*/
-module.exports = {
- stories: ["../src/**/*.stories.@(ts|tsx)"],
- framework: "@storybook/react",
- core: {
- builder: "webpack5",
- },
-};
+export { Icon, Button, LinkButton, ExternalLinkButton, ExternalLink, ButtonVariants } from "@scm-manager/ui-core";
diff --git a/scm-ui/ui-buttons/package.json b/scm-ui/ui-buttons/package.json
index 864b5407e9..952741d82e 100644
--- a/scm-ui/ui-buttons/package.json
+++ b/scm-ui/ui-buttons/package.json
@@ -2,77 +2,14 @@
"name": "@scm-manager/ui-buttons",
"version": "3.0.0-SNAPSHOT",
"private": false,
- "main": "build/index.js",
- "module": "build/index.mjs",
- "types": "build/index.d.ts",
- "files": [
- "build"
- ],
- "scripts": {
- "build": "tsup ./src/index.ts -d build --format esm,cjs --dts",
- "dev": "tsup ./src/index.ts -d build --format esm,cjs --dts --watch",
- "lint": "eslint src",
- "typecheck": "tsc",
- "storybook": "start-storybook -p 6006 -s ../ui-webapp/public",
- "build-storybook": "build-storybook",
- "image-snapshots": "jest \"image-snapshot.test.ts\"",
- "a11y-check": "jest \"a11y.test.ts\"",
- "depcheck": "depcheck"
- },
+ "main": "index.ts",
"peerDependencies": {
- "react": "^17.0.1",
- "react-dom": "^17.0.1",
- "react-router-dom": "^5.3.1",
- "classnames": "^2.2.6",
- "@scm-manager/ui-components": "3.0.0-SNAPSHOT"
+ "@scm-manager/ui-core": "3.0.0-SNAPSHOT"
},
"devDependencies": {
"@scm-manager/prettier-config": "^2.11.1",
- "@scm-manager/ui-api": "3.0.0-SNAPSHOT",
"@scm-manager/eslint-config": "^2.17.0",
- "@babel/core": "^7.17.8",
- "@scm-manager/tsconfig": "^2.12.0",
- "@storybook/addon-essentials": "^6.4.20",
- "@storybook/addon-interactions": "^6.4.20",
- "@storybook/addon-a11y": "^6.4.20",
- "@storybook/addon-links": "^6.4.20",
- "@storybook/builder-webpack5": "^6.4.20",
- "@storybook/manager-webpack5": "^6.4.20",
- "@storybook/react": "^6.4.20",
- "@storybook/addon-storyshots-puppeteer": "^6.4.20",
- "@storybook/addon-storyshots": "^6.4.20",
- "@storybook/testing-library": "^0.0.9",
- "jest-transform-css": "^4.0.1",
- "puppeteer": "^15.5.0",
- "storybook-addon-pseudo-states": "^1.15.1",
- "storybook-react-router": "^1.0.8",
- "@types/storybook-react-router": "^1.0.2",
- "sass-loader": "^12.3.0",
- "storybook-addon-themes": "^6.1.0",
- "babel-loader": "^8.2.4",
- "postcss": "^8.4.12",
- "postcss-loader": "^6.2.1",
- "webpack": "5",
- "tsup": "^6.1.2",
- "mini-css-extract-plugin": "^1.6.2",
- "html-webpack-plugin": "^5.5.0",
- "react-query": "^3.25.1",
- "i18next": "^19.9.2",
- "react-i18next": "11",
- "i18next-fetch-backend": "^2.3.1",
- "depcheck": "^1.4.3"
- },
- "babel": {
- "presets": [
- "@scm-manager/babel-preset"
- ]
- },
- "jest": {
- "transform": {
- "^.+\\.[tj]sx?$": "babel-jest",
- "^.+\\.(css|less|scss)$": "jest-transform-css",
- "^.+\\.mdx?$": "@storybook/addon-docs/jest-transform-mdx"
- }
+ "@scm-manager/tsconfig": "^2.13.0"
},
"prettier": "@scm-manager/prettier-config",
"eslintConfig": {
@@ -81,4 +18,4 @@
"publishConfig": {
"access": "public"
}
-}
\ No newline at end of file
+}
diff --git a/scm-ui/ui-components/src/BackendErrorNotification.tsx b/scm-ui/ui-components/src/BackendErrorNotification.tsx
index 45e1a4797a..3b2952091d 100644
--- a/scm-ui/ui-components/src/BackendErrorNotification.tsx
+++ b/scm-ui/ui-components/src/BackendErrorNotification.tsx
@@ -30,6 +30,10 @@ type Props = Omit, "type" | "role"> & {
error: BackendError;
};
+/**
+ * @deprecated Please import the identical module from "@scm-manager/ui-core"
+ */
+
const BackendErrorNotification: FC = ({ error, ...props }) => {
const [t] = useTranslation("plugins");
diff --git a/scm-ui/ui-components/src/ErrorNotification.tsx b/scm-ui/ui-components/src/ErrorNotification.tsx
index 6d18b34019..b01536f10b 100644
--- a/scm-ui/ui-components/src/ErrorNotification.tsx
+++ b/scm-ui/ui-components/src/ErrorNotification.tsx
@@ -50,6 +50,9 @@ const BasicErrorMessage: FC, "type" | "
);
};
+/**
+ * @deprecated Please import the identical module from "@scm-manager/ui-core"
+ */
const ErrorNotification: FC = ({ error, ...props }) => {
const [t] = useTranslation("commons");
if (error) {
diff --git a/scm-ui/ui-components/src/Image.tsx b/scm-ui/ui-components/src/Image.tsx
index 2e55624fc7..af1e0067ac 100644
--- a/scm-ui/ui-components/src/Image.tsx
+++ b/scm-ui/ui-components/src/Image.tsx
@@ -31,6 +31,9 @@ type Props = {
className?: string;
};
+/**
+ * @deprecated Please import the identical module from "@scm-manager/ui-core"
+ */
class Image extends React.Component {
createImageSrc = () => {
const { src } = this.props;
diff --git a/scm-ui/ui-components/src/Loading.tsx b/scm-ui/ui-components/src/Loading.tsx
index ec86c36f51..1d24005300 100644
--- a/scm-ui/ui-components/src/Loading.tsx
+++ b/scm-ui/ui-components/src/Loading.tsx
@@ -40,6 +40,10 @@ const FixedSizedImage = styled(Image)`
height: 128px;
`;
+/**
+ * @deprecated Please import the identical module from "@scm-manager/ui-core"
+ */
+
class Loading extends React.Component {
render() {
const { message, t } = this.props;
diff --git a/scm-ui/ui-components/src/Notification.tsx b/scm-ui/ui-components/src/Notification.tsx
index 9a97770ea8..b03dfb35c3 100644
--- a/scm-ui/ui-components/src/Notification.tsx
+++ b/scm-ui/ui-components/src/Notification.tsx
@@ -34,6 +34,10 @@ type Props = {
role?: string;
};
+/**
+ * @deprecated Please import the identical module from "@scm-manager/ui-core"
+ */
+
const Notification: FC = ({ type = "info", onClose, className, children, role }) => {
const renderCloseButton = () => {
if (onClose) {
diff --git a/scm-ui/ui-components/src/__snapshots__/storyshots.test.ts.snap b/scm-ui/ui-components/src/__snapshots__/storyshots.test.ts.snap
index 661171f18a..fbaef7432c 100644
--- a/scm-ui/ui-components/src/__snapshots__/storyshots.test.ts.snap
+++ b/scm-ui/ui-components/src/__snapshots__/storyshots.test.ts.snap
@@ -71110,7 +71110,7 @@ exports[`Storyshots Repositories/RepositoryEntry Archived 1`] = `
(window.scmStage || "").toUpperCase() !== "PRODUCTION";
+/**
+ * @deprecated Please import the identical module from "@scm-manager/ui-core"
+ */
+
export const createAttributesForTesting = (testId?: string) => {
if (!testId) {
return undefined;
diff --git a/scm-ui/ui-components/src/layout/Level.tsx b/scm-ui/ui-components/src/layout/Level.tsx
index 9076114c1b..d9280bd650 100644
--- a/scm-ui/ui-components/src/layout/Level.tsx
+++ b/scm-ui/ui-components/src/layout/Level.tsx
@@ -31,6 +31,10 @@ type Props = {
right?: ReactNode;
};
+/**
+ * @deprecated Please import the identical module from "@scm-manager/ui-core"
+ */
+
export default class Level extends React.Component {
render() {
const { className, left, children, right } = this.props;
diff --git a/scm-ui/ui-components/src/layout/SubSubtitle.tsx b/scm-ui/ui-components/src/layout/SubSubtitle.tsx
index ece0352106..48f5e09cf6 100644
--- a/scm-ui/ui-components/src/layout/SubSubtitle.tsx
+++ b/scm-ui/ui-components/src/layout/SubSubtitle.tsx
@@ -28,6 +28,10 @@ type Props = {
className?: string;
};
+/**
+ * @deprecated Please import the identical module from "@scm-manager/ui-core"
+ */
+
class SubSubtitle extends React.Component {
render() {
const { className, children } = this.props;
diff --git a/scm-ui/ui-components/src/layout/Subtitle.tsx b/scm-ui/ui-components/src/layout/Subtitle.tsx
index cf6602dc52..3169cb06a0 100644
--- a/scm-ui/ui-components/src/layout/Subtitle.tsx
+++ b/scm-ui/ui-components/src/layout/Subtitle.tsx
@@ -29,6 +29,10 @@ type Props = {
className?: string;
};
+/**
+ * @deprecated Please import the identical module from "@scm-manager/ui-core"
+ */
+
const Subtitle: FC = ({ subtitle, className, children }) => {
if (subtitle) {
return
{subtitle}
;
diff --git a/scm-ui/ui-components/src/layout/Title.tsx b/scm-ui/ui-components/src/layout/Title.tsx
index adf42d775c..1502f89715 100644
--- a/scm-ui/ui-components/src/layout/Title.tsx
+++ b/scm-ui/ui-components/src/layout/Title.tsx
@@ -31,6 +31,10 @@ type Props = {
className?: string;
};
+/**
+ * @deprecated Please import the identical module from "@scm-manager/ui-core"
+ */
+
const Title: FC = ({ title, preventRefreshingPageTitle, customPageTitle, className, children }) => {
useEffect(() => {
if (!preventRefreshingPageTitle) {
diff --git a/scm-ui/ui-components/src/useGeneratedId.tsx b/scm-ui/ui-components/src/useGeneratedId.tsx
index 1ae7473e1b..cccd211d25 100644
--- a/scm-ui/ui-components/src/useGeneratedId.tsx
+++ b/scm-ui/ui-components/src/useGeneratedId.tsx
@@ -22,10 +22,11 @@
* SOFTWARE.
*/
-import { useMemo } from "react";
-
-let counter = 0;
+import { useAriaId } from "@scm-manager/ui-core";
+/**
+ * @deprecated Please import the identical module from "@scm-manager/ui-core"
+ */
export default function useGeneratedId(fallback?: string) {
- return useMemo(() => fallback ?? `scm-id-${++counter}`, [fallback]);
+ return useAriaId(fallback);
}
diff --git a/scm-ui/ui-core/.storybook/.babelrc b/scm-ui/ui-core/.storybook/.babelrc
new file mode 100644
index 0000000000..a138b1182a
--- /dev/null
+++ b/scm-ui/ui-core/.storybook/.babelrc
@@ -0,0 +1,3 @@
+{
+ "presets": ["@scm-manager/babel-preset"]
+}
diff --git a/scm-ui/ui-forms/.storybook/RemoveThemesPlugin.js b/scm-ui/ui-core/.storybook/RemoveThemesPlugin.js
similarity index 95%
rename from scm-ui/ui-forms/.storybook/RemoveThemesPlugin.js
rename to scm-ui/ui-core/.storybook/RemoveThemesPlugin.js
index 9976554354..13e07247d0 100644
--- a/scm-ui/ui-forms/.storybook/RemoveThemesPlugin.js
+++ b/scm-ui/ui-core/.storybook/RemoveThemesPlugin.js
@@ -31,13 +31,13 @@ class RemoveThemesPlugin {
HtmlWebpackPlugin.getHooks(compilation).beforeAssetTagGeneration.tapAsync(
'RemoveThemesPlugin',
(data, cb) => {
-
+
// remove generated style-loader bundles from the page
// there should be a better way, which does not generate the bundles at all
// but for now it works
if (data.assets.js) {
data.assets.js = data.assets.js.filter(bundle => !bundle.startsWith("ui-theme-"))
- .filter(bundle => !bundle.startsWith("runtime~ui-theme-"))
+ .filter(bundle => !bundle.startsWith("runtime~ui-theme-"))
}
// remove css links to avoid conflicts with the themes
diff --git a/scm-ui/ui-buttons/.storybook/main.js b/scm-ui/ui-core/.storybook/main.js
similarity index 99%
rename from scm-ui/ui-buttons/.storybook/main.js
rename to scm-ui/ui-core/.storybook/main.js
index f5e456bcaa..68c4366cb1 100644
--- a/scm-ui/ui-buttons/.storybook/main.js
+++ b/scm-ui/ui-core/.storybook/main.js
@@ -30,6 +30,7 @@ const ReactDOM = require("react-dom");
const root = path.resolve("..");
+
const themedir = path.join(root, "ui-styles", "src");
ReactDOM.createPortal = (node) => node;
diff --git a/scm-ui/ui-overlays/.storybook/preview-head.html b/scm-ui/ui-core/.storybook/preview-head.html
similarity index 99%
rename from scm-ui/ui-overlays/.storybook/preview-head.html
rename to scm-ui/ui-core/.storybook/preview-head.html
index d1c34ac7ef..107692c5ee 100644
--- a/scm-ui/ui-overlays/.storybook/preview-head.html
+++ b/scm-ui/ui-core/.storybook/preview-head.html
@@ -23,4 +23,3 @@
-->
-
diff --git a/scm-ui/ui-buttons/.storybook/preview.js b/scm-ui/ui-core/.storybook/preview.js
similarity index 100%
rename from scm-ui/ui-buttons/.storybook/preview.js
rename to scm-ui/ui-core/.storybook/preview.js
diff --git a/scm-ui/ui-buttons/.storybook/withApiProvider.js b/scm-ui/ui-core/.storybook/withApiProvider.js
similarity index 99%
rename from scm-ui/ui-buttons/.storybook/withApiProvider.js
rename to scm-ui/ui-core/.storybook/withApiProvider.js
index 8aa561d39c..4d799d292e 100644
--- a/scm-ui/ui-buttons/.storybook/withApiProvider.js
+++ b/scm-ui/ui-core/.storybook/withApiProvider.js
@@ -21,6 +21,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
+
import * as React from "react";
import { ApiProvider } from "@scm-manager/ui-api";
diff --git a/scm-ui/ui-buttons/docs/introduction.stories.mdx b/scm-ui/ui-core/docs/introduction.stories.mdx
similarity index 100%
rename from scm-ui/ui-buttons/docs/introduction.stories.mdx
rename to scm-ui/ui-core/docs/introduction.stories.mdx
diff --git a/scm-ui/ui-buttons/docs/usage.stories.mdx b/scm-ui/ui-core/docs/usage.stories.mdx
similarity index 100%
rename from scm-ui/ui-buttons/docs/usage.stories.mdx
rename to scm-ui/ui-core/docs/usage.stories.mdx
diff --git a/scm-ui/ui-core/package.json b/scm-ui/ui-core/package.json
new file mode 100644
index 0000000000..6aafb5ab4c
--- /dev/null
+++ b/scm-ui/ui-core/package.json
@@ -0,0 +1,81 @@
+{
+ "name": "@scm-manager/ui-core",
+ "version": "3.0.0-SNAPSHOT",
+ "main": "./src/index.ts",
+ "license": "MIT",
+ "scripts": {
+ "storybook": "start-storybook -p 6006",
+ "build-storybook": "build-storybook"
+ },
+ "peerDependencies": {
+ "react": "^17.0.1",
+ "react-dom": "^17.0.1",
+ "react-router-dom": "^5.3.1",
+ "classnames": "^2.3.1",
+ "react-hook-form": "7",
+ "react-i18next": "11",
+ "react-query": "3",
+ "styled-components": "5"
+ },
+ "dependencies": {
+ "@headlessui/react": "^1.7.15",
+ "@radix-ui/react-radio-group": "^1.1.3",
+ "@radix-ui/react-slot": "^1.0.1",
+ "@radix-ui/react-visually-hidden": "^1.0.3",
+ "@radix-ui/react-dialog": "1.0.4",
+ "@radix-ui/react-dropdown-menu": "2.0.5",
+ "@radix-ui/react-popover": "1.0.6",
+ "@radix-ui/react-tooltip": "1.0.2",
+ "@radix-ui/react-tabs": "^1.0.4",
+ "@radix-ui/react-collapsible": "^1.0.3",
+ "mousetrap": "1.6.5"
+ },
+ "devDependencies": {
+ "@scm-manager/prettier-config": "^2.11.1",
+ "@scm-manager/eslint-config": "^2.17.0",
+ "@scm-manager/tsconfig": "^2.12.0",
+ "@scm-manager/babel-preset": "^2.13.1",
+ "@types/mousetrap": "1.6.5",
+ "@testing-library/react-hooks": "8.0.1",
+ "@testing-library/react": "12.1.5",
+ "@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",
+ "@storybook/addon-a11y": "^6.5.10",
+ "storybook-addon-i18next": "^1.3.0",
+ "storybook-addon-pseudo-states": "^1.15.1",
+ "@storybook/builder-webpack5": "^6.5.10",
+ "@storybook/manager-webpack5": "^6.5.10",
+ "@storybook/react": "^6.5.10",
+ "@storybook/testing-library": "^0.0.13",
+ "@storybook/addon-storyshots-puppeteer": "^6.4.20",
+ "@storybook/addon-storyshots": "^6.4.20",
+ "storybook-addon-mock": "^3.2.0",
+ "storybook-addon-themes": "^6.1.0",
+ "storybook-react-router": "^1.0.8",
+ "mini-css-extract-plugin": "^1.6.2",
+ "html-webpack-plugin": "^5.5.0",
+ "webpack": "5",
+ "@babel/core": "^7.19.0",
+ "i18next": "^19.9.2",
+ "react-i18next": "11",
+ "i18next-fetch-backend": "^2.3.1",
+ "babel-loader": "^8.2.5",
+ "depcheck": "^1.4.3",
+ "jest-extended": "3.1.0"
+ },
+ "prettier": "@scm-manager/prettier-config",
+ "eslintConfig": {
+ "extends": "@scm-manager/eslint-config"
+ },
+ "publishConfig": {
+ "access": "public"
+ },
+ "jest": {
+ "setupFilesAfterEnv": [
+ "jest-extended/all"
+ ]
+ }
+}
diff --git a/scm-ui/ui-buttons/src/Button.stories.tsx b/scm-ui/ui-core/src/base/buttons/Button.stories.tsx
similarity index 100%
rename from scm-ui/ui-buttons/src/Button.stories.tsx
rename to scm-ui/ui-core/src/base/buttons/Button.stories.tsx
diff --git a/scm-ui/ui-buttons/src/Button.test.stories.mdx b/scm-ui/ui-core/src/base/buttons/Button.test.stories.mdx
similarity index 100%
rename from scm-ui/ui-buttons/src/Button.test.stories.mdx
rename to scm-ui/ui-core/src/base/buttons/Button.test.stories.mdx
diff --git a/scm-ui/ui-buttons/src/Button.tsx b/scm-ui/ui-core/src/base/buttons/Button.tsx
similarity index 98%
rename from scm-ui/ui-buttons/src/Button.tsx
rename to scm-ui/ui-core/src/base/buttons/Button.tsx
index 2ae0c17f1f..b66883f405 100644
--- a/scm-ui/ui-buttons/src/Button.tsx
+++ b/scm-ui/ui-core/src/base/buttons/Button.tsx
@@ -25,7 +25,7 @@
import React, { AnchorHTMLAttributes, ButtonHTMLAttributes } from "react";
import { Link as ReactRouterLink, LinkProps as ReactRouterLinkProps } from "react-router-dom";
import classNames from "classnames";
-import { createAttributesForTesting } from "@scm-manager/ui-components";
+import { createAttributesForTesting } from "../helpers";
/**
* @beta
diff --git a/scm-ui/ui-buttons/src/Icon.tsx b/scm-ui/ui-core/src/base/buttons/Icon.tsx
similarity index 100%
rename from scm-ui/ui-buttons/src/Icon.tsx
rename to scm-ui/ui-core/src/base/buttons/Icon.tsx
diff --git a/scm-ui/ui-buttons/src/a11y.test.ts b/scm-ui/ui-core/src/base/buttons/a11y.test.ts
similarity index 100%
rename from scm-ui/ui-buttons/src/a11y.test.ts
rename to scm-ui/ui-core/src/base/buttons/a11y.test.ts
diff --git a/scm-ui/ui-core/src/base/buttons/docs/introduction.stories.mdx b/scm-ui/ui-core/src/base/buttons/docs/introduction.stories.mdx
new file mode 100644
index 0000000000..03a67c26cf
--- /dev/null
+++ b/scm-ui/ui-core/src/base/buttons/docs/introduction.stories.mdx
@@ -0,0 +1,64 @@
+import { Meta } from "@storybook/addon-docs";
+import { Button } from "../";
+
+
+
+# Buttons
+
+The `@scm-manager/ui-core` library provides [atoms](https://atomicdesign.bradfrost.com/chapter-2/#atoms) implemented
+as minimal wrappers around native html elements styled to match the general SCM-Manager aesthetic.
+
+## Components
+
+There are three actionable components available. Styling is consistent amongst them and all have the required `variant` property.
+
+1. [Button](?path=/story/components--button)
+2. [Link Button](?path=/story/components--link-button)
+3. [External Link Button](?path=/story/components--external-link-button)
+
+## Usage
+
+Actionable components serve a dedicated purpose. It is therefore important to know when and how to use them.
+
+### Variants
+
+There are four variants available to each of the three button types, varying in importance.
+
+
+
+
+
Emphasis
+
Button Variant
+
Usage Examples
+
+
+
+
+
Very High
+
+
Destructive actions
+
+
+
High
+
+
Form submit
+
+
+
Normal
+
+
Cancel action in dialog
+
+
+
Low
+
+
Circumstantially relevant action on page with many actionable elements
+
+
+
+
+## Content
+
+Buttons exclusively contain text and no icons. Icons tend to be ambiguous and not always applicable which leads to inconsistent
+and cluttered layouts.
+
+Button text should be short, concise and describe the action performed.
diff --git a/scm-ui/ui-core/src/base/buttons/docs/usage.stories.mdx b/scm-ui/ui-core/src/base/buttons/docs/usage.stories.mdx
new file mode 100644
index 0000000000..cf5d43c41c
--- /dev/null
+++ b/scm-ui/ui-core/src/base/buttons/docs/usage.stories.mdx
@@ -0,0 +1,22 @@
+import { Meta, Story } from "@storybook/addon-docs";
+import { Button } from "../";
+
+
+
+In confirmation dialogs, there are two actions.
+One to cancel the current process and one to confirm it.
+Aborting is always the secondary action, confirmation always the primary.
+Focus is always on the cancelling action.
+
+
+
+
Delete User
+
Do you really want to delete this user ?
+
+
+
+
+
+
diff --git a/scm-ui/ui-buttons/src/image-snapshot.test.ts b/scm-ui/ui-core/src/base/buttons/image-snapshot.test.ts
similarity index 100%
rename from scm-ui/ui-buttons/src/image-snapshot.test.ts
rename to scm-ui/ui-core/src/base/buttons/image-snapshot.test.ts
diff --git a/scm-ui/ui-buttons/src/index.ts b/scm-ui/ui-core/src/base/buttons/index.ts
similarity index 100%
rename from scm-ui/ui-buttons/src/index.ts
rename to scm-ui/ui-core/src/base/buttons/index.ts
diff --git a/scm-ui/ui-forms/src/AddListEntryForm.tsx b/scm-ui/ui-core/src/base/forms/AddListEntryForm.tsx
similarity index 98%
rename from scm-ui/ui-forms/src/AddListEntryForm.tsx
rename to scm-ui/ui-core/src/base/forms/AddListEntryForm.tsx
index c4c130082f..3fe4b0c149 100644
--- a/scm-ui/ui-forms/src/AddListEntryForm.tsx
+++ b/scm-ui/ui-core/src/base/forms/AddListEntryForm.tsx
@@ -26,7 +26,7 @@ import React, { useCallback, useEffect } from "react";
import { ScmFormPathContextProvider, useScmFormPathContext } from "./FormPathContext";
import { ScmFormContextProvider, useScmFormContext } from "./ScmFormContext";
import { DeepPartial, UseFieldArrayReturn, useForm, UseFormReturn } from "react-hook-form";
-import { Button } from "@scm-manager/ui-buttons";
+import { Button } from "../buttons";
import { prefixWithoutIndices } from "./helpers";
import { useScmFormListContext } from "./ScmFormListContext";
import { useTranslation } from "react-i18next";
diff --git a/scm-ui/ui-forms/src/ConfigurationForm.tsx b/scm-ui/ui-core/src/base/forms/ConfigurationForm.tsx
similarity index 97%
rename from scm-ui/ui-forms/src/ConfigurationForm.tsx
rename to scm-ui/ui-core/src/base/forms/ConfigurationForm.tsx
index 09c8adecf6..829a6564db 100644
--- a/scm-ui/ui-forms/src/ConfigurationForm.tsx
+++ b/scm-ui/ui-core/src/base/forms/ConfigurationForm.tsx
@@ -23,7 +23,7 @@
*/
import { useConfigLink } from "@scm-manager/ui-api";
-import { Loading } from "@scm-manager/ui-components";
+import { Loading } from "../misc";
import React, { ComponentProps } from "react";
import { HalRepresentation } from "@scm-manager/ui-types";
import Form from "./Form";
diff --git a/scm-ui/ui-forms/src/Form.stories.tsx b/scm-ui/ui-core/src/base/forms/Form.stories.tsx
similarity index 100%
rename from scm-ui/ui-forms/src/Form.stories.tsx
rename to scm-ui/ui-core/src/base/forms/Form.stories.tsx
diff --git a/scm-ui/ui-forms/src/Form.tsx b/scm-ui/ui-core/src/base/forms/Form.tsx
similarity index 98%
rename from scm-ui/ui-forms/src/Form.tsx
rename to scm-ui/ui-core/src/base/forms/Form.tsx
index e12c29a5ca..0fcc6c0648 100644
--- a/scm-ui/ui-forms/src/Form.tsx
+++ b/scm-ui/ui-core/src/base/forms/Form.tsx
@@ -24,10 +24,11 @@
import React, { FC, useCallback, useEffect, useState } from "react";
import { DeepPartial, SubmitHandler, useForm, UseFormReturn } from "react-hook-form";
-import { ErrorNotification, Level } from "@scm-manager/ui-components";
+import { ErrorNotification } from "../notifications";
+import { Level } from "../misc";
import { ScmFormContextProvider } from "./ScmFormContext";
import { useTranslation } from "react-i18next";
-import { Button } from "@scm-manager/ui-buttons";
+import { Button } from "../buttons";
import styled from "styled-components";
import { setValues } from "./helpers";
diff --git a/scm-ui/ui-forms/src/FormPathContext.tsx b/scm-ui/ui-core/src/base/forms/FormPathContext.tsx
similarity index 100%
rename from scm-ui/ui-forms/src/FormPathContext.tsx
rename to scm-ui/ui-core/src/base/forms/FormPathContext.tsx
diff --git a/scm-ui/ui-forms/src/FormRow.tsx b/scm-ui/ui-core/src/base/forms/FormRow.tsx
similarity index 100%
rename from scm-ui/ui-forms/src/FormRow.tsx
rename to scm-ui/ui-core/src/base/forms/FormRow.tsx
diff --git a/scm-ui/ui-forms/src/ScmFormContext.tsx b/scm-ui/ui-core/src/base/forms/ScmFormContext.tsx
similarity index 100%
rename from scm-ui/ui-forms/src/ScmFormContext.tsx
rename to scm-ui/ui-core/src/base/forms/ScmFormContext.tsx
diff --git a/scm-ui/ui-forms/src/ScmFormListContext.tsx b/scm-ui/ui-core/src/base/forms/ScmFormListContext.tsx
similarity index 100%
rename from scm-ui/ui-forms/src/ScmFormListContext.tsx
rename to scm-ui/ui-core/src/base/forms/ScmFormListContext.tsx
diff --git a/scm-ui/ui-forms/src/base/Control.tsx b/scm-ui/ui-core/src/base/forms/base/Control.tsx
similarity index 100%
rename from scm-ui/ui-forms/src/base/Control.tsx
rename to scm-ui/ui-core/src/base/forms/base/Control.tsx
diff --git a/scm-ui/ui-forms/src/base/Field.tsx b/scm-ui/ui-core/src/base/forms/base/Field.tsx
similarity index 100%
rename from scm-ui/ui-forms/src/base/Field.tsx
rename to scm-ui/ui-core/src/base/forms/base/Field.tsx
diff --git a/scm-ui/ui-forms/src/base/field-message/FieldMessage.tsx b/scm-ui/ui-core/src/base/forms/base/field-message/FieldMessage.tsx
similarity index 100%
rename from scm-ui/ui-forms/src/base/field-message/FieldMessage.tsx
rename to scm-ui/ui-core/src/base/forms/base/field-message/FieldMessage.tsx
diff --git a/scm-ui/ui-forms/src/base/help/Help.tsx b/scm-ui/ui-core/src/base/forms/base/help/Help.tsx
similarity index 96%
rename from scm-ui/ui-forms/src/base/help/Help.tsx
rename to scm-ui/ui-core/src/base/forms/base/help/Help.tsx
index 80b602cfdf..d41f58b6b8 100644
--- a/scm-ui/ui-forms/src/base/help/Help.tsx
+++ b/scm-ui/ui-core/src/base/forms/base/help/Help.tsx
@@ -23,7 +23,7 @@
*/
import React from "react";
-import { Tooltip } from "@scm-manager/ui-overlays";
+import { Tooltip } from "../../../overlays";
type Props = { text?: string; className?: string };
const Help = ({ text, className }: Props) => (
diff --git a/scm-ui/ui-forms/src/base/label/Label.tsx b/scm-ui/ui-core/src/base/forms/base/label/Label.tsx
similarity index 100%
rename from scm-ui/ui-forms/src/base/label/Label.tsx
rename to scm-ui/ui-core/src/base/forms/base/label/Label.tsx
diff --git a/scm-ui/ui-forms/src/checkbox/Checkbox.stories.mdx b/scm-ui/ui-core/src/base/forms/checkbox/Checkbox.stories.mdx
similarity index 100%
rename from scm-ui/ui-forms/src/checkbox/Checkbox.stories.mdx
rename to scm-ui/ui-core/src/base/forms/checkbox/Checkbox.stories.mdx
diff --git a/scm-ui/ui-forms/src/checkbox/Checkbox.tsx b/scm-ui/ui-core/src/base/forms/checkbox/Checkbox.tsx
similarity index 97%
rename from scm-ui/ui-forms/src/checkbox/Checkbox.tsx
rename to scm-ui/ui-core/src/base/forms/checkbox/Checkbox.tsx
index bc6c361859..d01afc9803 100644
--- a/scm-ui/ui-forms/src/checkbox/Checkbox.tsx
+++ b/scm-ui/ui-core/src/base/forms/checkbox/Checkbox.tsx
@@ -23,7 +23,7 @@
*/
import React, { InputHTMLAttributes } from "react";
-import { createAttributesForTesting } from "@scm-manager/ui-components";
+import { createAttributesForTesting } from "../../helpers";
import Help from "../base/help/Help";
import styled from "styled-components";
import classNames from "classnames";
diff --git a/scm-ui/ui-forms/src/checkbox/CheckboxField.tsx b/scm-ui/ui-core/src/base/forms/checkbox/CheckboxField.tsx
similarity index 100%
rename from scm-ui/ui-forms/src/checkbox/CheckboxField.tsx
rename to scm-ui/ui-core/src/base/forms/checkbox/CheckboxField.tsx
diff --git a/scm-ui/ui-forms/src/checkbox/ControlledCheckboxField.stories.mdx b/scm-ui/ui-core/src/base/forms/checkbox/ControlledCheckboxField.stories.mdx
similarity index 100%
rename from scm-ui/ui-forms/src/checkbox/ControlledCheckboxField.stories.mdx
rename to scm-ui/ui-core/src/base/forms/checkbox/ControlledCheckboxField.stories.mdx
diff --git a/scm-ui/ui-forms/src/checkbox/ControlledCheckboxField.tsx b/scm-ui/ui-core/src/base/forms/checkbox/ControlledCheckboxField.tsx
similarity index 100%
rename from scm-ui/ui-forms/src/checkbox/ControlledCheckboxField.tsx
rename to scm-ui/ui-core/src/base/forms/checkbox/ControlledCheckboxField.tsx
diff --git a/scm-ui/ui-forms/src/chip-input/ChipInputField.stories.tsx b/scm-ui/ui-core/src/base/forms/chip-input/ChipInputField.stories.tsx
similarity index 100%
rename from scm-ui/ui-forms/src/chip-input/ChipInputField.stories.tsx
rename to scm-ui/ui-core/src/base/forms/chip-input/ChipInputField.stories.tsx
diff --git a/scm-ui/ui-forms/src/chip-input/ChipInputField.tsx b/scm-ui/ui-core/src/base/forms/chip-input/ChipInputField.tsx
similarity index 95%
rename from scm-ui/ui-forms/src/chip-input/ChipInputField.tsx
rename to scm-ui/ui-core/src/base/forms/chip-input/ChipInputField.tsx
index 7668269c08..23ee53aea0 100644
--- a/scm-ui/ui-forms/src/chip-input/ChipInputField.tsx
+++ b/scm-ui/ui-core/src/base/forms/chip-input/ChipInputField.tsx
@@ -22,8 +22,8 @@
* SOFTWARE.
*/
-import React, { KeyboardEventHandler, PropsWithRef, ReactElement, Ref, RefObject, useCallback } from "react";
-import { createAttributesForTesting, useGeneratedId } from "@scm-manager/ui-components";
+import React, { KeyboardEventHandler, PropsWithRef, ReactElement, Ref, useCallback } from "react";
+import { createAttributesForTesting, useAriaId } from "../../helpers";
import Field from "../base/Field";
import Label from "../base/label/Label";
import Help from "../base/help/Help";
@@ -114,9 +114,9 @@ const ChipInputField = function ChipInputField(
(item) => (createDeleteText ? createDeleteText(item) : t("delete", { item })),
[createDeleteText, t]
);
- const inputId = useGeneratedId(id ?? testId);
- const labelId = useGeneratedId();
- const inputDescriptionId = useGeneratedId();
+ const inputId = useAriaId(id ?? testId);
+ const labelId = useAriaId();
+ const inputDescriptionId = useAriaId();
const variant = error ? "danger" : undefined;
return (
diff --git a/scm-ui/ui-forms/src/chip-input/ControlledChipInputField.tsx b/scm-ui/ui-core/src/base/forms/chip-input/ControlledChipInputField.tsx
similarity index 100%
rename from scm-ui/ui-forms/src/chip-input/ControlledChipInputField.tsx
rename to scm-ui/ui-core/src/base/forms/chip-input/ControlledChipInputField.tsx
diff --git a/scm-ui/ui-forms/src/combobox/Combobox.stories.tsx b/scm-ui/ui-core/src/base/forms/combobox/Combobox.stories.tsx
similarity index 100%
rename from scm-ui/ui-forms/src/combobox/Combobox.stories.tsx
rename to scm-ui/ui-core/src/base/forms/combobox/Combobox.stories.tsx
diff --git a/scm-ui/ui-forms/src/combobox/Combobox.tsx b/scm-ui/ui-core/src/base/forms/combobox/Combobox.tsx
similarity index 98%
rename from scm-ui/ui-forms/src/combobox/Combobox.tsx
rename to scm-ui/ui-core/src/base/forms/combobox/Combobox.tsx
index 688884c4d5..340dd06c0a 100644
--- a/scm-ui/ui-forms/src/combobox/Combobox.tsx
+++ b/scm-ui/ui-core/src/base/forms/combobox/Combobox.tsx
@@ -36,7 +36,7 @@ import { Combobox as HeadlessCombobox } from "@headlessui/react";
import classNames from "classnames";
import styled from "styled-components";
import { withForwardRef } from "../helpers";
-import { createAttributesForTesting } from "@scm-manager/ui-components";
+import { createAttributesForTesting } from "../../helpers";
import { Option } from "@scm-manager/ui-types";
const OptionsWrapper = styled(HeadlessCombobox.Options).attrs({
diff --git a/scm-ui/ui-forms/src/combobox/ComboboxField.tsx b/scm-ui/ui-core/src/base/forms/combobox/ComboboxField.tsx
similarity index 95%
rename from scm-ui/ui-forms/src/combobox/ComboboxField.tsx
rename to scm-ui/ui-core/src/base/forms/combobox/ComboboxField.tsx
index 479f019465..b48602f42a 100644
--- a/scm-ui/ui-forms/src/combobox/ComboboxField.tsx
+++ b/scm-ui/ui-core/src/base/forms/combobox/ComboboxField.tsx
@@ -26,7 +26,7 @@ import Field from "../base/Field";
import Label from "../base/label/Label";
import Help from "../base/help/Help";
import React from "react";
-import { useGeneratedId } from "@scm-manager/ui-components";
+import { useAriaId } from "../../helpers";
import { withForwardRef } from "../helpers";
import Combobox, { ComboboxProps } from "./Combobox";
import classNames from "classnames";
@@ -46,7 +46,7 @@ const ComboboxField = function ComboboxField(
}: ComboboxProps & { label: string; helpText?: string; error?: string; isLoading?: boolean },
ref: React.ForwardedRef
) {
- const labelId = useGeneratedId();
+ const labelId = useAriaId();
return (