|
|
|
|
@@ -31,13 +31,15 @@ interface TabProps {
|
|
|
|
|
|
|
|
|
|
// TODO customise messages shown
|
|
|
|
|
interface Props {
|
|
|
|
|
label?: string;
|
|
|
|
|
activeIndex?: number;
|
|
|
|
|
activeHeader?: string;
|
|
|
|
|
headless?: boolean;
|
|
|
|
|
children: ReactElement<TabProps>[];
|
|
|
|
|
keepAllAlive?: boolean;
|
|
|
|
|
defaultExtension?: string;
|
|
|
|
|
forceDefaultExtension?: boolean;
|
|
|
|
|
appendDefaultExtension?: boolean;
|
|
|
|
|
allowedExtensions?: string[];
|
|
|
|
|
onCreateNewTab?: (name: string) => any;
|
|
|
|
|
onCloseTab?: (index: number, header?: string) => any;
|
|
|
|
|
onChangeActive?: (index: number, header?: string) => any;
|
|
|
|
|
@@ -46,6 +48,7 @@ interface Props {
|
|
|
|
|
export const Tab = (props: TabProps) => null;
|
|
|
|
|
|
|
|
|
|
export const Tabs = ({
|
|
|
|
|
label = "Tab",
|
|
|
|
|
children,
|
|
|
|
|
activeIndex,
|
|
|
|
|
activeHeader,
|
|
|
|
|
@@ -55,7 +58,8 @@ export const Tabs = ({
|
|
|
|
|
onCloseTab,
|
|
|
|
|
onChangeActive,
|
|
|
|
|
defaultExtension = "",
|
|
|
|
|
forceDefaultExtension,
|
|
|
|
|
appendDefaultExtension = false,
|
|
|
|
|
allowedExtensions,
|
|
|
|
|
}: Props) => {
|
|
|
|
|
const [active, setActive] = useState(activeIndex || 0);
|
|
|
|
|
const tabs: TabProps[] = children.map(elem => elem.props);
|
|
|
|
|
@@ -86,9 +90,13 @@ export const Tabs = ({
|
|
|
|
|
if (tabs.find(tab => tab.header === tabname)) {
|
|
|
|
|
return { error: "Name already exists." };
|
|
|
|
|
}
|
|
|
|
|
const ext = tabname.split(".").pop() || "";
|
|
|
|
|
if (allowedExtensions && !allowedExtensions.includes(ext)) {
|
|
|
|
|
return { error: "This file extension is not allowed!" };
|
|
|
|
|
}
|
|
|
|
|
return { error: null };
|
|
|
|
|
},
|
|
|
|
|
[tabs]
|
|
|
|
|
[allowedExtensions, tabs]
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const handleActiveChange = useCallback(
|
|
|
|
|
@@ -101,9 +109,11 @@ export const Tabs = ({
|
|
|
|
|
|
|
|
|
|
const handleCreateTab = useCallback(() => {
|
|
|
|
|
// add default extension in case omitted
|
|
|
|
|
let _tabname = tabname.includes(".") ? tabname : tabname + defaultExtension;
|
|
|
|
|
if (forceDefaultExtension && !_tabname.endsWith(defaultExtension)) {
|
|
|
|
|
_tabname = _tabname + defaultExtension;
|
|
|
|
|
let _tabname = tabname.includes(".")
|
|
|
|
|
? tabname
|
|
|
|
|
: `${tabname}.${defaultExtension}`;
|
|
|
|
|
if (appendDefaultExtension && !_tabname.endsWith(defaultExtension)) {
|
|
|
|
|
_tabname = `${_tabname}.${defaultExtension}`;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const chk = validateTabname(_tabname);
|
|
|
|
|
@@ -122,7 +132,7 @@ export const Tabs = ({
|
|
|
|
|
}, [
|
|
|
|
|
tabname,
|
|
|
|
|
defaultExtension,
|
|
|
|
|
forceDefaultExtension,
|
|
|
|
|
appendDefaultExtension,
|
|
|
|
|
validateTabname,
|
|
|
|
|
onCreateNewTab,
|
|
|
|
|
handleActiveChange,
|
|
|
|
|
@@ -206,13 +216,13 @@ export const Tabs = ({
|
|
|
|
|
size="sm"
|
|
|
|
|
css={{ alignItems: "center", px: "$2", mr: "$3" }}
|
|
|
|
|
>
|
|
|
|
|
<Plus size="16px" /> {tabs.length === 0 && "Add new tab"}
|
|
|
|
|
<Plus size="16px" /> {tabs.length === 0 && `Add new ${label.toLocaleLowerCase()}`}
|
|
|
|
|
</Button>
|
|
|
|
|
</DialogTrigger>
|
|
|
|
|
<DialogContent>
|
|
|
|
|
<DialogTitle>Create new tab</DialogTitle>
|
|
|
|
|
<DialogTitle>Create new {label.toLocaleLowerCase()}</DialogTitle>
|
|
|
|
|
<DialogDescription>
|
|
|
|
|
<Label>Tabname</Label>
|
|
|
|
|
<Label>{label} name</Label>
|
|
|
|
|
<Input
|
|
|
|
|
value={tabname}
|
|
|
|
|
onChange={e => setTabname(e.target.value)}
|
|
|
|
|
|