@vuu-ui/vuu-layout 0.8.83 → 0.8.85
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/cjs/layout-reducer/layoutUtils.js +1 -1
- package/cjs/layout-reducer/layoutUtils.js.map +1 -1
- package/cjs/stack/Stack.js +4 -3
- package/cjs/stack/Stack.js.map +1 -1
- package/esm/layout-reducer/layoutUtils.js +1 -1
- package/esm/layout-reducer/layoutUtils.js.map +1 -1
- package/esm/stack/Stack.js +4 -3
- package/esm/stack/Stack.js.map +1 -1
- package/package.json +8 -8
|
@@ -200,7 +200,7 @@ const layoutQuery = (query, path, layoutRoot) => {
|
|
|
200
200
|
}
|
|
201
201
|
};
|
|
202
202
|
const getDefaultTabLabel = (component, tabIndex, existingLabels = []) => {
|
|
203
|
-
let label = component.props?.title ?? component.props?.["data-tab-title"];
|
|
203
|
+
let label = component.props?.title ?? component.props?.["data-tab-title"] ?? existingLabels[tabIndex];
|
|
204
204
|
if (label) {
|
|
205
205
|
return label;
|
|
206
206
|
} else {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"layoutUtils.js","sources":["../../src/layout-reducer/layoutUtils.ts"],"sourcesContent":["import {\n LayoutJSON,\n LayoutModel,\n dimension,\n getLayoutComponent,\n isContainer,\n isLayoutComponent,\n uuid,\n} from \"@vuu-ui/vuu-utils\";\nimport React, { CSSProperties, ReactElement, cloneElement } from \"react\";\nimport { TabLabelFactory } from \"../stack\";\nimport {\n getPersistentState,\n hasPersistentState,\n setPersistentState,\n} from \"../use-persistent-state\";\nimport { expandFlex, followPathToParent, getProps, typeOf } from \"../utils\";\nimport { layoutType } from \"./layoutTypes\";\n\ninterface ComponentWithId {\n id: string;\n [key: string]: unknown;\n}\n\nexport const getManagedDimension = (\n style: CSSProperties,\n): [dimension, dimension] =>\n style.flexDirection === \"column\" ? [\"height\", \"width\"] : [\"width\", \"height\"];\n\nconst theKidHasNoStyle: CSSProperties = {};\n\nexport const applyLayoutProps = (component: ReactElement, path = \"0\") => {\n const [layoutProps, children] = getChildLayoutProps(\n typeOf(component) as string,\n component.props,\n path,\n );\n return React.cloneElement(component, layoutProps, children);\n};\n\nexport interface LayoutProps extends ComponentWithId {\n active?: number;\n \"data-path\"?: string;\n children?: ReactElement[];\n column?: boolean;\n dropTarget?: boolean;\n key: string;\n layout?: LayoutJSON;\n path?: string;\n resizeable?: boolean;\n style: CSSProperties;\n type?: string;\n version?: number;\n}\n\n/**\n * parse the declarative JSX and clone adding layout attributes\n */\nexport const cloneElementAddLayoutProps = (\n layoutElement: ReactElement,\n previousLayout?: ReactElement,\n): ReactElement => {\n const type = typeOf(layoutElement) as string;\n const [layoutProps, children] = getChildLayoutProps(\n type,\n layoutElement.props,\n \"0\",\n undefined,\n previousLayout,\n );\n return cloneElement(layoutElement, layoutProps, children);\n};\n\nexport const applyLayout = (\n type: layoutType,\n props: LayoutProps,\n previousLayout?: LayoutModel,\n): LayoutModel => {\n const [layoutProps, children] = getChildLayoutProps(\n type,\n props,\n \"0\",\n undefined,\n previousLayout,\n );\n return {\n ...props,\n ...layoutProps,\n type,\n children,\n };\n};\n\nfunction getLayoutProps(\n type: string,\n props: LayoutProps,\n path = \"0\",\n parentType: string | null = null,\n previousLayout?: LayoutModel,\n): LayoutProps {\n const {\n active: prevActive = 0,\n \"data-path\": dataPath,\n path: prevPath = dataPath,\n id: prevId,\n style: prevStyle,\n } = getProps(previousLayout);\n\n const prevMatch = typeOf(previousLayout) === type && path === prevPath;\n const id = prevMatch ? prevId : (props.id ?? uuid());\n const active = type === \"Stack\" ? (props.active ?? prevActive) : undefined;\n\n const key = id;\n const style = prevMatch ? prevStyle : getStyle(type, props, parentType);\n return isLayoutComponent(type)\n ? { id, key, path, style, type, active }\n : { id, key, style, \"data-path\": path };\n}\n\nfunction getChildLayoutProps(\n type: string,\n props: LayoutProps,\n path: string,\n parentType: string | null = null,\n previousLayout?: LayoutModel,\n): [LayoutProps, ReactElement[]] {\n const layoutProps = getLayoutProps(\n type,\n props,\n path,\n parentType,\n previousLayout,\n );\n\n if (props.layout && !previousLayout) {\n return [layoutProps, [layoutFromJson(props.layout, `${path}.0`)]];\n }\n\n const previousChildren =\n (previousLayout as any)?.children ?? previousLayout?.props?.children;\n const hasDynamicChildren = props.dropTarget && previousChildren;\n const children = hasDynamicChildren\n ? previousChildren\n : getLayoutChildren(type, props.children, path, previousChildren);\n return [layoutProps, children];\n}\n\nfunction getLayoutChildren(\n type: string,\n children?: ReactElement[],\n path = \"0\",\n previousChildren?: ReactElement[],\n) {\n const kids = Array.isArray(children)\n ? children\n : React.isValidElement(children)\n ? [children]\n : [];\n return isContainer(type)\n ? kids.map((child, i) => {\n const childType = typeOf(child) as string;\n const previousType = typeOf(previousChildren?.[i]);\n\n if (!previousType || childType === previousType) {\n const [layoutProps, children] = getChildLayoutProps(\n childType,\n child.props,\n `${path}.${i}`,\n type,\n previousChildren?.[i],\n );\n return React.cloneElement(child, layoutProps, children);\n }\n\n return previousChildren?.[i];\n })\n : children;\n}\n\nconst getStyle = (\n type: string,\n props: LayoutProps,\n parentType?: string | null,\n) => {\n let { style = theKidHasNoStyle } = props;\n if (type === \"Flexbox\") {\n style = {\n flexDirection: props.column ? \"column\" : \"row\",\n ...style,\n display: \"flex\",\n };\n }\n\n if (style.flex) {\n const { flex, ...otherStyles } = style;\n style = {\n ...otherStyles,\n ...expandFlex(typeof flex === \"number\" ? flex : 0),\n };\n } else if (parentType === \"Stack\") {\n style = {\n ...style,\n ...expandFlex(1),\n };\n } else if (\n parentType === \"Flexbox\" &&\n (style.width || style.height) &&\n style.flexBasis === undefined\n ) {\n style = {\n ...style,\n flexBasis: \"auto\",\n flexGrow: 0,\n flexShrink: 0,\n };\n }\n\n return style;\n};\n\nexport function layoutFromJson(\n { id = uuid(), type, children, props, state }: LayoutJSON,\n path: string,\n): ReactElement {\n const componentType = type.match(/^[a-z]/) ? type : getLayoutComponent(type);\n\n if (componentType === undefined) {\n throw Error(\n `layoutUtils unable to create component from JSON, unknown type ${type}`,\n );\n }\n\n if (state) {\n setPersistentState(id, state);\n }\n\n return React.createElement(\n componentType,\n {\n id,\n ...props,\n key: id,\n path,\n },\n children\n ? children.map((child, i) => layoutFromJson(child, `${path}.${i}`))\n : undefined,\n );\n}\n\nexport function layoutToJSON(component: ReactElement) {\n return componentToJson(component);\n}\n\nexport function componentToJson(component: ReactElement): LayoutJSON {\n const type = typeOf(component) as string;\n const { id, children, type: _omit, ...props } = getProps(component);\n\n const state = hasPersistentState(id) ? getPersistentState(id) : undefined;\n\n return {\n id,\n type,\n props: serializeProps(props as LayoutProps),\n state,\n children: React.Children.map(children, componentToJson),\n };\n}\n\nexport function serializeProps(props?: LayoutProps) {\n if (props) {\n const { path, ...otherProps } = props;\n const result: { [key: string]: any } = {};\n for (const [key, value] of Object.entries(otherProps)) {\n result[key] = serializeValue(value);\n }\n return result;\n }\n}\n\nfunction serializeValue(value: unknown): any {\n if (\n typeof value === \"string\" ||\n typeof value === \"number\" ||\n typeof value === \"boolean\"\n ) {\n return value;\n } else if (Array.isArray(value)) {\n return value.map(serializeValue);\n } else if (typeof value === \"object\" && value !== null) {\n const result: { [key: string]: any } = {};\n for (const [k, v] of Object.entries(value)) {\n result[k] = serializeValue(v);\n }\n return result;\n }\n}\n\n// This is experimental and the only query we support to start off with is\n// PARENT_CONTAINER\nexport type LayoutQuery = \"PARENT_CONTAINER\";\n\nexport const layoutQuery = (\n query: LayoutQuery,\n path?: string,\n layoutRoot?: ReactElement,\n) => {\n if (path && layoutRoot) {\n const parentElement = followPathToParent(layoutRoot, path);\n if (parentElement) {\n const { id: parentContainerId } = getProps(parentElement);\n const parentContainerType = typeOf(parentElement);\n return {\n parentContainerId,\n parentContainerType,\n };\n }\n return {\n parentContainerType: \"Stack\",\n parentContainerId: \"blah\",\n };\n }\n};\n\nexport const getDefaultTabLabel: TabLabelFactory = (\n component,\n tabIndex,\n existingLabels = [],\n): string => {\n let label = component.props?.title ?? component.props?.[\"data-tab-title\"];\n if (label) {\n return label;\n } else {\n let count = tabIndex;\n do {\n label = `Tab ${++count}`;\n } while (existingLabels.includes(label));\n return label;\n }\n};\n"],"names":["typeOf","cloneElement","getProps","uuid","isLayoutComponent","isContainer","children","expandFlex","getLayoutComponent","setPersistentState","hasPersistentState","getPersistentState","followPathToParent"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"layoutUtils.js","sources":["../../src/layout-reducer/layoutUtils.ts"],"sourcesContent":["import {\n LayoutJSON,\n LayoutModel,\n dimension,\n getLayoutComponent,\n isContainer,\n isLayoutComponent,\n uuid,\n} from \"@vuu-ui/vuu-utils\";\nimport React, { CSSProperties, ReactElement, cloneElement } from \"react\";\nimport { TabLabelFactory } from \"../stack\";\nimport {\n getPersistentState,\n hasPersistentState,\n setPersistentState,\n} from \"../use-persistent-state\";\nimport { expandFlex, followPathToParent, getProps, typeOf } from \"../utils\";\nimport { layoutType } from \"./layoutTypes\";\n\ninterface ComponentWithId {\n id: string;\n [key: string]: unknown;\n}\n\nexport const getManagedDimension = (\n style: CSSProperties,\n): [dimension, dimension] =>\n style.flexDirection === \"column\" ? [\"height\", \"width\"] : [\"width\", \"height\"];\n\nconst theKidHasNoStyle: CSSProperties = {};\n\nexport const applyLayoutProps = (component: ReactElement, path = \"0\") => {\n const [layoutProps, children] = getChildLayoutProps(\n typeOf(component) as string,\n component.props,\n path,\n );\n return React.cloneElement(component, layoutProps, children);\n};\n\nexport interface LayoutProps extends ComponentWithId {\n active?: number;\n \"data-path\"?: string;\n children?: ReactElement[];\n column?: boolean;\n dropTarget?: boolean;\n key: string;\n layout?: LayoutJSON;\n path?: string;\n resizeable?: boolean;\n style: CSSProperties;\n type?: string;\n version?: number;\n}\n\n/**\n * parse the declarative JSX and clone adding layout attributes\n */\nexport const cloneElementAddLayoutProps = (\n layoutElement: ReactElement,\n previousLayout?: ReactElement,\n): ReactElement => {\n const type = typeOf(layoutElement) as string;\n const [layoutProps, children] = getChildLayoutProps(\n type,\n layoutElement.props,\n \"0\",\n undefined,\n previousLayout,\n );\n return cloneElement(layoutElement, layoutProps, children);\n};\n\nexport const applyLayout = (\n type: layoutType,\n props: LayoutProps,\n previousLayout?: LayoutModel,\n): LayoutModel => {\n const [layoutProps, children] = getChildLayoutProps(\n type,\n props,\n \"0\",\n undefined,\n previousLayout,\n );\n return {\n ...props,\n ...layoutProps,\n type,\n children,\n };\n};\n\nfunction getLayoutProps(\n type: string,\n props: LayoutProps,\n path = \"0\",\n parentType: string | null = null,\n previousLayout?: LayoutModel,\n): LayoutProps {\n const {\n active: prevActive = 0,\n \"data-path\": dataPath,\n path: prevPath = dataPath,\n id: prevId,\n style: prevStyle,\n } = getProps(previousLayout);\n\n const prevMatch = typeOf(previousLayout) === type && path === prevPath;\n const id = prevMatch ? prevId : (props.id ?? uuid());\n const active = type === \"Stack\" ? (props.active ?? prevActive) : undefined;\n\n const key = id;\n const style = prevMatch ? prevStyle : getStyle(type, props, parentType);\n return isLayoutComponent(type)\n ? { id, key, path, style, type, active }\n : { id, key, style, \"data-path\": path };\n}\n\nfunction getChildLayoutProps(\n type: string,\n props: LayoutProps,\n path: string,\n parentType: string | null = null,\n previousLayout?: LayoutModel,\n): [LayoutProps, ReactElement[]] {\n const layoutProps = getLayoutProps(\n type,\n props,\n path,\n parentType,\n previousLayout,\n );\n\n if (props.layout && !previousLayout) {\n return [layoutProps, [layoutFromJson(props.layout, `${path}.0`)]];\n }\n\n const previousChildren =\n (previousLayout as any)?.children ?? previousLayout?.props?.children;\n const hasDynamicChildren = props.dropTarget && previousChildren;\n const children = hasDynamicChildren\n ? previousChildren\n : getLayoutChildren(type, props.children, path, previousChildren);\n return [layoutProps, children];\n}\n\nfunction getLayoutChildren(\n type: string,\n children?: ReactElement[],\n path = \"0\",\n previousChildren?: ReactElement[],\n) {\n const kids = Array.isArray(children)\n ? children\n : React.isValidElement(children)\n ? [children]\n : [];\n return isContainer(type)\n ? kids.map((child, i) => {\n const childType = typeOf(child) as string;\n const previousType = typeOf(previousChildren?.[i]);\n\n if (!previousType || childType === previousType) {\n const [layoutProps, children] = getChildLayoutProps(\n childType,\n child.props,\n `${path}.${i}`,\n type,\n previousChildren?.[i],\n );\n return React.cloneElement(child, layoutProps, children);\n }\n\n return previousChildren?.[i];\n })\n : children;\n}\n\nconst getStyle = (\n type: string,\n props: LayoutProps,\n parentType?: string | null,\n) => {\n let { style = theKidHasNoStyle } = props;\n if (type === \"Flexbox\") {\n style = {\n flexDirection: props.column ? \"column\" : \"row\",\n ...style,\n display: \"flex\",\n };\n }\n\n if (style.flex) {\n const { flex, ...otherStyles } = style;\n style = {\n ...otherStyles,\n ...expandFlex(typeof flex === \"number\" ? flex : 0),\n };\n } else if (parentType === \"Stack\") {\n style = {\n ...style,\n ...expandFlex(1),\n };\n } else if (\n parentType === \"Flexbox\" &&\n (style.width || style.height) &&\n style.flexBasis === undefined\n ) {\n style = {\n ...style,\n flexBasis: \"auto\",\n flexGrow: 0,\n flexShrink: 0,\n };\n }\n\n return style;\n};\n\nexport function layoutFromJson(\n { id = uuid(), type, children, props, state }: LayoutJSON,\n path: string,\n): ReactElement {\n const componentType = type.match(/^[a-z]/) ? type : getLayoutComponent(type);\n\n if (componentType === undefined) {\n throw Error(\n `layoutUtils unable to create component from JSON, unknown type ${type}`,\n );\n }\n\n if (state) {\n setPersistentState(id, state);\n }\n\n return React.createElement(\n componentType,\n {\n id,\n ...props,\n key: id,\n path,\n },\n children\n ? children.map((child, i) => layoutFromJson(child, `${path}.${i}`))\n : undefined,\n );\n}\n\nexport function layoutToJSON(component: ReactElement) {\n return componentToJson(component);\n}\n\nexport function componentToJson(component: ReactElement): LayoutJSON {\n const type = typeOf(component) as string;\n const { id, children, type: _omit, ...props } = getProps(component);\n\n const state = hasPersistentState(id) ? getPersistentState(id) : undefined;\n\n return {\n id,\n type,\n props: serializeProps(props as LayoutProps),\n state,\n children: React.Children.map(children, componentToJson),\n };\n}\n\nexport function serializeProps(props?: LayoutProps) {\n if (props) {\n const { path, ...otherProps } = props;\n const result: { [key: string]: any } = {};\n for (const [key, value] of Object.entries(otherProps)) {\n result[key] = serializeValue(value);\n }\n return result;\n }\n}\n\nfunction serializeValue(value: unknown): any {\n if (\n typeof value === \"string\" ||\n typeof value === \"number\" ||\n typeof value === \"boolean\"\n ) {\n return value;\n } else if (Array.isArray(value)) {\n return value.map(serializeValue);\n } else if (typeof value === \"object\" && value !== null) {\n const result: { [key: string]: any } = {};\n for (const [k, v] of Object.entries(value)) {\n result[k] = serializeValue(v);\n }\n return result;\n }\n}\n\n// This is experimental and the only query we support to start off with is\n// PARENT_CONTAINER\nexport type LayoutQuery = \"PARENT_CONTAINER\";\n\nexport const layoutQuery = (\n query: LayoutQuery,\n path?: string,\n layoutRoot?: ReactElement,\n) => {\n if (path && layoutRoot) {\n const parentElement = followPathToParent(layoutRoot, path);\n if (parentElement) {\n const { id: parentContainerId } = getProps(parentElement);\n const parentContainerType = typeOf(parentElement);\n return {\n parentContainerId,\n parentContainerType,\n };\n }\n return {\n parentContainerType: \"Stack\",\n parentContainerId: \"blah\",\n };\n }\n};\n\nexport const getDefaultTabLabel: TabLabelFactory = (\n component,\n tabIndex,\n existingLabels = [],\n): string => {\n let label =\n component.props?.title ??\n component.props?.[\"data-tab-title\"] ??\n existingLabels[tabIndex];\n if (label) {\n return label;\n } else {\n let count = tabIndex;\n do {\n label = `Tab ${++count}`;\n } while (existingLabels.includes(label));\n return label;\n }\n};\n"],"names":["typeOf","cloneElement","getProps","uuid","isLayoutComponent","isContainer","children","expandFlex","getLayoutComponent","setPersistentState","hasPersistentState","getPersistentState","followPathToParent"],"mappings":"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"}
|
package/cjs/stack/Stack.js
CHANGED
|
@@ -53,7 +53,7 @@ const Stack = React.forwardRef(function Stack2({
|
|
|
53
53
|
window: targetWindow
|
|
54
54
|
});
|
|
55
55
|
const id = vuuUtils.useId(idProp);
|
|
56
|
-
const
|
|
56
|
+
const tabLabelsRef = React.useRef([]);
|
|
57
57
|
const {
|
|
58
58
|
allowCloseTab,
|
|
59
59
|
allowRenameTab,
|
|
@@ -74,14 +74,15 @@ const Stack = React.forwardRef(function Stack2({
|
|
|
74
74
|
}
|
|
75
75
|
return null;
|
|
76
76
|
};
|
|
77
|
+
tabLabelsRef.current.length = 0;
|
|
77
78
|
const renderTabs = () => getChildElements(children).map((child2, idx) => {
|
|
78
79
|
const {
|
|
79
80
|
closeable = allowCloseTab,
|
|
80
81
|
id: childId = `${id}-${idx}`,
|
|
81
82
|
"data-tab-location": tabLocation
|
|
82
83
|
} = child2.props;
|
|
83
|
-
const label = getTabLabel(child2, idx,
|
|
84
|
-
|
|
84
|
+
const label = getTabLabel(child2, idx, tabLabelsRef.current);
|
|
85
|
+
tabLabelsRef.current.push(label);
|
|
85
86
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
86
87
|
vuuUiControls.Tab,
|
|
87
88
|
{
|
package/cjs/stack/Stack.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Stack.js","sources":["../../src/stack/Stack.tsx"],"sourcesContent":["import { Tab, Tabstrip, TabstripProps } from \"@vuu-ui/vuu-ui-controls\";\nimport { useId } from \"@vuu-ui/vuu-utils\";\nimport cx from \"clsx\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport React, {\n ForwardedRef,\n forwardRef,\n ReactElement,\n ReactNode,\n useCallback,\n useRef,\n} from \"react\";\nimport { getDefaultTabLabel } from \"../layout-reducer\";\nimport { StackProps } from \"./stackTypes\";\n\nimport stackCss from \"./Stack.css\";\n\nconst classBase = \"vuuTabs\";\n\nconst getDefaultTabIcon = () => undefined;\n\nconst getChildElements = <T extends ReactElement = ReactElement>(\n children: ReactNode,\n): T[] => {\n const elements: T[] = [];\n React.Children.forEach(children, (child) => {\n if (React.isValidElement(child)) {\n elements.push(child as T);\n } else {\n console.warn(`Stack has unexpected child element type`);\n }\n });\n return elements;\n};\n\nconst DefaultTabstripProps: Partial<TabstripProps> = {\n allowAddTab: false,\n allowCloseTab: false,\n allowRenameTab: false,\n};\n\nexport const Stack = forwardRef(function Stack(\n {\n TabstripProps = DefaultTabstripProps,\n active = 0,\n children,\n className: classNameProp,\n getTabIcon = getDefaultTabIcon,\n getTabLabel = getDefaultTabLabel,\n id: idProp,\n keyBoardActivation = \"manual\",\n // onMouseDown,\n onAddTab,\n onMoveTab,\n onTabClose,\n onTabEdit,\n onTabSelectionChanged,\n showTabs = \"top\",\n style,\n }: StackProps,\n ref: ForwardedRef<HTMLDivElement>,\n) {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-stack\",\n css: stackCss,\n window: targetWindow,\n });\n\n const id = useId(idProp);\n const
|
|
1
|
+
{"version":3,"file":"Stack.js","sources":["../../src/stack/Stack.tsx"],"sourcesContent":["import { Tab, Tabstrip, TabstripProps } from \"@vuu-ui/vuu-ui-controls\";\nimport { useId } from \"@vuu-ui/vuu-utils\";\nimport cx from \"clsx\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport React, {\n ForwardedRef,\n forwardRef,\n ReactElement,\n ReactNode,\n useCallback,\n useRef,\n} from \"react\";\nimport { getDefaultTabLabel } from \"../layout-reducer\";\nimport { StackProps } from \"./stackTypes\";\n\nimport stackCss from \"./Stack.css\";\n\nconst classBase = \"vuuTabs\";\n\nconst getDefaultTabIcon = () => undefined;\n\nconst getChildElements = <T extends ReactElement = ReactElement>(\n children: ReactNode,\n): T[] => {\n const elements: T[] = [];\n React.Children.forEach(children, (child) => {\n if (React.isValidElement(child)) {\n elements.push(child as T);\n } else {\n console.warn(`Stack has unexpected child element type`);\n }\n });\n return elements;\n};\n\nconst DefaultTabstripProps: Partial<TabstripProps> = {\n allowAddTab: false,\n allowCloseTab: false,\n allowRenameTab: false,\n};\n\nexport const Stack = forwardRef(function Stack(\n {\n TabstripProps = DefaultTabstripProps,\n active = 0,\n children,\n className: classNameProp,\n getTabIcon = getDefaultTabIcon,\n getTabLabel = getDefaultTabLabel,\n id: idProp,\n keyBoardActivation = \"manual\",\n // onMouseDown,\n onAddTab,\n onMoveTab,\n onTabClose,\n onTabEdit,\n onTabSelectionChanged,\n showTabs = \"top\",\n style,\n }: StackProps,\n ref: ForwardedRef<HTMLDivElement>,\n) {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-stack\",\n css: stackCss,\n window: targetWindow,\n });\n\n const id = useId(idProp);\n const tabLabelsRef = useRef<string[]>([]);\n const {\n allowCloseTab,\n allowRenameTab,\n className: tabstripClassName,\n } = TabstripProps;\n\n const handleExitEditMode = useCallback(\n (\n _oldText: string,\n newText: string,\n _allowDeactivation: boolean,\n tabIndex: number,\n ) => {\n onTabEdit?.(tabIndex, newText);\n },\n [onTabEdit],\n );\n\n const activeChild = () => {\n //TODO need to inject an id if child does not have one, so we can\n // establish the aria-controls relationship. In a Vuu layout, there\n // will always be an id.\n if (React.isValidElement(children)) {\n return children;\n }\n if (Array.isArray(children)) {\n return children[active] ?? null;\n }\n return null;\n };\n\n // The list of existing Tab Labels is required only when assigning a default label\n // to a new Tab. We rebuild on each render\n tabLabelsRef.current.length = 0;\n\n const renderTabs = () =>\n getChildElements(children).map((child, idx) => {\n const {\n closeable = allowCloseTab,\n id: childId = `${id}-${idx}`,\n \"data-tab-location\": tabLocation,\n } = child.props;\n const label = getTabLabel(child, idx, tabLabelsRef.current);\n tabLabelsRef.current.push(label);\n return (\n <Tab\n ariaControls={childId}\n data-icon={getTabIcon(child, idx)}\n key={childId}\n id={`${childId}-tab`}\n index={idx}\n label={label}\n location={tabLocation}\n closeable={closeable}\n editable={allowRenameTab}\n />\n );\n });\n\n const child = activeChild();\n const isHorizontal = showTabs === \"left\" || showTabs === \"right\";\n const tabstripOrientation = isHorizontal ? \"vertical\" : \"horizontal\";\n\n return (\n <div\n className={cx(classBase, classNameProp, {\n [`${classBase}-horizontal`]: isHorizontal,\n })}\n style={style}\n id={id}\n ref={ref}\n >\n {showTabs ? (\n <Tabstrip\n aria-label=\"data tabs\"\n {...TabstripProps}\n activeTabIndex={\n TabstripProps?.activeTabIndex ?? (child === null ? -1 : active)\n }\n allowDragDrop={TabstripProps.allowDragDrop !== false}\n animateSelectionThumb\n className={cx(\"vuuTabHeader\", tabstripClassName)}\n keyBoardActivation={keyBoardActivation}\n onActiveChange={onTabSelectionChanged}\n onAddTab={onAddTab}\n onCloseTab={onTabClose}\n onExitEditMode={handleExitEditMode}\n onMoveTab={onMoveTab}\n orientation={tabstripOrientation}\n >\n {renderTabs()}\n </Tabstrip>\n ) : null}\n <div\n aria-labelledby={`${id}-${active}`}\n className={`${classBase}-tabPanel`}\n role=\"tabpanel\"\n >\n {child}\n </div>\n </div>\n );\n});\nStack.displayName = \"Stack\";\n"],"names":["forwardRef","Stack","TabstripProps","getDefaultTabLabel","useWindow","useComponentCssInjection","stackCss","useId","useRef","useCallback","child","jsx","Tab","jsxs","Tabstrip"],"mappings":"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"}
|
|
@@ -198,7 +198,7 @@ const layoutQuery = (query, path, layoutRoot) => {
|
|
|
198
198
|
}
|
|
199
199
|
};
|
|
200
200
|
const getDefaultTabLabel = (component, tabIndex, existingLabels = []) => {
|
|
201
|
-
let label = component.props?.title ?? component.props?.["data-tab-title"];
|
|
201
|
+
let label = component.props?.title ?? component.props?.["data-tab-title"] ?? existingLabels[tabIndex];
|
|
202
202
|
if (label) {
|
|
203
203
|
return label;
|
|
204
204
|
} else {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"layoutUtils.js","sources":["../../src/layout-reducer/layoutUtils.ts"],"sourcesContent":["import {\n LayoutJSON,\n LayoutModel,\n dimension,\n getLayoutComponent,\n isContainer,\n isLayoutComponent,\n uuid,\n} from \"@vuu-ui/vuu-utils\";\nimport React, { CSSProperties, ReactElement, cloneElement } from \"react\";\nimport { TabLabelFactory } from \"../stack\";\nimport {\n getPersistentState,\n hasPersistentState,\n setPersistentState,\n} from \"../use-persistent-state\";\nimport { expandFlex, followPathToParent, getProps, typeOf } from \"../utils\";\nimport { layoutType } from \"./layoutTypes\";\n\ninterface ComponentWithId {\n id: string;\n [key: string]: unknown;\n}\n\nexport const getManagedDimension = (\n style: CSSProperties,\n): [dimension, dimension] =>\n style.flexDirection === \"column\" ? [\"height\", \"width\"] : [\"width\", \"height\"];\n\nconst theKidHasNoStyle: CSSProperties = {};\n\nexport const applyLayoutProps = (component: ReactElement, path = \"0\") => {\n const [layoutProps, children] = getChildLayoutProps(\n typeOf(component) as string,\n component.props,\n path,\n );\n return React.cloneElement(component, layoutProps, children);\n};\n\nexport interface LayoutProps extends ComponentWithId {\n active?: number;\n \"data-path\"?: string;\n children?: ReactElement[];\n column?: boolean;\n dropTarget?: boolean;\n key: string;\n layout?: LayoutJSON;\n path?: string;\n resizeable?: boolean;\n style: CSSProperties;\n type?: string;\n version?: number;\n}\n\n/**\n * parse the declarative JSX and clone adding layout attributes\n */\nexport const cloneElementAddLayoutProps = (\n layoutElement: ReactElement,\n previousLayout?: ReactElement,\n): ReactElement => {\n const type = typeOf(layoutElement) as string;\n const [layoutProps, children] = getChildLayoutProps(\n type,\n layoutElement.props,\n \"0\",\n undefined,\n previousLayout,\n );\n return cloneElement(layoutElement, layoutProps, children);\n};\n\nexport const applyLayout = (\n type: layoutType,\n props: LayoutProps,\n previousLayout?: LayoutModel,\n): LayoutModel => {\n const [layoutProps, children] = getChildLayoutProps(\n type,\n props,\n \"0\",\n undefined,\n previousLayout,\n );\n return {\n ...props,\n ...layoutProps,\n type,\n children,\n };\n};\n\nfunction getLayoutProps(\n type: string,\n props: LayoutProps,\n path = \"0\",\n parentType: string | null = null,\n previousLayout?: LayoutModel,\n): LayoutProps {\n const {\n active: prevActive = 0,\n \"data-path\": dataPath,\n path: prevPath = dataPath,\n id: prevId,\n style: prevStyle,\n } = getProps(previousLayout);\n\n const prevMatch = typeOf(previousLayout) === type && path === prevPath;\n const id = prevMatch ? prevId : (props.id ?? uuid());\n const active = type === \"Stack\" ? (props.active ?? prevActive) : undefined;\n\n const key = id;\n const style = prevMatch ? prevStyle : getStyle(type, props, parentType);\n return isLayoutComponent(type)\n ? { id, key, path, style, type, active }\n : { id, key, style, \"data-path\": path };\n}\n\nfunction getChildLayoutProps(\n type: string,\n props: LayoutProps,\n path: string,\n parentType: string | null = null,\n previousLayout?: LayoutModel,\n): [LayoutProps, ReactElement[]] {\n const layoutProps = getLayoutProps(\n type,\n props,\n path,\n parentType,\n previousLayout,\n );\n\n if (props.layout && !previousLayout) {\n return [layoutProps, [layoutFromJson(props.layout, `${path}.0`)]];\n }\n\n const previousChildren =\n (previousLayout as any)?.children ?? previousLayout?.props?.children;\n const hasDynamicChildren = props.dropTarget && previousChildren;\n const children = hasDynamicChildren\n ? previousChildren\n : getLayoutChildren(type, props.children, path, previousChildren);\n return [layoutProps, children];\n}\n\nfunction getLayoutChildren(\n type: string,\n children?: ReactElement[],\n path = \"0\",\n previousChildren?: ReactElement[],\n) {\n const kids = Array.isArray(children)\n ? children\n : React.isValidElement(children)\n ? [children]\n : [];\n return isContainer(type)\n ? kids.map((child, i) => {\n const childType = typeOf(child) as string;\n const previousType = typeOf(previousChildren?.[i]);\n\n if (!previousType || childType === previousType) {\n const [layoutProps, children] = getChildLayoutProps(\n childType,\n child.props,\n `${path}.${i}`,\n type,\n previousChildren?.[i],\n );\n return React.cloneElement(child, layoutProps, children);\n }\n\n return previousChildren?.[i];\n })\n : children;\n}\n\nconst getStyle = (\n type: string,\n props: LayoutProps,\n parentType?: string | null,\n) => {\n let { style = theKidHasNoStyle } = props;\n if (type === \"Flexbox\") {\n style = {\n flexDirection: props.column ? \"column\" : \"row\",\n ...style,\n display: \"flex\",\n };\n }\n\n if (style.flex) {\n const { flex, ...otherStyles } = style;\n style = {\n ...otherStyles,\n ...expandFlex(typeof flex === \"number\" ? flex : 0),\n };\n } else if (parentType === \"Stack\") {\n style = {\n ...style,\n ...expandFlex(1),\n };\n } else if (\n parentType === \"Flexbox\" &&\n (style.width || style.height) &&\n style.flexBasis === undefined\n ) {\n style = {\n ...style,\n flexBasis: \"auto\",\n flexGrow: 0,\n flexShrink: 0,\n };\n }\n\n return style;\n};\n\nexport function layoutFromJson(\n { id = uuid(), type, children, props, state }: LayoutJSON,\n path: string,\n): ReactElement {\n const componentType = type.match(/^[a-z]/) ? type : getLayoutComponent(type);\n\n if (componentType === undefined) {\n throw Error(\n `layoutUtils unable to create component from JSON, unknown type ${type}`,\n );\n }\n\n if (state) {\n setPersistentState(id, state);\n }\n\n return React.createElement(\n componentType,\n {\n id,\n ...props,\n key: id,\n path,\n },\n children\n ? children.map((child, i) => layoutFromJson(child, `${path}.${i}`))\n : undefined,\n );\n}\n\nexport function layoutToJSON(component: ReactElement) {\n return componentToJson(component);\n}\n\nexport function componentToJson(component: ReactElement): LayoutJSON {\n const type = typeOf(component) as string;\n const { id, children, type: _omit, ...props } = getProps(component);\n\n const state = hasPersistentState(id) ? getPersistentState(id) : undefined;\n\n return {\n id,\n type,\n props: serializeProps(props as LayoutProps),\n state,\n children: React.Children.map(children, componentToJson),\n };\n}\n\nexport function serializeProps(props?: LayoutProps) {\n if (props) {\n const { path, ...otherProps } = props;\n const result: { [key: string]: any } = {};\n for (const [key, value] of Object.entries(otherProps)) {\n result[key] = serializeValue(value);\n }\n return result;\n }\n}\n\nfunction serializeValue(value: unknown): any {\n if (\n typeof value === \"string\" ||\n typeof value === \"number\" ||\n typeof value === \"boolean\"\n ) {\n return value;\n } else if (Array.isArray(value)) {\n return value.map(serializeValue);\n } else if (typeof value === \"object\" && value !== null) {\n const result: { [key: string]: any } = {};\n for (const [k, v] of Object.entries(value)) {\n result[k] = serializeValue(v);\n }\n return result;\n }\n}\n\n// This is experimental and the only query we support to start off with is\n// PARENT_CONTAINER\nexport type LayoutQuery = \"PARENT_CONTAINER\";\n\nexport const layoutQuery = (\n query: LayoutQuery,\n path?: string,\n layoutRoot?: ReactElement,\n) => {\n if (path && layoutRoot) {\n const parentElement = followPathToParent(layoutRoot, path);\n if (parentElement) {\n const { id: parentContainerId } = getProps(parentElement);\n const parentContainerType = typeOf(parentElement);\n return {\n parentContainerId,\n parentContainerType,\n };\n }\n return {\n parentContainerType: \"Stack\",\n parentContainerId: \"blah\",\n };\n }\n};\n\nexport const getDefaultTabLabel: TabLabelFactory = (\n component,\n tabIndex,\n existingLabels = [],\n): string => {\n let label = component.props?.title ?? component.props?.[\"data-tab-title\"];\n if (label) {\n return label;\n } else {\n let count = tabIndex;\n do {\n label = `Tab ${++count}`;\n } while (existingLabels.includes(label));\n return label;\n }\n};\n"],"names":["children"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"layoutUtils.js","sources":["../../src/layout-reducer/layoutUtils.ts"],"sourcesContent":["import {\n LayoutJSON,\n LayoutModel,\n dimension,\n getLayoutComponent,\n isContainer,\n isLayoutComponent,\n uuid,\n} from \"@vuu-ui/vuu-utils\";\nimport React, { CSSProperties, ReactElement, cloneElement } from \"react\";\nimport { TabLabelFactory } from \"../stack\";\nimport {\n getPersistentState,\n hasPersistentState,\n setPersistentState,\n} from \"../use-persistent-state\";\nimport { expandFlex, followPathToParent, getProps, typeOf } from \"../utils\";\nimport { layoutType } from \"./layoutTypes\";\n\ninterface ComponentWithId {\n id: string;\n [key: string]: unknown;\n}\n\nexport const getManagedDimension = (\n style: CSSProperties,\n): [dimension, dimension] =>\n style.flexDirection === \"column\" ? [\"height\", \"width\"] : [\"width\", \"height\"];\n\nconst theKidHasNoStyle: CSSProperties = {};\n\nexport const applyLayoutProps = (component: ReactElement, path = \"0\") => {\n const [layoutProps, children] = getChildLayoutProps(\n typeOf(component) as string,\n component.props,\n path,\n );\n return React.cloneElement(component, layoutProps, children);\n};\n\nexport interface LayoutProps extends ComponentWithId {\n active?: number;\n \"data-path\"?: string;\n children?: ReactElement[];\n column?: boolean;\n dropTarget?: boolean;\n key: string;\n layout?: LayoutJSON;\n path?: string;\n resizeable?: boolean;\n style: CSSProperties;\n type?: string;\n version?: number;\n}\n\n/**\n * parse the declarative JSX and clone adding layout attributes\n */\nexport const cloneElementAddLayoutProps = (\n layoutElement: ReactElement,\n previousLayout?: ReactElement,\n): ReactElement => {\n const type = typeOf(layoutElement) as string;\n const [layoutProps, children] = getChildLayoutProps(\n type,\n layoutElement.props,\n \"0\",\n undefined,\n previousLayout,\n );\n return cloneElement(layoutElement, layoutProps, children);\n};\n\nexport const applyLayout = (\n type: layoutType,\n props: LayoutProps,\n previousLayout?: LayoutModel,\n): LayoutModel => {\n const [layoutProps, children] = getChildLayoutProps(\n type,\n props,\n \"0\",\n undefined,\n previousLayout,\n );\n return {\n ...props,\n ...layoutProps,\n type,\n children,\n };\n};\n\nfunction getLayoutProps(\n type: string,\n props: LayoutProps,\n path = \"0\",\n parentType: string | null = null,\n previousLayout?: LayoutModel,\n): LayoutProps {\n const {\n active: prevActive = 0,\n \"data-path\": dataPath,\n path: prevPath = dataPath,\n id: prevId,\n style: prevStyle,\n } = getProps(previousLayout);\n\n const prevMatch = typeOf(previousLayout) === type && path === prevPath;\n const id = prevMatch ? prevId : (props.id ?? uuid());\n const active = type === \"Stack\" ? (props.active ?? prevActive) : undefined;\n\n const key = id;\n const style = prevMatch ? prevStyle : getStyle(type, props, parentType);\n return isLayoutComponent(type)\n ? { id, key, path, style, type, active }\n : { id, key, style, \"data-path\": path };\n}\n\nfunction getChildLayoutProps(\n type: string,\n props: LayoutProps,\n path: string,\n parentType: string | null = null,\n previousLayout?: LayoutModel,\n): [LayoutProps, ReactElement[]] {\n const layoutProps = getLayoutProps(\n type,\n props,\n path,\n parentType,\n previousLayout,\n );\n\n if (props.layout && !previousLayout) {\n return [layoutProps, [layoutFromJson(props.layout, `${path}.0`)]];\n }\n\n const previousChildren =\n (previousLayout as any)?.children ?? previousLayout?.props?.children;\n const hasDynamicChildren = props.dropTarget && previousChildren;\n const children = hasDynamicChildren\n ? previousChildren\n : getLayoutChildren(type, props.children, path, previousChildren);\n return [layoutProps, children];\n}\n\nfunction getLayoutChildren(\n type: string,\n children?: ReactElement[],\n path = \"0\",\n previousChildren?: ReactElement[],\n) {\n const kids = Array.isArray(children)\n ? children\n : React.isValidElement(children)\n ? [children]\n : [];\n return isContainer(type)\n ? kids.map((child, i) => {\n const childType = typeOf(child) as string;\n const previousType = typeOf(previousChildren?.[i]);\n\n if (!previousType || childType === previousType) {\n const [layoutProps, children] = getChildLayoutProps(\n childType,\n child.props,\n `${path}.${i}`,\n type,\n previousChildren?.[i],\n );\n return React.cloneElement(child, layoutProps, children);\n }\n\n return previousChildren?.[i];\n })\n : children;\n}\n\nconst getStyle = (\n type: string,\n props: LayoutProps,\n parentType?: string | null,\n) => {\n let { style = theKidHasNoStyle } = props;\n if (type === \"Flexbox\") {\n style = {\n flexDirection: props.column ? \"column\" : \"row\",\n ...style,\n display: \"flex\",\n };\n }\n\n if (style.flex) {\n const { flex, ...otherStyles } = style;\n style = {\n ...otherStyles,\n ...expandFlex(typeof flex === \"number\" ? flex : 0),\n };\n } else if (parentType === \"Stack\") {\n style = {\n ...style,\n ...expandFlex(1),\n };\n } else if (\n parentType === \"Flexbox\" &&\n (style.width || style.height) &&\n style.flexBasis === undefined\n ) {\n style = {\n ...style,\n flexBasis: \"auto\",\n flexGrow: 0,\n flexShrink: 0,\n };\n }\n\n return style;\n};\n\nexport function layoutFromJson(\n { id = uuid(), type, children, props, state }: LayoutJSON,\n path: string,\n): ReactElement {\n const componentType = type.match(/^[a-z]/) ? type : getLayoutComponent(type);\n\n if (componentType === undefined) {\n throw Error(\n `layoutUtils unable to create component from JSON, unknown type ${type}`,\n );\n }\n\n if (state) {\n setPersistentState(id, state);\n }\n\n return React.createElement(\n componentType,\n {\n id,\n ...props,\n key: id,\n path,\n },\n children\n ? children.map((child, i) => layoutFromJson(child, `${path}.${i}`))\n : undefined,\n );\n}\n\nexport function layoutToJSON(component: ReactElement) {\n return componentToJson(component);\n}\n\nexport function componentToJson(component: ReactElement): LayoutJSON {\n const type = typeOf(component) as string;\n const { id, children, type: _omit, ...props } = getProps(component);\n\n const state = hasPersistentState(id) ? getPersistentState(id) : undefined;\n\n return {\n id,\n type,\n props: serializeProps(props as LayoutProps),\n state,\n children: React.Children.map(children, componentToJson),\n };\n}\n\nexport function serializeProps(props?: LayoutProps) {\n if (props) {\n const { path, ...otherProps } = props;\n const result: { [key: string]: any } = {};\n for (const [key, value] of Object.entries(otherProps)) {\n result[key] = serializeValue(value);\n }\n return result;\n }\n}\n\nfunction serializeValue(value: unknown): any {\n if (\n typeof value === \"string\" ||\n typeof value === \"number\" ||\n typeof value === \"boolean\"\n ) {\n return value;\n } else if (Array.isArray(value)) {\n return value.map(serializeValue);\n } else if (typeof value === \"object\" && value !== null) {\n const result: { [key: string]: any } = {};\n for (const [k, v] of Object.entries(value)) {\n result[k] = serializeValue(v);\n }\n return result;\n }\n}\n\n// This is experimental and the only query we support to start off with is\n// PARENT_CONTAINER\nexport type LayoutQuery = \"PARENT_CONTAINER\";\n\nexport const layoutQuery = (\n query: LayoutQuery,\n path?: string,\n layoutRoot?: ReactElement,\n) => {\n if (path && layoutRoot) {\n const parentElement = followPathToParent(layoutRoot, path);\n if (parentElement) {\n const { id: parentContainerId } = getProps(parentElement);\n const parentContainerType = typeOf(parentElement);\n return {\n parentContainerId,\n parentContainerType,\n };\n }\n return {\n parentContainerType: \"Stack\",\n parentContainerId: \"blah\",\n };\n }\n};\n\nexport const getDefaultTabLabel: TabLabelFactory = (\n component,\n tabIndex,\n existingLabels = [],\n): string => {\n let label =\n component.props?.title ??\n component.props?.[\"data-tab-title\"] ??\n existingLabels[tabIndex];\n if (label) {\n return label;\n } else {\n let count = tabIndex;\n do {\n label = `Tab ${++count}`;\n } while (existingLabels.includes(label));\n return label;\n }\n};\n"],"names":["children"],"mappings":"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"}
|
package/esm/stack/Stack.js
CHANGED
|
@@ -51,7 +51,7 @@ const Stack = forwardRef(function Stack2({
|
|
|
51
51
|
window: targetWindow
|
|
52
52
|
});
|
|
53
53
|
const id = useId(idProp);
|
|
54
|
-
const
|
|
54
|
+
const tabLabelsRef = useRef([]);
|
|
55
55
|
const {
|
|
56
56
|
allowCloseTab,
|
|
57
57
|
allowRenameTab,
|
|
@@ -72,14 +72,15 @@ const Stack = forwardRef(function Stack2({
|
|
|
72
72
|
}
|
|
73
73
|
return null;
|
|
74
74
|
};
|
|
75
|
+
tabLabelsRef.current.length = 0;
|
|
75
76
|
const renderTabs = () => getChildElements(children).map((child2, idx) => {
|
|
76
77
|
const {
|
|
77
78
|
closeable = allowCloseTab,
|
|
78
79
|
id: childId = `${id}-${idx}`,
|
|
79
80
|
"data-tab-location": tabLocation
|
|
80
81
|
} = child2.props;
|
|
81
|
-
const label = getTabLabel(child2, idx,
|
|
82
|
-
|
|
82
|
+
const label = getTabLabel(child2, idx, tabLabelsRef.current);
|
|
83
|
+
tabLabelsRef.current.push(label);
|
|
83
84
|
return /* @__PURE__ */ jsx(
|
|
84
85
|
Tab,
|
|
85
86
|
{
|
package/esm/stack/Stack.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Stack.js","sources":["../../src/stack/Stack.tsx"],"sourcesContent":["import { Tab, Tabstrip, TabstripProps } from \"@vuu-ui/vuu-ui-controls\";\nimport { useId } from \"@vuu-ui/vuu-utils\";\nimport cx from \"clsx\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport React, {\n ForwardedRef,\n forwardRef,\n ReactElement,\n ReactNode,\n useCallback,\n useRef,\n} from \"react\";\nimport { getDefaultTabLabel } from \"../layout-reducer\";\nimport { StackProps } from \"./stackTypes\";\n\nimport stackCss from \"./Stack.css\";\n\nconst classBase = \"vuuTabs\";\n\nconst getDefaultTabIcon = () => undefined;\n\nconst getChildElements = <T extends ReactElement = ReactElement>(\n children: ReactNode,\n): T[] => {\n const elements: T[] = [];\n React.Children.forEach(children, (child) => {\n if (React.isValidElement(child)) {\n elements.push(child as T);\n } else {\n console.warn(`Stack has unexpected child element type`);\n }\n });\n return elements;\n};\n\nconst DefaultTabstripProps: Partial<TabstripProps> = {\n allowAddTab: false,\n allowCloseTab: false,\n allowRenameTab: false,\n};\n\nexport const Stack = forwardRef(function Stack(\n {\n TabstripProps = DefaultTabstripProps,\n active = 0,\n children,\n className: classNameProp,\n getTabIcon = getDefaultTabIcon,\n getTabLabel = getDefaultTabLabel,\n id: idProp,\n keyBoardActivation = \"manual\",\n // onMouseDown,\n onAddTab,\n onMoveTab,\n onTabClose,\n onTabEdit,\n onTabSelectionChanged,\n showTabs = \"top\",\n style,\n }: StackProps,\n ref: ForwardedRef<HTMLDivElement>,\n) {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-stack\",\n css: stackCss,\n window: targetWindow,\n });\n\n const id = useId(idProp);\n const
|
|
1
|
+
{"version":3,"file":"Stack.js","sources":["../../src/stack/Stack.tsx"],"sourcesContent":["import { Tab, Tabstrip, TabstripProps } from \"@vuu-ui/vuu-ui-controls\";\nimport { useId } from \"@vuu-ui/vuu-utils\";\nimport cx from \"clsx\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport React, {\n ForwardedRef,\n forwardRef,\n ReactElement,\n ReactNode,\n useCallback,\n useRef,\n} from \"react\";\nimport { getDefaultTabLabel } from \"../layout-reducer\";\nimport { StackProps } from \"./stackTypes\";\n\nimport stackCss from \"./Stack.css\";\n\nconst classBase = \"vuuTabs\";\n\nconst getDefaultTabIcon = () => undefined;\n\nconst getChildElements = <T extends ReactElement = ReactElement>(\n children: ReactNode,\n): T[] => {\n const elements: T[] = [];\n React.Children.forEach(children, (child) => {\n if (React.isValidElement(child)) {\n elements.push(child as T);\n } else {\n console.warn(`Stack has unexpected child element type`);\n }\n });\n return elements;\n};\n\nconst DefaultTabstripProps: Partial<TabstripProps> = {\n allowAddTab: false,\n allowCloseTab: false,\n allowRenameTab: false,\n};\n\nexport const Stack = forwardRef(function Stack(\n {\n TabstripProps = DefaultTabstripProps,\n active = 0,\n children,\n className: classNameProp,\n getTabIcon = getDefaultTabIcon,\n getTabLabel = getDefaultTabLabel,\n id: idProp,\n keyBoardActivation = \"manual\",\n // onMouseDown,\n onAddTab,\n onMoveTab,\n onTabClose,\n onTabEdit,\n onTabSelectionChanged,\n showTabs = \"top\",\n style,\n }: StackProps,\n ref: ForwardedRef<HTMLDivElement>,\n) {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-stack\",\n css: stackCss,\n window: targetWindow,\n });\n\n const id = useId(idProp);\n const tabLabelsRef = useRef<string[]>([]);\n const {\n allowCloseTab,\n allowRenameTab,\n className: tabstripClassName,\n } = TabstripProps;\n\n const handleExitEditMode = useCallback(\n (\n _oldText: string,\n newText: string,\n _allowDeactivation: boolean,\n tabIndex: number,\n ) => {\n onTabEdit?.(tabIndex, newText);\n },\n [onTabEdit],\n );\n\n const activeChild = () => {\n //TODO need to inject an id if child does not have one, so we can\n // establish the aria-controls relationship. In a Vuu layout, there\n // will always be an id.\n if (React.isValidElement(children)) {\n return children;\n }\n if (Array.isArray(children)) {\n return children[active] ?? null;\n }\n return null;\n };\n\n // The list of existing Tab Labels is required only when assigning a default label\n // to a new Tab. We rebuild on each render\n tabLabelsRef.current.length = 0;\n\n const renderTabs = () =>\n getChildElements(children).map((child, idx) => {\n const {\n closeable = allowCloseTab,\n id: childId = `${id}-${idx}`,\n \"data-tab-location\": tabLocation,\n } = child.props;\n const label = getTabLabel(child, idx, tabLabelsRef.current);\n tabLabelsRef.current.push(label);\n return (\n <Tab\n ariaControls={childId}\n data-icon={getTabIcon(child, idx)}\n key={childId}\n id={`${childId}-tab`}\n index={idx}\n label={label}\n location={tabLocation}\n closeable={closeable}\n editable={allowRenameTab}\n />\n );\n });\n\n const child = activeChild();\n const isHorizontal = showTabs === \"left\" || showTabs === \"right\";\n const tabstripOrientation = isHorizontal ? \"vertical\" : \"horizontal\";\n\n return (\n <div\n className={cx(classBase, classNameProp, {\n [`${classBase}-horizontal`]: isHorizontal,\n })}\n style={style}\n id={id}\n ref={ref}\n >\n {showTabs ? (\n <Tabstrip\n aria-label=\"data tabs\"\n {...TabstripProps}\n activeTabIndex={\n TabstripProps?.activeTabIndex ?? (child === null ? -1 : active)\n }\n allowDragDrop={TabstripProps.allowDragDrop !== false}\n animateSelectionThumb\n className={cx(\"vuuTabHeader\", tabstripClassName)}\n keyBoardActivation={keyBoardActivation}\n onActiveChange={onTabSelectionChanged}\n onAddTab={onAddTab}\n onCloseTab={onTabClose}\n onExitEditMode={handleExitEditMode}\n onMoveTab={onMoveTab}\n orientation={tabstripOrientation}\n >\n {renderTabs()}\n </Tabstrip>\n ) : null}\n <div\n aria-labelledby={`${id}-${active}`}\n className={`${classBase}-tabPanel`}\n role=\"tabpanel\"\n >\n {child}\n </div>\n </div>\n );\n});\nStack.displayName = \"Stack\";\n"],"names":["Stack","TabstripProps","child"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "0.8.
|
|
2
|
+
"version": "0.8.85",
|
|
3
3
|
"description": "VUU Layout Components",
|
|
4
4
|
"author": "heswell",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"types": "types/index.d.ts",
|
|
7
7
|
"devDependencies": {
|
|
8
|
-
"@vuu-ui/vuu-data-types": "0.8.
|
|
9
|
-
"@vuu-ui/vuu-filter-types": "0.8.
|
|
8
|
+
"@vuu-ui/vuu-data-types": "0.8.85",
|
|
9
|
+
"@vuu-ui/vuu-filter-types": "0.8.85"
|
|
10
10
|
},
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"@salt-ds/core": "1.34.0",
|
|
13
13
|
"@salt-ds/styles": "0.2.1",
|
|
14
14
|
"@salt-ds/window": "0.1.1",
|
|
15
|
-
"@vuu-ui/vuu-filters": "0.8.
|
|
16
|
-
"@vuu-ui/vuu-popups": "0.8.
|
|
17
|
-
"@vuu-ui/vuu-table": "0.8.
|
|
18
|
-
"@vuu-ui/vuu-ui-controls": "0.8.
|
|
19
|
-
"@vuu-ui/vuu-utils": "0.8.
|
|
15
|
+
"@vuu-ui/vuu-filters": "0.8.85",
|
|
16
|
+
"@vuu-ui/vuu-popups": "0.8.85",
|
|
17
|
+
"@vuu-ui/vuu-table": "0.8.85",
|
|
18
|
+
"@vuu-ui/vuu-ui-controls": "0.8.85",
|
|
19
|
+
"@vuu-ui/vuu-utils": "0.8.85"
|
|
20
20
|
},
|
|
21
21
|
"peerDependencies": {
|
|
22
22
|
"clsx": "^2.0.0",
|