@hitachivantara/uikit-react-pentaho 0.4.8 → 0.5.0
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/dist/cjs/Canvas/ToolbarTabs/ToolbarTabEditor.cjs +6 -2
- package/dist/cjs/Canvas/ToolbarTabs/ToolbarTabs.cjs +10 -8
- package/dist/cjs/Canvas/ToolbarTabs/ToolbarTabs.styles.cjs +3 -2
- package/dist/esm/Canvas/ToolbarTabs/ToolbarTabEditor.js +6 -2
- package/dist/esm/Canvas/ToolbarTabs/ToolbarTabEditor.js.map +1 -1
- package/dist/esm/Canvas/ToolbarTabs/ToolbarTabs.js +10 -8
- package/dist/esm/Canvas/ToolbarTabs/ToolbarTabs.js.map +1 -1
- package/dist/esm/Canvas/ToolbarTabs/ToolbarTabs.styles.js +3 -2
- package/dist/esm/Canvas/ToolbarTabs/ToolbarTabs.styles.js.map +1 -1
- package/dist/types/index.d.ts +7 -3
- package/package.json +5 -5
|
@@ -53,6 +53,7 @@ const { staticClasses, useClasses } = uikitReactCore.createClasses(
|
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
55
|
);
|
|
56
|
+
const sanitize = (value) => value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
56
57
|
const ToolbarTabEditor = ({
|
|
57
58
|
id,
|
|
58
59
|
className,
|
|
@@ -70,7 +71,10 @@ const ToolbarTabEditor = ({
|
|
|
70
71
|
}) => {
|
|
71
72
|
const { cx, classes } = useClasses(classesProp);
|
|
72
73
|
const contentEditableRef = react.useRef(null);
|
|
73
|
-
const [value, setValue] = uikitReactCore.useControlled(
|
|
74
|
+
const [value, setValue] = uikitReactCore.useControlled(
|
|
75
|
+
valueProp ? sanitize(valueProp) : valueProp,
|
|
76
|
+
defaultValueProp ? sanitize(defaultValueProp) : defaultValueProp
|
|
77
|
+
);
|
|
74
78
|
const [cachedValue, setCachedValue] = react.useState(value);
|
|
75
79
|
const [isEditing, setIsEditing] = uikitReactCore.useControlled(editProp, false);
|
|
76
80
|
const moveCursorToEnd = () => {
|
|
@@ -97,7 +101,7 @@ const ToolbarTabEditor = ({
|
|
|
97
101
|
if (isEditing) moveCursorToEnd();
|
|
98
102
|
}, [isEditing, value]);
|
|
99
103
|
const handleInput = (event) => {
|
|
100
|
-
const newValue = event.target.
|
|
104
|
+
const newValue = sanitize(event.target.textContent) || "";
|
|
101
105
|
setValue(newValue);
|
|
102
106
|
onInputProp?.(event);
|
|
103
107
|
onChangeProp?.(event, newValue);
|
|
@@ -21,7 +21,8 @@ const HvCanvasToolbarTabs = react.forwardRef((props, ref) => {
|
|
|
21
21
|
className,
|
|
22
22
|
selectedTabId: selectedTabIdProp,
|
|
23
23
|
icon: iconProp,
|
|
24
|
-
|
|
24
|
+
disableTabEdit = false,
|
|
25
|
+
hideCreateNew = false,
|
|
25
26
|
tabs: tabsProp,
|
|
26
27
|
defaultTabs: defaultTabsProp = [],
|
|
27
28
|
labels: labelsProp,
|
|
@@ -77,8 +78,8 @@ const HvCanvasToolbarTabs = react.forwardRef((props, ref) => {
|
|
|
77
78
|
}
|
|
78
79
|
handleChangeTabs(event, newTabs);
|
|
79
80
|
};
|
|
80
|
-
const handleKeyDownTab = (event, tabId) => {
|
|
81
|
-
if (uikitReactCore.isKey(event, "Delete") || uikitReactCore.isKey(event, "Backspace")) {
|
|
81
|
+
const handleKeyDownTab = (event, tabId, removable) => {
|
|
82
|
+
if (removable && (uikitReactCore.isKey(event, "Delete") || uikitReactCore.isKey(event, "Backspace"))) {
|
|
82
83
|
handleDeleteTab(event, tabId);
|
|
83
84
|
event.stopPropagation();
|
|
84
85
|
} else if (uikitReactCore.isKey(event, "Enter")) {
|
|
@@ -143,6 +144,7 @@ const HvCanvasToolbarTabs = react.forwardRef((props, ref) => {
|
|
|
143
144
|
onChange: handleChangeSelectedTab,
|
|
144
145
|
children: visibleTabs.map((tab, index) => {
|
|
145
146
|
const btnSelected = selectedTab === tab.id;
|
|
147
|
+
const removable = !tab.fixed;
|
|
146
148
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
147
149
|
PanelTab.HvCanvasPanelTab,
|
|
148
150
|
{
|
|
@@ -152,10 +154,10 @@ const HvCanvasToolbarTabs = react.forwardRef((props, ref) => {
|
|
|
152
154
|
id: String(tab.id),
|
|
153
155
|
className: classes.tab,
|
|
154
156
|
value: tab.id,
|
|
155
|
-
onKeyDown: (event) => handleKeyDownTab(event, tab.id),
|
|
157
|
+
onKeyDown: (event) => handleKeyDownTab(event, tab.id, removable),
|
|
156
158
|
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: classes.tabContent, children: [
|
|
157
159
|
tab.icon && /* @__PURE__ */ jsxRuntime.jsx("div", { className: classes.tabIconContainer, children: tab.icon }),
|
|
158
|
-
!btnSelected ||
|
|
160
|
+
!btnSelected || disableTabEdit ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
159
161
|
uikitReactCore.HvOverflowTooltip,
|
|
160
162
|
{
|
|
161
163
|
classes: {
|
|
@@ -177,11 +179,11 @@ const HvCanvasToolbarTabs = react.forwardRef((props, ref) => {
|
|
|
177
179
|
onKeyDown: (e) => e.stopPropagation()
|
|
178
180
|
}
|
|
179
181
|
),
|
|
180
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: classes.closeIconContainer, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
182
|
+
removable && /* @__PURE__ */ jsxRuntime.jsx("div", { className: classes.closeIconContainer, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
181
183
|
uikitReactIcons.CloseXS,
|
|
182
184
|
{
|
|
183
185
|
"aria-hidden": true,
|
|
184
|
-
|
|
186
|
+
size: "xs",
|
|
185
187
|
onClick: (event) => {
|
|
186
188
|
handleDeleteTab(event, tab.id);
|
|
187
189
|
event.stopPropagation();
|
|
@@ -212,7 +214,7 @@ const HvCanvasToolbarTabs = react.forwardRef((props, ref) => {
|
|
|
212
214
|
] }),
|
|
213
215
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { ref: actionsRef, className: classes.actionsContainer, children: [
|
|
214
216
|
children,
|
|
215
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
217
|
+
!hideCreateNew && /* @__PURE__ */ jsxRuntime.jsx(
|
|
216
218
|
uikitReactCore.HvButton,
|
|
217
219
|
{
|
|
218
220
|
variant: "primaryGhost",
|
|
@@ -10,7 +10,7 @@ const TAB_HEIGHT = 32;
|
|
|
10
10
|
const CLOSE_ICON_SIZE = 32;
|
|
11
11
|
const TAB_ICON_SIZE = 16;
|
|
12
12
|
const TAB_PADDING = uikitReactCore.theme.space.xs;
|
|
13
|
-
const TAB_COLOR = uikitReactCore.theme.
|
|
13
|
+
const TAB_COLOR = `color-mix(in srgb, ${uikitReactCore.theme.colors.pp.primaryDimmed} 50%, ${uikitReactCore.theme.colors.pp.dimmer})`;
|
|
14
14
|
const { staticClasses, useClasses } = uikitReactCore.createClasses(
|
|
15
15
|
"HvCanvasToolbarTabs",
|
|
16
16
|
{
|
|
@@ -22,7 +22,8 @@ const { staticClasses, useClasses } = uikitReactCore.createClasses(
|
|
|
22
22
|
backgroundColor: uikitReactCore.theme.colors.atmo1,
|
|
23
23
|
boxShadow: uikitReactCore.theme.colors.shadow,
|
|
24
24
|
borderRadius: `0px 0px ${uikitReactCore.theme.radii.base} ${uikitReactCore.theme.radii.base}`,
|
|
25
|
-
transition: "width 0.3s ease"
|
|
25
|
+
transition: "width 0.3s ease",
|
|
26
|
+
height: TAB_HEIGHT
|
|
26
27
|
},
|
|
27
28
|
tabsContainer: {
|
|
28
29
|
display: "flex"
|
|
@@ -51,6 +51,7 @@ const { staticClasses, useClasses } = createClasses(
|
|
|
51
51
|
}
|
|
52
52
|
}
|
|
53
53
|
);
|
|
54
|
+
const sanitize = (value) => value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
54
55
|
const ToolbarTabEditor = ({
|
|
55
56
|
id,
|
|
56
57
|
className,
|
|
@@ -68,7 +69,10 @@ const ToolbarTabEditor = ({
|
|
|
68
69
|
}) => {
|
|
69
70
|
const { cx, classes } = useClasses(classesProp);
|
|
70
71
|
const contentEditableRef = useRef(null);
|
|
71
|
-
const [value, setValue] = useControlled(
|
|
72
|
+
const [value, setValue] = useControlled(
|
|
73
|
+
valueProp ? sanitize(valueProp) : valueProp,
|
|
74
|
+
defaultValueProp ? sanitize(defaultValueProp) : defaultValueProp
|
|
75
|
+
);
|
|
72
76
|
const [cachedValue, setCachedValue] = useState(value);
|
|
73
77
|
const [isEditing, setIsEditing] = useControlled(editProp, false);
|
|
74
78
|
const moveCursorToEnd = () => {
|
|
@@ -95,7 +99,7 @@ const ToolbarTabEditor = ({
|
|
|
95
99
|
if (isEditing) moveCursorToEnd();
|
|
96
100
|
}, [isEditing, value]);
|
|
97
101
|
const handleInput = (event) => {
|
|
98
|
-
const newValue = event.target.
|
|
102
|
+
const newValue = sanitize(event.target.textContent) || "";
|
|
99
103
|
setValue(newValue);
|
|
100
104
|
onInputProp?.(event);
|
|
101
105
|
onChangeProp?.(event, newValue);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ToolbarTabEditor.js","sources":["../../../../src/Canvas/ToolbarTabs/ToolbarTabEditor.tsx"],"sourcesContent":["import { useLayoutEffect, useRef, useState } from \"react\";\nimport {\n createClasses,\n ExtractNames,\n HvTypography,\n HvTypographyProps,\n isKey,\n theme,\n useControlled,\n} from \"@hitachivantara/uikit-react-core\";\nimport { Edit } from \"@hitachivantara/uikit-react-icons\";\n\n// TODO - Extract component in the future: when we have more specs and/or is used in other components\n\nconst { staticClasses, useClasses } = createClasses(\n \"HvCanvasToolbarTabs-editor\",\n {\n root: {\n position: \"relative\",\n display: \"flex\",\n width: \"100%\",\n overflow: \"hidden\",\n \"&:has($label:hover:not($edit))\": {\n color: theme.colors.secondary_80,\n \"& $editIcon\": { visibility: \"visible\" },\n },\n },\n edit: {\n color: theme.colors.secondary_80,\n borderColor: \"currentColor\",\n backgroundColor: theme.colors.atmo1,\n cursor: \"text\",\n },\n label: {\n width: \"100%\",\n boxSizing: \"border-box\",\n border: \"1px solid transparent\",\n borderRadius: theme.radii.base,\n padding: theme.spacing(0, \"sm\", 0, \"xs\"),\n textAlign: \"start\",\n whiteSpace: \"nowrap\",\n overflow: \"hidden\",\n outline: \"none\",\n \"&:not($edit)\": {\n textOverflow: \"ellipsis\",\n },\n \"&:hover:not($edit)\": {\n color: theme.colors.secondary_80,\n borderColor: theme.colors.containerBackgroundHover,\n backgroundColor: theme.colors.containerBackgroundHover,\n },\n },\n editIcon: {\n position: \"absolute\",\n right: theme.spacing(0.5),\n top: 4,\n width: 16,\n height: 16,\n visibility: \"hidden\",\n pointerEvents: \"none\",\n },\n },\n);\n\nexport { staticClasses as toolbarTabEditorClasses };\n\ntype ToolbarTabEditorClasses = ExtractNames<typeof useClasses>;\n\ninterface ToolbarTabEditorProps\n extends Omit<HvTypographyProps, \"classes\" | \"onBlur\" | \"onChange\"> {\n /** The value of the component. When used, the component has to be controlled. */\n value?: string;\n /** The default value of the component. */\n defaultValue?: string;\n /** Whether the editor is in edit mode. When used, the prop has to be controlled. */\n edit?: boolean;\n /** A Jss Object used to override or extend the styles applied. */\n classes?: ToolbarTabEditorClasses;\n /** Called the field is blurred. */\n onBlur?: (\n event: React.FocusEvent<Element> | React.KeyboardEvent<Element>,\n value: string,\n ) => void;\n /** Called the value changes. */\n onChange?: (\n event: React.FormEvent<Element> | React.KeyboardEvent<Element>,\n value: string,\n ) => void;\n /** Called the `edit` prop changes. */\n onEditChange?: (value: boolean) => void;\n}\n\nexport const ToolbarTabEditor = ({\n id,\n className,\n edit: editProp,\n value: valueProp,\n defaultValue: defaultValueProp = \"\",\n classes: classesProp,\n onInput: onInputProp,\n onClick: onClickProp,\n onBlur: onBlurProp,\n onKeyDown: onKeyDownProp,\n onChange: onChangeProp,\n onEditChange: onEditChangeProp,\n ...others\n}: ToolbarTabEditorProps) => {\n const { cx, classes } = useClasses(classesProp);\n\n const contentEditableRef = useRef<HTMLSpanElement>(null);\n\n const [value, setValue] = useControlled(valueProp
|
|
1
|
+
{"version":3,"file":"ToolbarTabEditor.js","sources":["../../../../src/Canvas/ToolbarTabs/ToolbarTabEditor.tsx"],"sourcesContent":["import { useLayoutEffect, useRef, useState } from \"react\";\nimport {\n createClasses,\n ExtractNames,\n HvTypography,\n HvTypographyProps,\n isKey,\n theme,\n useControlled,\n} from \"@hitachivantara/uikit-react-core\";\nimport { Edit } from \"@hitachivantara/uikit-react-icons\";\n\n// TODO - Extract component in the future: when we have more specs and/or is used in other components\n\nconst { staticClasses, useClasses } = createClasses(\n \"HvCanvasToolbarTabs-editor\",\n {\n root: {\n position: \"relative\",\n display: \"flex\",\n width: \"100%\",\n overflow: \"hidden\",\n \"&:has($label:hover:not($edit))\": {\n color: theme.colors.secondary_80,\n \"& $editIcon\": { visibility: \"visible\" },\n },\n },\n edit: {\n color: theme.colors.secondary_80,\n borderColor: \"currentColor\",\n backgroundColor: theme.colors.atmo1,\n cursor: \"text\",\n },\n label: {\n width: \"100%\",\n boxSizing: \"border-box\",\n border: \"1px solid transparent\",\n borderRadius: theme.radii.base,\n padding: theme.spacing(0, \"sm\", 0, \"xs\"),\n textAlign: \"start\",\n whiteSpace: \"nowrap\",\n overflow: \"hidden\",\n outline: \"none\",\n \"&:not($edit)\": {\n textOverflow: \"ellipsis\",\n },\n \"&:hover:not($edit)\": {\n color: theme.colors.secondary_80,\n borderColor: theme.colors.containerBackgroundHover,\n backgroundColor: theme.colors.containerBackgroundHover,\n },\n },\n editIcon: {\n position: \"absolute\",\n right: theme.spacing(0.5),\n top: 4,\n width: 16,\n height: 16,\n visibility: \"hidden\",\n pointerEvents: \"none\",\n },\n },\n);\n\nexport { staticClasses as toolbarTabEditorClasses };\n\ntype ToolbarTabEditorClasses = ExtractNames<typeof useClasses>;\n\ninterface ToolbarTabEditorProps\n extends Omit<HvTypographyProps, \"classes\" | \"onBlur\" | \"onChange\"> {\n /** The value of the component. When used, the component has to be controlled. */\n value?: string;\n /** The default value of the component. */\n defaultValue?: string;\n /** Whether the editor is in edit mode. When used, the prop has to be controlled. */\n edit?: boolean;\n /** A Jss Object used to override or extend the styles applied. */\n classes?: ToolbarTabEditorClasses;\n /** Called the field is blurred. */\n onBlur?: (\n event: React.FocusEvent<Element> | React.KeyboardEvent<Element>,\n value: string,\n ) => void;\n /** Called the value changes. */\n onChange?: (\n event: React.FormEvent<Element> | React.KeyboardEvent<Element>,\n value: string,\n ) => void;\n /** Called the `edit` prop changes. */\n onEditChange?: (value: boolean) => void;\n}\n\nconst sanitize = (value: string) =>\n value\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/\"/g, \""\")\n .replace(/'/g, \"'\");\n\nexport const ToolbarTabEditor = ({\n id,\n className,\n edit: editProp,\n value: valueProp,\n defaultValue: defaultValueProp = \"\",\n classes: classesProp,\n onInput: onInputProp,\n onClick: onClickProp,\n onBlur: onBlurProp,\n onKeyDown: onKeyDownProp,\n onChange: onChangeProp,\n onEditChange: onEditChangeProp,\n ...others\n}: ToolbarTabEditorProps) => {\n const { cx, classes } = useClasses(classesProp);\n\n const contentEditableRef = useRef<HTMLSpanElement>(null);\n\n // Sanitize content\n const [value, setValue] = useControlled(\n valueProp ? sanitize(valueProp) : valueProp,\n defaultValueProp ? sanitize(defaultValueProp) : defaultValueProp,\n );\n const [cachedValue, setCachedValue] = useState(value);\n const [isEditing, setIsEditing] = useControlled(editProp, false);\n\n const moveCursorToEnd = () => {\n if (!contentEditableRef.current) return;\n const element = contentEditableRef.current;\n const range = document.createRange();\n const selection = window.getSelection();\n range.selectNodeContents(element);\n range.collapse(false);\n selection?.removeAllRanges();\n selection?.addRange(range);\n element.scrollLeft = element.scrollWidth;\n };\n\n const scrollContentToStart = () => {\n if (!contentEditableRef.current) return;\n const element = contentEditableRef.current;\n element.scrollLeft = 0;\n };\n\n const changeEdit = (edit: boolean) => {\n setIsEditing(edit);\n onEditChangeProp?.(edit);\n };\n\n // Update cursor when value updates: otherwise it goes to the start\n useLayoutEffect(() => {\n if (isEditing) moveCursorToEnd();\n }, [isEditing, value]);\n\n const handleInput: HvTypographyProps[\"onInput\"] = (event) => {\n // Sanitize content\n const newValue = sanitize((event.target as any).textContent) || \"\";\n setValue(newValue);\n onInputProp?.(event);\n onChangeProp?.(event, newValue);\n };\n\n const handleClick: HvTypographyProps[\"onClick\"] = (event) => {\n setCachedValue(value);\n changeEdit(true);\n onClickProp?.(event);\n };\n\n const handleBlur = (\n event: React.FocusEvent<Element> | React.KeyboardEvent<Element>,\n ) => {\n changeEdit(false);\n scrollContentToStart();\n\n // Never leave the field empty\n const newValue = value.trim() || cachedValue;\n setValue(newValue);\n\n onBlurProp?.(event, newValue);\n };\n\n const handleKeyDown: HvTypographyProps[\"onKeyDown\"] = (event) => {\n if (isKey(event, \"Enter\")) {\n // Blur field\n handleBlur(event);\n } else if (isKey(event, \"Esc\")) {\n changeEdit(false);\n\n // Cancel editing\n setValue(cachedValue);\n onChangeProp?.(event, cachedValue);\n }\n onKeyDownProp?.(event);\n };\n\n return (\n <div id={id} className={cx(classes.root, className)}>\n <HvTypography\n ref={contentEditableRef}\n contentEditable={isEditing}\n className={cx(classes.label, { [classes.edit]: isEditing })}\n variant=\"label\"\n component=\"span\"\n onInput={handleInput}\n onClick={handleClick}\n onBlur={handleBlur}\n onKeyDown={handleKeyDown}\n // Using children is unstable in React for contentEditable so the value is rendered through dangerouslySetInnerHTML\n dangerouslySetInnerHTML={{\n __html: value,\n }}\n {...others}\n />\n <Edit className={classes.editIcon} iconSize=\"XS\" />\n </div>\n );\n};\n"],"names":[],"mappings":"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"}
|
|
@@ -20,7 +20,8 @@ const HvCanvasToolbarTabs = forwardRef((props, ref) => {
|
|
|
20
20
|
className,
|
|
21
21
|
selectedTabId: selectedTabIdProp,
|
|
22
22
|
icon: iconProp,
|
|
23
|
-
|
|
23
|
+
disableTabEdit = false,
|
|
24
|
+
hideCreateNew = false,
|
|
24
25
|
tabs: tabsProp,
|
|
25
26
|
defaultTabs: defaultTabsProp = [],
|
|
26
27
|
labels: labelsProp,
|
|
@@ -76,8 +77,8 @@ const HvCanvasToolbarTabs = forwardRef((props, ref) => {
|
|
|
76
77
|
}
|
|
77
78
|
handleChangeTabs(event, newTabs);
|
|
78
79
|
};
|
|
79
|
-
const handleKeyDownTab = (event, tabId) => {
|
|
80
|
-
if (isKey(event, "Delete") || isKey(event, "Backspace")) {
|
|
80
|
+
const handleKeyDownTab = (event, tabId, removable) => {
|
|
81
|
+
if (removable && (isKey(event, "Delete") || isKey(event, "Backspace"))) {
|
|
81
82
|
handleDeleteTab(event, tabId);
|
|
82
83
|
event.stopPropagation();
|
|
83
84
|
} else if (isKey(event, "Enter")) {
|
|
@@ -142,6 +143,7 @@ const HvCanvasToolbarTabs = forwardRef((props, ref) => {
|
|
|
142
143
|
onChange: handleChangeSelectedTab,
|
|
143
144
|
children: visibleTabs.map((tab, index) => {
|
|
144
145
|
const btnSelected = selectedTab === tab.id;
|
|
146
|
+
const removable = !tab.fixed;
|
|
145
147
|
return /* @__PURE__ */ jsx(
|
|
146
148
|
HvCanvasPanelTab,
|
|
147
149
|
{
|
|
@@ -151,10 +153,10 @@ const HvCanvasToolbarTabs = forwardRef((props, ref) => {
|
|
|
151
153
|
id: String(tab.id),
|
|
152
154
|
className: classes.tab,
|
|
153
155
|
value: tab.id,
|
|
154
|
-
onKeyDown: (event) => handleKeyDownTab(event, tab.id),
|
|
156
|
+
onKeyDown: (event) => handleKeyDownTab(event, tab.id, removable),
|
|
155
157
|
children: /* @__PURE__ */ jsxs("div", { className: classes.tabContent, children: [
|
|
156
158
|
tab.icon && /* @__PURE__ */ jsx("div", { className: classes.tabIconContainer, children: tab.icon }),
|
|
157
|
-
!btnSelected ||
|
|
159
|
+
!btnSelected || disableTabEdit ? /* @__PURE__ */ jsx(
|
|
158
160
|
HvOverflowTooltip,
|
|
159
161
|
{
|
|
160
162
|
classes: {
|
|
@@ -176,11 +178,11 @@ const HvCanvasToolbarTabs = forwardRef((props, ref) => {
|
|
|
176
178
|
onKeyDown: (e) => e.stopPropagation()
|
|
177
179
|
}
|
|
178
180
|
),
|
|
179
|
-
/* @__PURE__ */ jsx("div", { className: classes.closeIconContainer, children: /* @__PURE__ */ jsx(
|
|
181
|
+
removable && /* @__PURE__ */ jsx("div", { className: classes.closeIconContainer, children: /* @__PURE__ */ jsx(
|
|
180
182
|
CloseXS,
|
|
181
183
|
{
|
|
182
184
|
"aria-hidden": true,
|
|
183
|
-
|
|
185
|
+
size: "xs",
|
|
184
186
|
onClick: (event) => {
|
|
185
187
|
handleDeleteTab(event, tab.id);
|
|
186
188
|
event.stopPropagation();
|
|
@@ -211,7 +213,7 @@ const HvCanvasToolbarTabs = forwardRef((props, ref) => {
|
|
|
211
213
|
] }),
|
|
212
214
|
/* @__PURE__ */ jsxs("div", { ref: actionsRef, className: classes.actionsContainer, children: [
|
|
213
215
|
children,
|
|
214
|
-
/* @__PURE__ */ jsx(
|
|
216
|
+
!hideCreateNew && /* @__PURE__ */ jsx(
|
|
215
217
|
HvButton,
|
|
216
218
|
{
|
|
217
219
|
variant: "primaryGhost",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ToolbarTabs.js","sources":["../../../../src/Canvas/ToolbarTabs/ToolbarTabs.tsx"],"sourcesContent":["import { forwardRef, useMemo, useState } from \"react\";\nimport { useResizeDetector } from \"react-resize-detector\";\nimport {\n ExtractNames,\n HvBaseProps,\n HvButton,\n HvButtonProps,\n HvDropDownMenu,\n HvOverflowTooltip,\n isKey,\n uniqueId,\n useControlled,\n useDefaultProps,\n useForkRef,\n useLabels,\n} from \"@hitachivantara/uikit-react-core\";\nimport {\n AddAlt,\n CloseXS,\n MoreOptionsHorizontal,\n} from \"@hitachivantara/uikit-react-icons\";\nimport { clamp } from \"@hitachivantara/uikit-react-utils\";\n\nimport { HvCanvasPanelTab } from \"../PanelTab\";\nimport { HvCanvasPanelTabs, HvCanvasPanelTabsProps } from \"../PanelTabs\";\nimport { ToolbarTabEditor } from \"./ToolbarTabEditor\";\nimport {\n DROPDOWN_MENU_WIDTH,\n MAX_TAB_WIDTH,\n MIN_TAB_WIDTH,\n staticClasses,\n useClasses,\n} from \"./ToolbarTabs.styles\";\n\nexport { staticClasses as canvasToolbarTabsClasses };\n\nexport type HvCanvasToolbarTabsClasses = ExtractNames<typeof useClasses>;\n\nconst DEFAULT_LABELS = {\n create: \"Create new\",\n undefined: \"Undefined\",\n dropdownMenu: \"Dropdown menu\",\n};\n\ninterface ToolbarTabsTab {\n id: string;\n label: string;\n icon?: React.ReactNode;\n}\n\nexport interface HvCanvasToolbarTabsProps\n extends HvBaseProps<HTMLDivElement, \"onChange\"> {\n /** When controlled, defines the tabs. */\n tabs?: ToolbarTabsTab[];\n /** When uncontrolled, defines the initial tabs. */\n defaultTabs?: ToolbarTabsTab[];\n /** Id of the selected tab if it needs to be controlled. */\n selectedTabId?: string;\n /** Defines the icon to be placed before the label when a new tab is created. If not defined, no icon is used. */\n icon?: React.ReactNode;\n /** Defines whether or not the tabs are editable. */\n allowTabEdit?: boolean;\n /** Callback triggered when a tab changes/is clicked. */\n onTabChange?: (\n event: React.SyntheticEvent | null,\n tabId: string | null,\n ) => void;\n /** Callback triggered when the tabs change: new tab added, tab removed, tab reorder, and label updated. */\n onChange?: (\n event: React.MouseEvent<HTMLButtonElement> | React.SyntheticEvent,\n tabs: ToolbarTabsTab[],\n ) => void;\n /** An object containing all the labels. */\n labels?: Partial<typeof DEFAULT_LABELS>;\n /** A Jss Object used to override or extend the styles applied. */\n classes?: HvCanvasToolbarTabsClasses;\n}\n\n/**\n * A toolbar tabs component to use in a canvas context.\n */\nexport const HvCanvasToolbarTabs = forwardRef<\n HTMLDivElement,\n HvCanvasToolbarTabsProps\n>((props, ref) => {\n const {\n children,\n className,\n selectedTabId: selectedTabIdProp,\n icon: iconProp,\n allowTabEdit = true,\n tabs: tabsProp,\n defaultTabs: defaultTabsProp = [],\n labels: labelsProp,\n classes: classesProp,\n onTabChange: onTabChangeProp,\n onChange: onChangeProp,\n ...others\n } = useDefaultProps(\"HvCanvasToolbarTabs\", props);\n\n const { classes, cx } = useClasses(classesProp);\n\n const labels = useLabels(DEFAULT_LABELS, labelsProp);\n\n // Actions resize detector: to know when to use the dropdown menu\n const { width: actionsWidth = 0, ref: actionsRef } = useResizeDetector({\n handleHeight: false,\n });\n\n // Root resize detector: to know when to use the dropdown menu\n const { width: rootWidth = 0, ref: rootRef } = useResizeDetector({\n handleHeight: false,\n });\n\n const [tabs, setTabs] = useControlled(tabsProp, defaultTabsProp);\n const [selectedTab, setSelectedTab] = useControlled<string | null>(\n selectedTabIdProp,\n tabs?.[0]?.id ?? \"none\",\n );\n const [isEditing, setIsEditing] = useState(false);\n\n const rootForkedRef = useForkRef(ref, rootRef);\n\n const handleChangeTabs = (\n event: React.MouseEvent<HTMLButtonElement> | React.SyntheticEvent,\n newTabs: ToolbarTabsTab[],\n ) => {\n setTabs(newTabs);\n onChangeProp?.(event, newTabs);\n };\n\n const handleChangeSelectedTab: HvCanvasPanelTabsProps[\"onChange\"] = (\n event,\n value,\n ) => {\n setSelectedTab(String(value));\n onTabChangeProp?.(event, String(value));\n };\n\n const handleCreateNew: HvButtonProps[\"onClick\"] = (event) => {\n const newTabs: ToolbarTabsTab[] = [...tabs];\n const newTab: ToolbarTabsTab = {\n id: uniqueId(),\n label: `${labels.undefined} ${newTabs.length + 1}`,\n icon: iconProp,\n };\n newTabs.push(newTab);\n handleChangeSelectedTab(event, newTab.id);\n handleChangeTabs?.(event, newTabs);\n };\n\n const handleEdit = (\n event: React.FormEvent<Element>,\n value: string,\n tabId: string,\n ) =>\n handleChangeTabs(\n event,\n tabs.map((tab) => (tab.id === tabId ? { ...tab, label: value } : tab)),\n );\n\n const handleDeleteTab = (event: any, tabId: string) => {\n const newTabs = tabs.filter((tab) => tab.id !== tabId);\n\n if (tabId === selectedTab) {\n const currentIndex = tabs.findIndex((tab) => tab.id === tabId);\n const newIndex = currentIndex - 1 < 0 ? 0 : currentIndex - 1;\n handleChangeSelectedTab(event, newTabs[newIndex]?.id ?? \"none\");\n }\n\n handleChangeTabs(event, newTabs);\n };\n\n const handleKeyDownTab = (event: React.KeyboardEvent, tabId: string) => {\n if (isKey(event, \"Delete\") || isKey(event, \"Backspace\")) {\n handleDeleteTab(event, tabId);\n\n // We don't want the click to also select the tab\n event.stopPropagation();\n } else if (isKey(event, \"Enter\")) {\n // Activate edit label mode\n setIsEditing(true);\n }\n };\n\n const { tabWidth, hiddenTabs, visibleTabs } = useMemo(() => {\n let availableWidth = rootWidth - actionsWidth;\n let calculatedTabWidth = availableWidth / tabs.length;\n let clamped = clamp(calculatedTabWidth, MAX_TAB_WIDTH, MIN_TAB_WIDTH);\n\n // Overflowing\n if (calculatedTabWidth < MIN_TAB_WIDTH) {\n availableWidth -= DROPDOWN_MENU_WIDTH;\n const visibleCount = Math.floor(availableWidth / MIN_TAB_WIDTH);\n calculatedTabWidth = availableWidth / visibleCount;\n clamped = clamp(calculatedTabWidth, MAX_TAB_WIDTH, MIN_TAB_WIDTH);\n\n const temporaryHiddenTabs = tabs.slice(visibleCount);\n const selectedTabHiddenIndex = temporaryHiddenTabs.findIndex(\n (tab) => tab.id === selectedTab,\n );\n const excludedTabIndex = visibleCount - 1;\n const shouldShuffle = selectedTabHiddenIndex !== -1 && visibleCount > 0;\n\n if (shouldShuffle) {\n return {\n tabWidth: clamped,\n visibleTabs: [\n ...tabs.slice(0, excludedTabIndex),\n temporaryHiddenTabs[selectedTabHiddenIndex],\n ].filter((tab) => tab),\n hiddenTabs: [\n tabs[excludedTabIndex],\n ...temporaryHiddenTabs.filter(\n (tab, i) => i !== selectedTabHiddenIndex,\n ),\n ].filter((tab) => tab),\n };\n }\n\n return {\n tabWidth: clamped,\n visibleTabs: tabs.slice(0, visibleCount),\n hiddenTabs: temporaryHiddenTabs,\n };\n }\n\n return {\n tabWidth: clamped,\n visibleTabs: tabs,\n hiddenTabs: [],\n };\n }, [actionsWidth, rootWidth, selectedTab, tabs]);\n\n return (\n <div\n ref={rootForkedRef}\n className={cx(classes.root, className)}\n {...others}\n >\n <div className={classes.tabsContainer}>\n {visibleTabs.length > 0 && (\n <HvCanvasPanelTabs\n classes={{ list: classes.tabsList }}\n value={selectedTab}\n onChange={handleChangeSelectedTab}\n >\n {visibleTabs.map((tab, index) => {\n const btnSelected = selectedTab === tab.id;\n return (\n <HvCanvasPanelTab\n style={{\n width: tabWidth,\n }}\n key={tab.id}\n id={String(tab.id)}\n className={classes.tab}\n value={tab.id}\n onKeyDown={(event) => handleKeyDownTab(event, tab.id)}\n >\n <div className={classes.tabContent}>\n {tab.icon && (\n <div className={classes.tabIconContainer}>{tab.icon}</div>\n )}\n {!btnSelected || !allowTabEdit ? (\n <HvOverflowTooltip\n classes={{\n tooltipAnchor: classes.tabLabel,\n }}\n data={tab.label}\n />\n ) : (\n <ToolbarTabEditor\n classes={{\n label: cx(classes.tabLabel, classes.tabLabelEditor),\n }}\n value={tab.label}\n edit={isEditing}\n onEditChange={setIsEditing}\n onChange={(event, value) =>\n handleEdit(event, value, tab.id)\n }\n onBlur={(event, value) =>\n handleEdit(event, value, tab.id)\n }\n // We don't want the arrow keys to trigger the tab navigation\n onKeyDown={(e) => e.stopPropagation()}\n />\n )}\n <div className={classes.closeIconContainer}>\n <CloseXS\n aria-hidden\n iconSize=\"XS\"\n onClick={(event) => {\n handleDeleteTab(event, tab.id);\n\n // We don't want the click to also select the tab\n event.stopPropagation();\n }}\n />\n </div>\n {selectedTab !== tab.id &&\n visibleTabs[index + 1]?.id !== selectedTab && (\n <div className={classes.tabDivider} />\n )}\n </div>\n </HvCanvasPanelTab>\n );\n })}\n </HvCanvasPanelTabs>\n )}\n {hiddenTabs.length > 0 && (\n <HvDropDownMenu\n classes={{\n container: classes.dropdownMenuContainer,\n menuListRoot: classes.dropdownMenuListRoot,\n }}\n dataList={hiddenTabs}\n icon={<MoreOptionsHorizontal />}\n labels={{ dropdownMenu: labels.dropdownMenu }}\n onClick={(event, value) =>\n handleChangeSelectedTab(event, value.id ?? \"none\")\n }\n />\n )}\n </div>\n <div ref={actionsRef} className={classes.actionsContainer}>\n {children}\n <HvButton\n variant=\"primaryGhost\"\n startIcon={<AddAlt />}\n onClick={handleCreateNew}\n >\n {labels.create}\n </HvButton>\n </div>\n </div>\n );\n});\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ToolbarTabs.js","sources":["../../../../src/Canvas/ToolbarTabs/ToolbarTabs.tsx"],"sourcesContent":["import { forwardRef, useMemo, useState } from \"react\";\nimport { useResizeDetector } from \"react-resize-detector\";\nimport {\n ExtractNames,\n HvBaseProps,\n HvButton,\n HvButtonProps,\n HvDropDownMenu,\n HvOverflowTooltip,\n isKey,\n uniqueId,\n useControlled,\n useDefaultProps,\n useForkRef,\n useLabels,\n} from \"@hitachivantara/uikit-react-core\";\nimport {\n AddAlt,\n CloseXS,\n MoreOptionsHorizontal,\n} from \"@hitachivantara/uikit-react-icons\";\nimport { clamp } from \"@hitachivantara/uikit-react-utils\";\n\nimport { HvCanvasPanelTab } from \"../PanelTab\";\nimport { HvCanvasPanelTabs, HvCanvasPanelTabsProps } from \"../PanelTabs\";\nimport { ToolbarTabEditor } from \"./ToolbarTabEditor\";\nimport {\n DROPDOWN_MENU_WIDTH,\n MAX_TAB_WIDTH,\n MIN_TAB_WIDTH,\n staticClasses,\n useClasses,\n} from \"./ToolbarTabs.styles\";\n\nexport { staticClasses as canvasToolbarTabsClasses };\n\nexport type HvCanvasToolbarTabsClasses = ExtractNames<typeof useClasses>;\n\nconst DEFAULT_LABELS = {\n create: \"Create new\",\n undefined: \"Undefined\",\n dropdownMenu: \"Dropdown menu\",\n};\n\ninterface ToolbarTabsTab {\n id: string;\n label: string;\n icon?: React.ReactNode;\n /** Whether the tab is fixed and can't be removed. Defaults to `false`, i.e., all tabs are removable by default. */\n fixed?: boolean;\n}\n\nexport interface HvCanvasToolbarTabsProps\n extends HvBaseProps<HTMLDivElement, \"onChange\"> {\n /** When controlled, defines the tabs. */\n tabs?: ToolbarTabsTab[];\n /** When uncontrolled, defines the initial tabs. */\n defaultTabs?: ToolbarTabsTab[];\n /** Id of the selected tab if it needs to be controlled. */\n selectedTabId?: string;\n /** Defines the icon to be placed before the label when a new tab is created through the \"Create new\" button. If not defined, no icon is used. */\n icon?: React.ReactNode;\n /** Whether the tabs are editable or not. Default to `false`. */\n disableTabEdit?: boolean;\n /** Callback triggered when a tab changes/is clicked. */\n onTabChange?: (\n event: React.SyntheticEvent | null,\n tabId: string | null,\n ) => void;\n /** Callback triggered when the tabs change: new tab added, tab removed, tab reorder, and label updated. */\n onChange?: (\n event: React.MouseEvent<HTMLButtonElement> | React.SyntheticEvent,\n tabs: ToolbarTabsTab[],\n ) => void;\n /** An object containing all the labels. */\n labels?: Partial<typeof DEFAULT_LABELS>;\n /** A Jss Object used to override or extend the styles applied. */\n classes?: HvCanvasToolbarTabsClasses;\n /** Whether the \"Create new\" button, which enables to create new tabs, is hidden. Defaults to `false`. */\n hideCreateNew?: boolean;\n}\n\n/**\n * A toolbar tabs component to use in a canvas context.\n */\nexport const HvCanvasToolbarTabs = forwardRef<\n HTMLDivElement,\n HvCanvasToolbarTabsProps\n>((props, ref) => {\n const {\n children,\n className,\n selectedTabId: selectedTabIdProp,\n icon: iconProp,\n disableTabEdit = false,\n hideCreateNew = false,\n tabs: tabsProp,\n defaultTabs: defaultTabsProp = [],\n labels: labelsProp,\n classes: classesProp,\n onTabChange: onTabChangeProp,\n onChange: onChangeProp,\n ...others\n } = useDefaultProps(\"HvCanvasToolbarTabs\", props);\n\n const { classes, cx } = useClasses(classesProp);\n\n const labels = useLabels(DEFAULT_LABELS, labelsProp);\n\n // Actions resize detector: to know when to use the dropdown menu\n const { width: actionsWidth = 0, ref: actionsRef } = useResizeDetector({\n handleHeight: false,\n });\n\n // Root resize detector: to know when to use the dropdown menu\n const { width: rootWidth = 0, ref: rootRef } = useResizeDetector({\n handleHeight: false,\n });\n\n const [tabs, setTabs] = useControlled(tabsProp, defaultTabsProp);\n const [selectedTab, setSelectedTab] = useControlled<string | null>(\n selectedTabIdProp,\n tabs?.[0]?.id ?? \"none\",\n );\n const [isEditing, setIsEditing] = useState(false);\n\n const rootForkedRef = useForkRef(ref, rootRef);\n\n const handleChangeTabs = (\n event: React.MouseEvent<HTMLButtonElement> | React.SyntheticEvent,\n newTabs: ToolbarTabsTab[],\n ) => {\n setTabs(newTabs);\n onChangeProp?.(event, newTabs);\n };\n\n const handleChangeSelectedTab: HvCanvasPanelTabsProps[\"onChange\"] = (\n event,\n value,\n ) => {\n setSelectedTab(String(value));\n onTabChangeProp?.(event, String(value));\n };\n\n const handleCreateNew: HvButtonProps[\"onClick\"] = (event) => {\n const newTabs: ToolbarTabsTab[] = [...tabs];\n const newTab: ToolbarTabsTab = {\n id: uniqueId(),\n label: `${labels.undefined} ${newTabs.length + 1}`,\n icon: iconProp,\n };\n newTabs.push(newTab);\n handleChangeSelectedTab(event, newTab.id);\n handleChangeTabs?.(event, newTabs);\n };\n\n const handleEdit = (\n event: React.FormEvent<Element>,\n value: string,\n tabId: string,\n ) =>\n handleChangeTabs(\n event,\n tabs.map((tab) => (tab.id === tabId ? { ...tab, label: value } : tab)),\n );\n\n const handleDeleteTab = (event: any, tabId: string) => {\n const newTabs = tabs.filter((tab) => tab.id !== tabId);\n\n if (tabId === selectedTab) {\n const currentIndex = tabs.findIndex((tab) => tab.id === tabId);\n const newIndex = currentIndex - 1 < 0 ? 0 : currentIndex - 1;\n handleChangeSelectedTab(event, newTabs[newIndex]?.id ?? \"none\");\n }\n\n handleChangeTabs(event, newTabs);\n };\n\n const handleKeyDownTab = (\n event: React.KeyboardEvent,\n tabId: string,\n removable: boolean,\n ) => {\n if (removable && (isKey(event, \"Delete\") || isKey(event, \"Backspace\"))) {\n handleDeleteTab(event, tabId);\n\n // We don't want the click to also select the tab\n event.stopPropagation();\n } else if (isKey(event, \"Enter\")) {\n // Activate edit label mode\n setIsEditing(true);\n }\n };\n\n const { tabWidth, hiddenTabs, visibleTabs } = useMemo(() => {\n let availableWidth = rootWidth - actionsWidth;\n let calculatedTabWidth = availableWidth / tabs.length;\n let clamped = clamp(calculatedTabWidth, MAX_TAB_WIDTH, MIN_TAB_WIDTH);\n\n // Overflowing\n if (calculatedTabWidth < MIN_TAB_WIDTH) {\n availableWidth -= DROPDOWN_MENU_WIDTH;\n const visibleCount = Math.floor(availableWidth / MIN_TAB_WIDTH);\n calculatedTabWidth = availableWidth / visibleCount;\n clamped = clamp(calculatedTabWidth, MAX_TAB_WIDTH, MIN_TAB_WIDTH);\n\n const temporaryHiddenTabs = tabs.slice(visibleCount);\n const selectedTabHiddenIndex = temporaryHiddenTabs.findIndex(\n (tab) => tab.id === selectedTab,\n );\n const excludedTabIndex = visibleCount - 1;\n const shouldShuffle = selectedTabHiddenIndex !== -1 && visibleCount > 0;\n\n if (shouldShuffle) {\n return {\n tabWidth: clamped,\n visibleTabs: [\n ...tabs.slice(0, excludedTabIndex),\n temporaryHiddenTabs[selectedTabHiddenIndex],\n ].filter((tab) => tab),\n hiddenTabs: [\n tabs[excludedTabIndex],\n ...temporaryHiddenTabs.filter(\n (tab, i) => i !== selectedTabHiddenIndex,\n ),\n ].filter((tab) => tab),\n };\n }\n\n return {\n tabWidth: clamped,\n visibleTabs: tabs.slice(0, visibleCount),\n hiddenTabs: temporaryHiddenTabs,\n };\n }\n\n return {\n tabWidth: clamped,\n visibleTabs: tabs,\n hiddenTabs: [],\n };\n }, [actionsWidth, rootWidth, selectedTab, tabs]);\n\n return (\n <div\n ref={rootForkedRef}\n className={cx(classes.root, className)}\n {...others}\n >\n <div className={classes.tabsContainer}>\n {visibleTabs.length > 0 && (\n <HvCanvasPanelTabs\n classes={{ list: classes.tabsList }}\n value={selectedTab}\n onChange={handleChangeSelectedTab}\n >\n {visibleTabs.map((tab, index) => {\n const btnSelected = selectedTab === tab.id;\n const removable = !tab.fixed;\n return (\n <HvCanvasPanelTab\n style={{\n width: tabWidth,\n }}\n key={tab.id}\n id={String(tab.id)}\n className={classes.tab}\n value={tab.id}\n onKeyDown={(event) =>\n handleKeyDownTab(event, tab.id, removable)\n }\n >\n <div className={classes.tabContent}>\n {tab.icon && (\n <div className={classes.tabIconContainer}>{tab.icon}</div>\n )}\n {!btnSelected || disableTabEdit ? (\n <HvOverflowTooltip\n classes={{\n tooltipAnchor: classes.tabLabel,\n }}\n data={tab.label}\n />\n ) : (\n <ToolbarTabEditor\n classes={{\n label: cx(classes.tabLabel, classes.tabLabelEditor),\n }}\n value={tab.label}\n edit={isEditing}\n onEditChange={setIsEditing}\n onChange={(event, value) =>\n handleEdit(event, value, tab.id)\n }\n onBlur={(event, value) =>\n handleEdit(event, value, tab.id)\n }\n // We don't want the arrow keys to trigger the tab navigation\n onKeyDown={(e) => e.stopPropagation()}\n />\n )}\n {removable && (\n <div className={classes.closeIconContainer}>\n <CloseXS\n aria-hidden\n size=\"xs\"\n onClick={(event) => {\n handleDeleteTab(event, tab.id);\n\n // We don't want the click to also select the tab\n event.stopPropagation();\n }}\n />\n </div>\n )}\n {selectedTab !== tab.id &&\n visibleTabs[index + 1]?.id !== selectedTab && (\n <div className={classes.tabDivider} />\n )}\n </div>\n </HvCanvasPanelTab>\n );\n })}\n </HvCanvasPanelTabs>\n )}\n {hiddenTabs.length > 0 && (\n <HvDropDownMenu\n classes={{\n container: classes.dropdownMenuContainer,\n menuListRoot: classes.dropdownMenuListRoot,\n }}\n dataList={hiddenTabs}\n icon={<MoreOptionsHorizontal />}\n labels={{ dropdownMenu: labels.dropdownMenu }}\n onClick={(event, value) =>\n handleChangeSelectedTab(event, value.id ?? \"none\")\n }\n />\n )}\n </div>\n <div ref={actionsRef} className={classes.actionsContainer}>\n {children}\n {!hideCreateNew && (\n <HvButton\n variant=\"primaryGhost\"\n startIcon={<AddAlt />}\n onClick={handleCreateNew}\n >\n {labels.create}\n </HvButton>\n )}\n </div>\n </div>\n );\n});\n"],"names":[],"mappings":"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"}
|
|
@@ -8,7 +8,7 @@ const TAB_HEIGHT = 32;
|
|
|
8
8
|
const CLOSE_ICON_SIZE = 32;
|
|
9
9
|
const TAB_ICON_SIZE = 16;
|
|
10
10
|
const TAB_PADDING = theme.space.xs;
|
|
11
|
-
const TAB_COLOR = theme.
|
|
11
|
+
const TAB_COLOR = `color-mix(in srgb, ${theme.colors.pp.primaryDimmed} 50%, ${theme.colors.pp.dimmer})`;
|
|
12
12
|
const { staticClasses, useClasses } = createClasses(
|
|
13
13
|
"HvCanvasToolbarTabs",
|
|
14
14
|
{
|
|
@@ -20,7 +20,8 @@ const { staticClasses, useClasses } = createClasses(
|
|
|
20
20
|
backgroundColor: theme.colors.atmo1,
|
|
21
21
|
boxShadow: theme.colors.shadow,
|
|
22
22
|
borderRadius: `0px 0px ${theme.radii.base} ${theme.radii.base}`,
|
|
23
|
-
transition: "width 0.3s ease"
|
|
23
|
+
transition: "width 0.3s ease",
|
|
24
|
+
height: TAB_HEIGHT
|
|
24
25
|
},
|
|
25
26
|
tabsContainer: {
|
|
26
27
|
display: "flex"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ToolbarTabs.styles.js","sources":["../../../../src/Canvas/ToolbarTabs/ToolbarTabs.styles.tsx"],"sourcesContent":["import { tabClasses } from \"@mui/base/Tab\";\nimport { createClasses, theme } from \"@hitachivantara/uikit-react-core\";\n\nimport { toolbarTabEditorClasses } from \"./ToolbarTabEditor\";\n\nexport const MIN_TAB_WIDTH = 120;\nexport const MAX_TAB_WIDTH = 220;\nexport const DROPDOWN_MENU_WIDTH = 64;\nconst TAB_HEIGHT = 32;\nconst CLOSE_ICON_SIZE = 32;\nconst TAB_ICON_SIZE = 16;\nconst TAB_PADDING = theme.space.xs;\nconst TAB_COLOR = theme.
|
|
1
|
+
{"version":3,"file":"ToolbarTabs.styles.js","sources":["../../../../src/Canvas/ToolbarTabs/ToolbarTabs.styles.tsx"],"sourcesContent":["import { tabClasses } from \"@mui/base/Tab\";\nimport { createClasses, theme } from \"@hitachivantara/uikit-react-core\";\n\nimport { toolbarTabEditorClasses } from \"./ToolbarTabEditor\";\n\nexport const MIN_TAB_WIDTH = 120;\nexport const MAX_TAB_WIDTH = 220;\nexport const DROPDOWN_MENU_WIDTH = 64;\nconst TAB_HEIGHT = 32;\nconst CLOSE_ICON_SIZE = 32;\nconst TAB_ICON_SIZE = 16;\nconst TAB_PADDING = theme.space.xs;\nconst TAB_COLOR = `color-mix(in srgb, ${theme.colors.pp.primaryDimmed} 50%, ${theme.colors.pp.dimmer})`;\n\nexport const { staticClasses, useClasses } = createClasses(\n \"HvCanvasToolbarTabs\",\n {\n root: {\n display: \"flex\",\n justifyContent: \"space-between\",\n alignItems: \"center\",\n width: \"100%\",\n backgroundColor: theme.colors.atmo1,\n boxShadow: theme.colors.shadow,\n borderRadius: `0px 0px ${theme.radii.base} ${theme.radii.base}`,\n transition: \"width 0.3s ease\",\n height: TAB_HEIGHT,\n },\n tabsContainer: {\n display: \"flex\",\n },\n tabsList: {\n height: TAB_HEIGHT,\n background: theme.colors.atmo1,\n borderEndStartRadius: theme.radii.base,\n },\n tab: {\n boxSizing: \"border-box\",\n border: `1px solid ${theme.colors.atmo1}`,\n borderBottom: \"none\",\n borderRadius: \"10px 10px 0 0\",\n boxShadow: \"none\",\n backgroundColor: theme.colors.atmo1,\n \"&:first-of-type\": { borderEndStartRadius: theme.radii.base },\n [`&.${tabClasses.selected}`]: {\n color: theme.colors.primary,\n backgroundColor: TAB_COLOR,\n borderColor: theme.colors.atmo4,\n },\n [`&:hover:not(.${tabClasses.selected}), &:focus:not(.${tabClasses.selected})`]:\n {\n borderRadius: 0,\n backgroundColor: TAB_COLOR,\n borderColor: TAB_COLOR,\n \"&:first-of-type\": { borderEndStartRadius: theme.radii.base },\n },\n\n // Hide icon when editor is hovered and focused\n [`&:has($tabLabelEditor:hover) $tabIconContainer, &:has(.${toolbarTabEditorClasses.edit}) $tabIconContainer`]:\n {\n display: \"none\",\n },\n // Hide close when editor is focused\n [`&:has(.${toolbarTabEditorClasses.edit}) $closeIconContainer`]: {\n display: \"none\",\n },\n },\n tabLabel: {\n \"&:not($tabLabelEditor)\": {\n margin: theme.spacing(0, \"xs\"),\n },\n },\n tabLabelEditor: {\n color: theme.colors.primary,\n },\n tabContent: {\n position: \"relative\",\n height: TAB_HEIGHT,\n display: \"flex\",\n justifyContent: \"flex-start\",\n alignItems: \"center\",\n width: \"100%\",\n padding: TAB_PADDING,\n },\n tabIconContainer: {\n display: \"flex\",\n justifyContent: \"center\",\n alignItems: \"center\",\n width: TAB_ICON_SIZE,\n },\n closeIconContainer: {\n display: \"flex\",\n justifyContent: \"center\",\n alignItems: \"center\",\n marginLeft: \"auto\",\n marginRight: theme.spacing(-1),\n width: CLOSE_ICON_SIZE,\n \"&:hover\": {\n backgroundColor: theme.colors.containerBackgroundHover,\n borderRadius: theme.radii.circle,\n },\n },\n tabDivider: {\n position: \"absolute\",\n height: 18,\n width: 1,\n backgroundColor: theme.colors.atmo3,\n right: 0,\n },\n actionsContainer: {\n display: \"flex\",\n justifyContent: \"flex-end\",\n alignItems: \"center\",\n gap: theme.space.sm,\n },\n dropdownMenuContainer: {\n width: DROPDOWN_MENU_WIDTH,\n display: \"flex\",\n justifyContent: \"center\",\n },\n dropdownMenuListRoot: {\n maxHeight: 220,\n },\n },\n);\n"],"names":["toolbarTabEditorClasses"],"mappings":"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"}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -215,10 +215,10 @@ export declare interface HvCanvasToolbarTabsProps extends HvBaseProps<HTMLDivEle
|
|
|
215
215
|
defaultTabs?: ToolbarTabsTab[];
|
|
216
216
|
/** Id of the selected tab if it needs to be controlled. */
|
|
217
217
|
selectedTabId?: string;
|
|
218
|
-
/** Defines the icon to be placed before the label when a new tab is created. If not defined, no icon is used. */
|
|
218
|
+
/** Defines the icon to be placed before the label when a new tab is created through the "Create new" button. If not defined, no icon is used. */
|
|
219
219
|
icon?: React.ReactNode;
|
|
220
|
-
/**
|
|
221
|
-
|
|
220
|
+
/** Whether the tabs are editable or not. Default to `false`. */
|
|
221
|
+
disableTabEdit?: boolean;
|
|
222
222
|
/** Callback triggered when a tab changes/is clicked. */
|
|
223
223
|
onTabChange?: (event: React.SyntheticEvent | null, tabId: string | null) => void;
|
|
224
224
|
/** Callback triggered when the tabs change: new tab added, tab removed, tab reorder, and label updated. */
|
|
@@ -227,12 +227,16 @@ export declare interface HvCanvasToolbarTabsProps extends HvBaseProps<HTMLDivEle
|
|
|
227
227
|
labels?: Partial<typeof DEFAULT_LABELS_3>;
|
|
228
228
|
/** A Jss Object used to override or extend the styles applied. */
|
|
229
229
|
classes?: HvCanvasToolbarTabsClasses;
|
|
230
|
+
/** Whether the "Create new" button, which enables to create new tabs, is hidden. Defaults to `false`. */
|
|
231
|
+
hideCreateNew?: boolean;
|
|
230
232
|
}
|
|
231
233
|
|
|
232
234
|
declare interface ToolbarTabsTab {
|
|
233
235
|
id: string;
|
|
234
236
|
label: string;
|
|
235
237
|
icon?: React.ReactNode;
|
|
238
|
+
/** Whether the tab is fixed and can't be removed. Defaults to `false`, i.e., all tabs are removable by default. */
|
|
239
|
+
fixed?: boolean;
|
|
236
240
|
}
|
|
237
241
|
|
|
238
242
|
declare const useClasses: (classesProp?: Partial<Record<"content" | "root" | "tab" | "closed" | "minimized" | "multipleTabs" | "overflowing" | "tabTitle" | "tabsRoot" | "leftActions" | "rightActions" | "actionsDisabled", string>>, addStatic?: boolean) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hitachivantara/uikit-react-pentaho",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"author": "Hitachi Vantara UI Kit Team",
|
|
6
6
|
"description": "UI Kit Pentaho+ React components.",
|
|
@@ -30,9 +30,9 @@
|
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
32
|
"@emotion/css": "^11.11.0",
|
|
33
|
-
"@hitachivantara/uikit-react-core": "^5.
|
|
34
|
-
"@hitachivantara/uikit-react-icons": "^5.
|
|
35
|
-
"@hitachivantara/uikit-react-utils": "^0.2.
|
|
33
|
+
"@hitachivantara/uikit-react-core": "^5.73.1",
|
|
34
|
+
"@hitachivantara/uikit-react-icons": "^5.12.1",
|
|
35
|
+
"@hitachivantara/uikit-react-utils": "^0.2.6",
|
|
36
36
|
"@mui/base": "^5.0.0-beta.40",
|
|
37
37
|
"react-resize-detector": "^8.1.0"
|
|
38
38
|
},
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"access": "public",
|
|
44
44
|
"directory": "package"
|
|
45
45
|
},
|
|
46
|
-
"gitHead": "
|
|
46
|
+
"gitHead": "a3c24b6ba79a7c604c6fbaffd56f8c373958af27",
|
|
47
47
|
"exports": {
|
|
48
48
|
".": {
|
|
49
49
|
"types": "./dist/types/index.d.ts",
|