diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9b550f94..d8b3b5e2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -11,9 +11,15 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p
- ``
- component for hiding elements in specific media
- ``
- - force children to get displayed as inline content
+ - force children to get displayed as inline content
+- ``
+ - simple placeholder element that can be used to display info about missing data
- ``
- - `useOnly` property: specify if only parts of the content should be used for the shortened preview, this property replaces `firstNonEmptyLineOnly`
+ - `useOnly` property: specify if only parts of the content should be used for the shortened preview, this property replaces `firstNonEmptyLineOnly`
+- ``
+ - `forceInline` property: force inline rendering
+- ``:
+ - `isValidNewOption` property: Checks if an input string is or can be turned into a valid new option.
### Fixed
@@ -21,7 +27,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p
- create more whitespace inside `small` tag
- reduce visual impact of border
- ``
- - take Markdown rendering into account before testing the maximum preview length
+ - take Markdown rendering into account before testing the maximum preview length
- ``
- header-menu items are vertically centered now
@@ -41,7 +47,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p
### Deprecated
- ``
- - `firstNonEmptyLineOnly` will be removed, is replaced by `useOnly="firstNonEmptyLine"`
+ - `firstNonEmptyLineOnly` will be removed, is replaced by `useOnly="firstNonEmptyLine"`
## [25.0.0] - 2025-12-01
diff --git a/src/cmem/ContentBlobToggler/ContentBlobToggler.tsx b/src/cmem/ContentBlobToggler/ContentBlobToggler.tsx
index 26b214ab..91b9a06c 100644
--- a/src/cmem/ContentBlobToggler/ContentBlobToggler.tsx
+++ b/src/cmem/ContentBlobToggler/ContentBlobToggler.tsx
@@ -1,6 +1,6 @@
-import React, { useState } from "react";
+import React, { useState} from "react";
-import { Link, Spacing } from "../../index";
+import { Link, Spacing, InlineText } from "../../index";
export interface ContentBlobTogglerProps extends React.HTMLAttributes {
/**
@@ -31,6 +31,10 @@ export interface ContentBlobTogglerProps extends React.HTMLAttributes
{!isExtended ? (
<>
@@ -76,7 +81,7 @@ export function ContentBlobToggler({
{fullviewContent}
{enableToggler && (
-
+ {forceInline ? <>{" "}> : }
);
+
+ return forceInline ? {tooglerDisplay} : tooglerDisplay;
}
diff --git a/src/cmem/ContentBlobToggler/StringPreviewContentBlobToggler.tsx b/src/cmem/ContentBlobToggler/StringPreviewContentBlobToggler.tsx
index e5ec7a79..08c19a43 100644
--- a/src/cmem/ContentBlobToggler/StringPreviewContentBlobToggler.tsx
+++ b/src/cmem/ContentBlobToggler/StringPreviewContentBlobToggler.tsx
@@ -54,6 +54,7 @@ export function StringPreviewContentBlobToggler({
allowedHtmlElementsInPreview,
noTogglerContentSuffix,
firstNonEmptyLineOnly,
+ ...otherContentBlobTogglerProps
}: StringPreviewContentBlobTogglerProps) {
// need to test `firstNonEmptyLineOnly` until property is removed
const useOnlyTest: StringPreviewContentBlobTogglerProps["useOnly"] = firstNonEmptyLineOnly
@@ -105,6 +106,7 @@ export function StringPreviewContentBlobToggler({
fullviewContent={fullviewContent}
startExtended={startExtended}
enableToggler={enableToggler}
+ {...otherContentBlobTogglerProps}
/>
);
}
diff --git a/src/components/MultiSelect/MultiSelect.tsx b/src/components/MultiSelect/MultiSelect.tsx
index 3685ed86..b0e0bd5f 100644
--- a/src/components/MultiSelect/MultiSelect.tsx
+++ b/src/components/MultiSelect/MultiSelect.tsx
@@ -70,9 +70,11 @@ interface MultiSuggestFieldCommonProps
*/
newItemCreationText?: string;
/**
- * Allows to creates new item from a given query. If this is not provided then no new items can be created.
+ * Allows to create new item from a given query. If this is not provided then no new items can be created.
*/
createNewItemFromQuery?: (query: string) => T;
+ /** Validates if a new item can be created from the current query string. */
+ isValidNewOption?: (query: string) => boolean;
/**
* Items that were newly created and not taken from the list will be post-fixed with this string.
*/
@@ -159,6 +161,7 @@ export function MultiSuggestField({
newItemPostfix = " (new item)",
disabled,
createNewItemFromQuery,
+ isValidNewOption,
requestDelay = 0,
clearQueryOnSelection = false,
className,
@@ -387,7 +390,9 @@ export function MultiSuggestField({
*/
const handleOnKeyUp = (event: React.KeyboardEvent) => {
if (event.key === "Enter" && !filteredItems.length && !!requestState.current.query && createNewItemFromQuery) {
- createNewItem(requestState.current.query);
+ if(!isValidNewOption || isValidNewOption(requestState.current.query)) {
+ createNewItem(requestState.current.query);
+ }
}
inputRef.current?.focus();
};
@@ -403,7 +408,11 @@ export function MultiSuggestField({
if (focusedItem) {
onItemSelect(focusedItem);
} else {
- onItemSelect(createNewItem(requestState.current.query));
+ if (!isValidNewOption || isValidNewOption(requestState.current.query)) {
+ onItemSelect(createNewItem(requestState.current.query));
+ } else {
+ return
+ }
}
requestState.current.query = "";
setTimeout(() => inputRef.current?.focus());
@@ -418,7 +427,7 @@ export function MultiSuggestField({
* @returns
*/
const newItemRenderer = (label: string, active: boolean, handleClick: React.MouseEventHandler) => {
- if (!createNewItemFromQuery) return undefined;
+ if (!createNewItemFromQuery || isValidNewOption && !isValidNewOption(label)) return undefined;
const clickHandler = (e: React.MouseEvent) => {
createNewItem(label);
handleClick(e);
diff --git a/src/components/NotAvailable/NotAvailable.stories.tsx b/src/components/NotAvailable/NotAvailable.stories.tsx
new file mode 100644
index 00000000..29dde1e3
--- /dev/null
+++ b/src/components/NotAvailable/NotAvailable.stories.tsx
@@ -0,0 +1,15 @@
+import React from "react";
+import { Meta, StoryFn } from "@storybook/react";
+
+import { NotAvailable } from "../../../index";
+
+export default {
+ title: "Components/NotAvailable",
+ component: NotAvailable,
+ argTypes: {},
+} as Meta;
+
+const TemplateFull: StoryFn = (args) => ;
+
+export const Default = TemplateFull.bind({});
+Default.args = {};
diff --git a/src/components/NotAvailable/NotAvailable.tsx b/src/components/NotAvailable/NotAvailable.tsx
new file mode 100644
index 00000000..47b14adb
--- /dev/null
+++ b/src/components/NotAvailable/NotAvailable.tsx
@@ -0,0 +1,70 @@
+import React from "react";
+
+import {
+ CLASSPREFIX as eccgui,
+ Tag,
+ TagProps,
+ Tooltip,
+ TooltipProps,
+} from "../../../index";
+import { TestableComponent } from "../interfaces";
+export interface NotAvailableProps extends TestableComponent, Pick, Pick {
+ /**
+ * Text displayed by the element.
+ */
+ label?: TagProps["children"];
+ /**
+ * Add a tooltip to the element.
+ * You need to set an empty string `""` to remove it.
+ */
+ tooltip?: TooltipProps["content"];
+ /**
+ * Specify the display of the used `Tag` component.
+ */
+ tagProps?: Omit;
+ /**
+ * Specify the display of the used `Tooltip` component.
+ */
+ tooltipProps?: Omit;
+ /**
+ * Do not use the `Tag` component for the display.
+ * The `intent` state can be displayed only on the tooltip then.
+ */
+ noTag?: boolean;
+}
+
+/**
+ * Simple placeholder element that can be used to display info about missing data.
+ */
+export const NotAvailable = ({
+ label = "n/a",
+ tooltip = "not available",
+ icon,
+ intent,
+ tagProps,
+ tooltipProps,
+ className,
+ noTag = false,
+ ...otherProps
+}: NotAvailableProps) => {
+ const defaultTagProps : TagProps = { icon, intent, emphasis: "weaker", className: `${eccgui}-notavailable` + className ? ` ${className}` : "" };
+ const naElement = noTag === false ? (
+
+ { label ?? "n/a"}
+
+ ) : <>{ label ?? "n/a"}>;
+ const defaultTooltipProps : TooltipProps = {
+ children: naElement,
+ content: tooltip,
+ intent,
+ addIndicator: noTag,
+ };
+
+ return tooltip ? : naElement;
+};
+
+export default NotAvailable;
diff --git a/src/components/index.ts b/src/components/index.ts
index 6f7fdf95..5e1c496d 100644
--- a/src/components/index.ts
+++ b/src/components/index.ts
@@ -23,6 +23,7 @@ export * from "./Link/Link";
export * from "./List/List";
export * from "./Menu";
export * from "./MultiSuggestField";
+export * from "./NotAvailable/NotAvailable";
export * from "./Notification";
export * from "./OverviewItem";
export * from "./Pagination/Pagination";