diff --git a/CHANGELOG.md b/CHANGELOG.md
index fa3e5e83..f0e8256f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,17 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p
## [Unreleased]
+### Added
+
+- ``
+ - visualize the usage of tabulator chars by background color and arrow symbol
+ - new `tabIntentSize`, `tabIntentStyle`, `tabForceSpaceForModes` properties to give better control over tabulator usage
+
+### Fixed
+
+- ``
+ - images representing SVG without `width` property on their root element are displayed with a minimal forced dimension to prevent that they are hidden in some browsers
+
## [23.4.1] - 2024-02-08
### Fixed
diff --git a/package.json b/package.json
index aae5603f..13dd327b 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
"name": "@eccenca/gui-elements",
"description": "GUI elements based on other libraries, usable in React application, written in Typescript.",
- "version": "23.4.1",
+ "version": "23.5.0-rc.0",
"license": "Apache-2.0",
"homepage": "https://github.com/eccenca/gui-elements",
"bugs": "https://github.com/eccenca/gui-elements/issues",
diff --git a/src/components/Depiction/depiction.scss b/src/components/Depiction/depiction.scss
index 024dce33..f991fbd8 100644
--- a/src/components/Depiction/depiction.scss
+++ b/src/components/Depiction/depiction.scss
@@ -3,16 +3,14 @@ $eccgui-size-depiction-height-small: mini-units(6) !default;
$eccgui-size-depiction-height-medium: mini-units(12) !default;
$eccgui-size-depiction-height-large: mini-units(24) !default;
$eccgui-size-depiction-height-xlarge: mini-units(48) !default;
-
$eccgui-color-depiction-background: $eccgui-color-workspace-text !default;
$eccgui-color-depiction-text: $eccgui-color-workspace-background !default;
$eccgui-size-depiction-border-radius: $pt-border-radius !default;
-
.#{$eccgui}-depiction {
- max-width: 100%;
- display: inline-flex;
position: relative;
+ display: inline-flex;
+ max-width: 100%;
.#{$eccgui}-overviewitem__item > & {
flex-grow: 0;
@@ -26,12 +24,13 @@ $eccgui-size-depiction-border-radius: $pt-border-radius !default;
}
.#{$eccgui}-depiction__image {
- overflow: hidden;
max-width: 100%;
max-height: 100%;
+ overflow: hidden;
border-radius: $eccgui-size-depiction-border-radius;
- img, svg {
+ img,
+ svg {
width: 100%;
height: 100%;
}
@@ -57,10 +56,22 @@ $eccgui-size-depiction-border-radius: $pt-border-radius !default;
.#{$eccgui}-depiction__image--ratio-source {
aspect-ratio: auto;
- img, svg {
+ img,
+ svg {
max-width: 100%;
max-height: 100%;
}
+
+ /**
+ * SVG images without width property on their SVG root are not (specific: using a width of 0px) displayed by some browsers (e.g. Firefox or Brave).
+ * This might be technically correct but to the user it looks like a bug and is not expected by them.
+ * We workaround this "problem" by adding minimal dimensions to images with an SVG source.
+ */
+ img[src^="data:image/svg"],
+ img[src*=".svg"] {
+ min-width: $eccgui-size-depiction-height-tiny;
+ min-height: $eccgui-size-depiction-height-tiny;
+ }
}
.#{$eccgui}-depiction__image--ratio-1to1 {
@@ -68,19 +79,22 @@ $eccgui-size-depiction-border-radius: $pt-border-radius !default;
}
.#{$eccgui}-depiction__image--contain-sizing {
- img, svg {
+ img,
+ svg {
object-fit: contain;
}
}
.#{$eccgui}-depiction__image--cover-sizing {
- img, svg {
+ img,
+ svg {
object-fit: cover;
}
}
.#{$eccgui}-depiction__image--stretch-sizing {
- img, svg {
+ img,
+ svg {
object-fit: fill;
}
}
@@ -153,8 +167,8 @@ $eccgui-size-depiction-border-radius: $pt-border-radius !default;
--#{$eccgui}-depiction-color: #{$eccgui-color-depiction-background};
}
.#{$eccgui}-depiction__image--color-config {
- background: var(--#{$eccgui}-depiction-background);
color: var(--#{$eccgui}-depiction-color);
+ background: var(--#{$eccgui}-depiction-background);
/*
Lead to more problems, even with our Carbon icons, that it "heals" unknown SVGs
@@ -166,11 +180,11 @@ $eccgui-size-depiction-border-radius: $pt-border-radius !default;
}
.#{$eccgui}-depiction__image--hasborder {
- border: 1px solid currentColor;
+ border: 1px solid currentcolor;
}
.#{$eccgui}-depiction__caption--none,
- .#{$eccgui}-depiction__caption--tooltip {
+.#{$eccgui}-depiction__caption--tooltip {
position: fixed;
left: -5000rem;
}
diff --git a/src/components/Depiction/stories/Depiction.stories.tsx b/src/components/Depiction/stories/Depiction.stories.tsx
index 257e1b72..bc5d13aa 100644
--- a/src/components/Depiction/stories/Depiction.stories.tsx
+++ b/src/components/Depiction/stories/Depiction.stories.tsx
@@ -1,19 +1,25 @@
import React from "react";
-import { ComponentStory, ComponentMeta } from "@storybook/react";
import { LogoReact } from "@carbon/icons-react";
+import { Meta, StoryFn } from "@storybook/react";
+
import { Badge, Depiction, Icon, TestIcon } from "../../../index";
+
import canonicalIcons from "./../../Icon/canonicalIconNames";
-import png16to9 from "./test-16to9.png";
+import { Svg9to16 } from "./test-9to16";
import png9to16 from "./test-9to16.png";
-import svg16to9 from "./test-16to9.svg";
import svg9to16 from "./test-9to16.svg";
-import svg16to9base64 from "./test-16to9.tobase64.svg";
import svg9to16base64 from "./test-9to16.tobase64.svg";
import { Svg16to9 } from "./test-16to9";
-import { Svg9to16 } from "./test-9to16";
+import png16to9 from "./test-16to9.png";
+import svg16to9 from "./test-16to9.svg";
+import svg16to9base64 from "./test-16to9.tobase64.svg";
+import svgDimensionless from "./test-dimensionless.svg";
+import svgDimensionlessBase64 from "./test-dimensionless.tobase64.svg";
const allIcons = new Map([
- ...Object.keys(canonicalIcons).map((keyId) => { return [`Icon: ${keyId}`, ] })
+ ...Object.keys(canonicalIcons).map((keyId) => {
+ return [`Icon: ${keyId}`, ];
+ }),
]);
const exampleImages = {
@@ -25,18 +31,28 @@ const exampleImages = {
"SVG 9:16 as Base64": ,
"SVG 16:9 as React element": ,
"SVG 9:16 as React element": ,
- // "PNG 16:9 as Base64": ,
- // "SVG 16:9 as Base64": ,
+ "SVG without known width/height dimensions": ,
+ "SVG without known width/height as Base64": ,
"Test icon": ,
...Object.fromEntries(allIcons),
};
const exampleBadges = {
"No badge": undefined,
- "Text badge (small, danger, bottom-right)": Problem occured!,
- "Icon badge (accent, inline, bottom-right)": ,
- "Number badge (large, info, top-right)": ,
-}
+ "Text badge (small, danger, bottom-right)": (
+
+ Problem occured!
+
+ ),
+ "Icon badge (accent, inline, bottom-right)": (
+
+
+
+ ),
+ "Number badge (large, info, top-right)": (
+
+ ),
+};
export default {
title: "Components/Depiction",
@@ -56,14 +72,12 @@ export default {
mapping: exampleBadges,
},
},
-} as ComponentMeta;
+} as Meta;
-const TemplateFull: ComponentStory = (args) => (
-
-);
+const TemplateFull: StoryFn = (args) => ;
export const FullExample = TemplateFull.bind({});
FullExample.args = {
image: ,
- caption: "This is a test description for the image."
+ caption: "This is a test description for the image.",
};
diff --git a/src/components/Depiction/stories/test-dimensionless.svg b/src/components/Depiction/stories/test-dimensionless.svg
new file mode 100644
index 00000000..74f51ec9
--- /dev/null
+++ b/src/components/Depiction/stories/test-dimensionless.svg
@@ -0,0 +1,41 @@
+
+
+
+
diff --git a/src/components/Depiction/stories/test-dimensionless.tobase64.svg b/src/components/Depiction/stories/test-dimensionless.tobase64.svg
new file mode 100644
index 00000000..74f51ec9
--- /dev/null
+++ b/src/components/Depiction/stories/test-dimensionless.tobase64.svg
@@ -0,0 +1,41 @@
+
+
+
+
diff --git a/src/extensions/codemirror/CodeMirror.tsx b/src/extensions/codemirror/CodeMirror.tsx
index 19ec2f55..222e5c52 100644
--- a/src/extensions/codemirror/CodeMirror.tsx
+++ b/src/extensions/codemirror/CodeMirror.tsx
@@ -66,6 +66,22 @@ export interface CodeEditorProps {
wrapLines?: boolean;
outerDivAttributes?: Partial>;
+
+ /**
+ * Size in spaces that is used for a tabulator key.
+ */
+ tabIntentSize?: number;
+
+ /**
+ * Set the char type that is used for the tabulator key.
+ * If set to `space` the a number of `tabIntentSize` spaces is used instead of a tab.
+ */
+ tabIntentStyle?: "tab" | "space";
+
+ /**
+ * For some modes an indent style with `space` can be forced, even if `tabIntentStyle="tab"` is set.
+ */
+ tabForceSpaceForModes?: SupportedCodeEditorModes[];
}
/**
@@ -82,6 +98,9 @@ export const CodeEditor = ({
height,
wrapLines = false,
outerDivAttributes,
+ tabIntentSize = 2,
+ tabIntentStyle = "tab",
+ tabForceSpaceForModes = ["python", "yaml"],
}: CodeEditorProps) => {
const domRef = useRef(null);
@@ -90,9 +109,16 @@ export const CodeEditor = ({
mode: convertMode(mode),
lineWrapping: wrapLines,
lineNumbers: !preventLineNumbers,
- tabSize: 2,
+ tabSize: tabIntentSize,
+ indentUnit: tabIntentSize,
+ indentWithTabs: tabIntentStyle === "tab" && !(tabForceSpaceForModes ?? []).includes(mode),
theme: "xq-light",
readOnly: readOnly,
+ extraKeys: {
+ Tab: function (cm) {
+ cm.execCommand(cm.getOption("indentWithTabs") ? "insertTab" : "insertSoftTab");
+ },
+ },
});
editorInstance.on("change", (api) => {
diff --git a/src/extensions/codemirror/_codemirror.scss b/src/extensions/codemirror/_codemirror.scss
index 704e34eb..36c3d60a 100644
--- a/src/extensions/codemirror/_codemirror.scss
+++ b/src/extensions/codemirror/_codemirror.scss
@@ -7,9 +7,9 @@
max-width: 100%;
.CodeMirror {
+ height: 290px;
clip-path: unset !important; // we may check later why they set inset(0) now
border-radius: $pt-border-radius;
- height: 290px;
// get them a "border" like input boxes from blueprintjs
box-shadow: input-transition-shadow($input-shadow-color-focus), $pt-input-box-shadow;
@@ -54,6 +54,20 @@
.CodeMirror-sizer {
border-right-width: $eccgui-size-inline-whitespace !important;
}
+
+ .cm-tab {
+ position: relative;
+
+ // mark tabulator chars
+ background-color: $eccgui-color-info-background;
+
+ &::after {
+ position: absolute;
+ left: 10%;
+ color: rgba($eccgui-color-workspace-text, $eccgui-opacity-muted);
+ content: "⇥";
+ }
+ }
}
}