var __extends = (this && this.__extends) || (function () {
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };
    return function (d, b) {
        if (typeof b !== "function" && b !== null)
            throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
var __assign = (this && this.__assign) || function () {
    __assign = Object.assign || function(t) {
        for (var s, i = 1, n = arguments.length; i < n; i++) {
            s = arguments[i];
            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
                t[p] = s[p];
        }
        return t;
    };
    return __assign.apply(this, arguments);
};
var __rest = (this && this.__rest) || function (s, e) {
    var t = {};
    for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
        t[p] = s[p];
    if (s != null && typeof Object.getOwnPropertySymbols === "function")
        for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
            if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
                t[p[i]] = s[p[i]];
        }
    return t;
};
import React, { forwardRef, } from 'react';
import { EditorContextProvider, ExecutionContextProvider, ExplorerContextProvider, HistoryContextProvider, SchemaContextProvider, StorageContextProvider, useAutoCompleteLeafs, useCopyQuery, useDragResize, useEditorContext, useExecutionContext, useExplorerContext, useHistoryContext, useMergeQuery, usePrettifyEditors, useSchemaContext, useStorageContext, } from '@graphiql/react';
import { ExecuteButton } from './ExecuteButton';
import { ToolbarButton } from './ToolbarButton';
import { ToolbarGroup } from './ToolbarGroup';
import { ToolbarMenu, ToolbarMenuItem } from './ToolbarMenu';
import { QueryEditor } from './QueryEditor';
import { VariableEditor } from './VariableEditor';
import { HeaderEditor } from './HeaderEditor';
import { ResultViewer } from './ResultViewer';
import { DocExplorer } from './DocExplorer';
import { QueryHistory } from './QueryHistory';
import find from '../utility/find';
import { formatError, formatResult } from '@graphiql/toolkit';
import { Tab, TabAddButton, Tabs } from './Tabs';
var majorVersion = parseInt(React.version.slice(0, 2), 10);
if (majorVersion < 16) {
    throw Error([
        'GraphiQL 0.18.0 and after is not compatible with React 15 or below.',
        'If you are using a CDN source (jsdelivr, unpkg, etc), follow this example:',
        'https://github.com/graphql/graphiql/blob/master/examples/graphiql-cdn/index.html#L49',
    ].join('\n'));
}
var GraphiQL = (function (_super) {
    __extends(GraphiQL, _super);
    function GraphiQL(props) {
        var _this = _super.call(this, props) || this;
        _this.ref = null;
        return _this;
    }
    GraphiQL.prototype.componentDidMount = function () {
        if (typeof window !== 'undefined') {
            window.g = this;
        }
    };
    GraphiQL.prototype.render = function () {
        var _this = this;
        return (React.createElement(GraphiQLProviders, __assign({}, this.props, { ref: function (node) {
                _this.ref = node;
            } })));
    };
    GraphiQL.prototype.getQueryEditor = function () {
        var _a;
        console.warn('The method `GraphiQL.getQueryEditor` is deprecated and will be removed in the next major version. To set the value of the editor you can use the `query` prop. To react on changes of the editor value you can pass a callback to the `onEditQuery` prop.');
        return ((_a = this.ref) === null || _a === void 0 ? void 0 : _a.getQueryEditor()) || null;
    };
    GraphiQL.prototype.getVariableEditor = function () {
        var _a;
        console.warn('The method `GraphiQL.getVariableEditor` is deprecated and will be removed in the next major version. To set the value of the editor you can use the `variables` prop. To react on changes of the editor value you can pass a callback to the `onEditVariables` prop.');
        return ((_a = this.ref) === null || _a === void 0 ? void 0 : _a.getVariableEditor()) || null;
    };
    GraphiQL.prototype.getHeaderEditor = function () {
        var _a;
        console.warn('The method `GraphiQL.getHeaderEditor` is deprecated and will be removed in the next major version. To set the value of the editor you can use the `headers` prop. To react on changes of the editor value you can pass a callback to the `onEditHeaders` prop.');
        return ((_a = this.ref) === null || _a === void 0 ? void 0 : _a.getHeaderEditor()) || null;
    };
    GraphiQL.prototype.refresh = function () {
        var _a;
        console.warn('The method `GraphiQL.refresh` is deprecated and will be removed in the next major version. Already now, all editors should automatically refresh when their size changes.');
        (_a = this.ref) === null || _a === void 0 ? void 0 : _a.refresh();
    };
    GraphiQL.prototype.autoCompleteLeafs = function () {
        var _a;
        console.warn('The method `GraphiQL.autoCompleteLeafs` is deprecated and will be removed in the next major version. Please switch to using the `autoCompleteLeafs` function provided by the `EditorContext` from the `@graphiql/react` package.');
        return (_a = this.ref) === null || _a === void 0 ? void 0 : _a.autoCompleteLeafs();
    };
    GraphiQL.formatResult = function (result) {
        console.warn('The function `GraphiQL.formatResult` is deprecated and will be removed in the next major version. Please switch to using the `formatResult` function provided by the `@graphiql/toolkit` package.');
        return formatResult(result);
    };
    GraphiQL.formatError = function (error) {
        console.warn('The function `GraphiQL.formatError` is deprecated and will be removed in the next major version. Please switch to using the `formatError` function provided by the `@graphiql/toolkit` package.');
        return formatError(error);
    };
    GraphiQL.Logo = GraphiQLLogo;
    GraphiQL.Toolbar = GraphiQLToolbar;
    GraphiQL.Footer = GraphiQLFooter;
    GraphiQL.QueryEditor = QueryEditor;
    GraphiQL.VariableEditor = VariableEditor;
    GraphiQL.HeaderEditor = HeaderEditor;
    GraphiQL.ResultViewer = ResultViewer;
    GraphiQL.Button = ToolbarButton;
    GraphiQL.ToolbarButton = ToolbarButton;
    GraphiQL.Group = ToolbarGroup;
    GraphiQL.Menu = ToolbarMenu;
    GraphiQL.MenuItem = ToolbarMenuItem;
    return GraphiQL;
}(React.Component));
export { GraphiQL };
var GraphiQLProviders = forwardRef(function GraphiQLProviders(_a, ref) {
    var dangerouslyAssumeSchemaIsValid = _a.dangerouslyAssumeSchemaIsValid, docExplorerOpen = _a.docExplorerOpen, externalFragments = _a.externalFragments, fetcher = _a.fetcher, inputValueDeprecation = _a.inputValueDeprecation, introspectionQueryName = _a.introspectionQueryName, maxHistoryLength = _a.maxHistoryLength, onEditOperationName = _a.onEditOperationName, onSchemaChange = _a.onSchemaChange, onToggleHistory = _a.onToggleHistory, onToggleDocs = _a.onToggleDocs, operationName = _a.operationName, storage = _a.storage, schema = _a.schema, schemaDescription = _a.schemaDescription, shouldPersistHeaders = _a.shouldPersistHeaders, validationRules = _a.validationRules, props = __rest(_a, ["dangerouslyAssumeSchemaIsValid", "docExplorerOpen", "externalFragments", "fetcher", "inputValueDeprecation", "introspectionQueryName", "maxHistoryLength", "onEditOperationName", "onSchemaChange", "onToggleHistory", "onToggleDocs", "operationName", "storage", "schema", "schemaDescription", "shouldPersistHeaders", "validationRules"]);
    if (typeof fetcher !== 'function') {
        throw new TypeError('GraphiQL requires a fetcher function.');
    }
    return (React.createElement(StorageContextProvider, { storage: storage },
        React.createElement(HistoryContextProvider, { maxHistoryLength: maxHistoryLength, onToggle: onToggleHistory },
            React.createElement(EditorContextProvider, { defaultQuery: props.defaultQuery, externalFragments: externalFragments, headers: props.headers, onEditOperationName: onEditOperationName, onTabChange: typeof props.tabs === 'object' ? props.tabs.onTabChange : undefined, query: props.query, shouldPersistHeaders: shouldPersistHeaders, validationRules: validationRules, variables: props.variables },
                React.createElement(SchemaContextProvider, { dangerouslyAssumeSchemaIsValid: dangerouslyAssumeSchemaIsValid, fetcher: fetcher, inputValueDeprecation: inputValueDeprecation, introspectionQueryName: introspectionQueryName, onSchemaChange: onSchemaChange, schema: schema, schemaDescription: schemaDescription },
                    React.createElement(ExecutionContextProvider, { fetcher: fetcher, operationName: operationName },
                        React.createElement(ExplorerContextProvider, { isVisible: docExplorerOpen, onToggleVisibility: onToggleDocs },
                            React.createElement(GraphiQLConsumeContexts, __assign({}, props, { ref: ref })))))))));
});
var GraphiQLConsumeContexts = forwardRef(function GraphiQLConsumeContexts(_a, ref) {
    var getDefaultFieldNames = _a.getDefaultFieldNames, props = __rest(_a, ["getDefaultFieldNames"]);
    var editorContext = useEditorContext({ nonNull: true });
    var executionContext = useExecutionContext({ nonNull: true });
    var explorerContext = useExplorerContext();
    var historyContext = useHistoryContext();
    var schemaContext = useSchemaContext({ nonNull: true });
    var storageContext = useStorageContext();
    var autoCompleteLeafs = useAutoCompleteLeafs({ getDefaultFieldNames: getDefaultFieldNames });
    var copy = useCopyQuery({ onCopyQuery: props.onCopyQuery });
    var merge = useMergeQuery();
    var prettify = usePrettifyEditors();
    var docResize = useDragResize({
        defaultSizeRelation: 3,
        direction: 'horizontal',
        initiallyHidden: (explorerContext === null || explorerContext === void 0 ? void 0 : explorerContext.isVisible) ? undefined : 'second',
        onHiddenElementChange: function (resizableElement) {
            if (resizableElement === 'second') {
                explorerContext === null || explorerContext === void 0 ? void 0 : explorerContext.hide();
            }
            else {
                explorerContext === null || explorerContext === void 0 ? void 0 : explorerContext.show();
            }
        },
        sizeThresholdSecond: 200,
        storageKey: 'docExplorerFlex',
    });
    var editorResize = useDragResize({
        direction: 'horizontal',
        storageKey: 'editorFlex',
    });
    var secondaryEditorResize = useDragResize({
        defaultSizeRelation: 3,
        direction: 'vertical',
        initiallyHidden: (function () {
            if (props.defaultVariableEditorOpen !== undefined) {
                return props.defaultVariableEditorOpen ? undefined : 'second';
            }
            if (props.defaultSecondaryEditorOpen !== undefined) {
                return props.defaultSecondaryEditorOpen ? undefined : 'second';
            }
            return editorContext.initialVariables || editorContext.initialHeaders
                ? undefined
                : 'second';
        })(),
        sizeThresholdSecond: 60,
        storageKey: 'secondaryEditorFlex',
    });
    return (React.createElement(GraphiQLWithContext, __assign({}, props, { editorContext: editorContext, executionContext: executionContext, explorerContext: explorerContext, historyContext: historyContext, schemaContext: schemaContext, storageContext: storageContext, autoCompleteLeafs: autoCompleteLeafs, copy: copy, merge: merge, prettify: prettify, docResize: docResize, editorResize: editorResize, secondaryEditorResize: secondaryEditorResize, ref: ref })));
});
var GraphiQLWithContext = (function (_super) {
    __extends(GraphiQLWithContext, _super);
    function GraphiQLWithContext(props) {
        var _this = _super.call(this, props) || this;
        _this.state = { activeSecondaryEditor: 'variable' };
        return _this;
    }
    GraphiQLWithContext.prototype.render = function () {
        var _this = this;
        var _a, _b, _c, _d;
        var children = React.Children.toArray(this.props.children);
        var logo = find(children, function (child) {
            return isChildComponentType(child, GraphiQL.Logo);
        }) || React.createElement(GraphiQL.Logo, null);
        var toolbar = find(children, function (child) {
            return isChildComponentType(child, GraphiQL.Toolbar);
        }) || (React.createElement(GraphiQL.Toolbar, null,
            React.createElement(ToolbarButton, { onClick: function () {
                    _this.props.prettify();
                }, title: "Prettify Query (Shift-Ctrl-P)", label: "Prettify" }),
            React.createElement(ToolbarButton, { onClick: function () {
                    _this.props.merge();
                }, title: "Merge Query (Shift-Ctrl-M)", label: "Merge" }),
            React.createElement(ToolbarButton, { onClick: function () {
                    _this.props.copy();
                }, title: "Copy Query (Shift-Ctrl-C)", label: "Copy" }),
            React.createElement(ToolbarButton, { onClick: function () { var _a; return (_a = _this.props.historyContext) === null || _a === void 0 ? void 0 : _a.toggle(); }, title: ((_a = this.props.historyContext) === null || _a === void 0 ? void 0 : _a.isVisible)
                    ? 'Hide History'
                    : 'Show History', label: "History" }),
            React.createElement(ToolbarButton, { onClick: function () { return _this.props.schemaContext.introspect(); }, title: "Fetch GraphQL schema using introspection (Shift-Ctrl-R)", label: "Introspect" }),
            ((_b = this.props.toolbar) === null || _b === void 0 ? void 0 : _b.additionalContent)
                ? this.props.toolbar.additionalContent
                : null));
        var footer = find(children, function (child) {
            return isChildComponentType(child, GraphiQL.Footer);
        });
        var headerEditorEnabled = (_c = this.props.headerEditorEnabled) !== null && _c !== void 0 ? _c : true;
        return (React.createElement("div", { "data-testid": "graphiql-container", className: "graphiql-container" },
            React.createElement("div", { ref: this.props.docResize.firstRef },
                ((_d = this.props.historyContext) === null || _d === void 0 ? void 0 : _d.isVisible) && (React.createElement("div", { className: "historyPaneWrap", style: { width: '230px', zIndex: 7 } },
                    React.createElement(QueryHistory, null))),
                React.createElement("div", { className: "editorWrap" },
                    React.createElement("div", { className: "topBarWrap" },
                        this.props.beforeTopBarContent,
                        React.createElement("div", { className: "topBar" },
                            logo,
                            React.createElement(ExecuteButton, null),
                            toolbar),
                        this.props.explorerContext &&
                            !this.props.explorerContext.isVisible && (React.createElement("button", { className: "docExplorerShow", onClick: function () {
                                var _a;
                                (_a = _this.props.explorerContext) === null || _a === void 0 ? void 0 : _a.show();
                                _this.props.docResize.setHiddenElement(null);
                            }, "aria-label": "Open Documentation Explorer" }, "Docs"))),
                    this.props.tabs ? (React.createElement(Tabs, { tabsProps: {
                            'aria-label': 'Select active operation',
                        } },
                        this.props.editorContext.tabs.map(function (tab, index) { return (React.createElement(Tab, { key: tab.id, isActive: index === _this.props.editorContext.activeTabIndex, title: tab.title, isCloseable: _this.props.editorContext.tabs.length > 1, onSelect: function () {
                                _this.props.executionContext.stop();
                                _this.props.editorContext.changeTab(index);
                            }, onClose: function () {
                                if (_this.props.editorContext.activeTabIndex === index) {
                                    _this.props.executionContext.stop();
                                }
                                _this.props.editorContext.closeTab(index);
                            }, tabProps: {
                                'aria-controls': 'sessionWrap',
                                id: "session-tab-".concat(index),
                            } })); }),
                        React.createElement(TabAddButton, { onClick: function () {
                                _this.props.editorContext.addTab();
                            } }))) : null,
                    React.createElement("div", { role: "tabpanel", id: "sessionWrap", className: "editorBar", "aria-labelledby": "session-tab-".concat(this.props.editorContext.activeTabIndex) },
                        React.createElement("div", { ref: this.props.editorResize.firstRef },
                            React.createElement("div", { className: "queryWrap" },
                                React.createElement("div", { ref: this.props.secondaryEditorResize.firstRef },
                                    React.createElement(QueryEditor, { editorTheme: this.props.editorTheme, onClickReference: function () {
                                            if (_this.props.docResize.hiddenElement === 'second') {
                                                _this.props.docResize.setHiddenElement(null);
                                            }
                                        }, keyMap: this.props.keyMap, onCopyQuery: this.props.onCopyQuery, onEdit: this.props.onEditQuery, readOnly: this.props.readOnly })),
                                React.createElement("div", { ref: this.props.secondaryEditorResize.dragBarRef },
                                    React.createElement("div", { className: "secondary-editor-title variable-editor-title", id: "secondary-editor-title" },
                                        React.createElement("div", { className: "variable-editor-title-text".concat(this.state.activeSecondaryEditor === 'variable'
                                                ? ' active'
                                                : ''), onClick: function () {
                                                if (_this.props.secondaryEditorResize.hiddenElement ===
                                                    'second') {
                                                    _this.props.secondaryEditorResize.setHiddenElement(null);
                                                }
                                                _this.setState({
                                                    activeSecondaryEditor: 'variable',
                                                }, function () {
                                                    var _a;
                                                    (_a = _this.props.editorContext.variableEditor) === null || _a === void 0 ? void 0 : _a.refresh();
                                                });
                                            } }, "Query Variables"),
                                        headerEditorEnabled && (React.createElement("div", { style: {
                                                marginLeft: '20px',
                                            }, className: "variable-editor-title-text".concat(this.state.activeSecondaryEditor === 'header'
                                                ? ' active'
                                                : ''), onClick: function () {
                                                if (_this.props.secondaryEditorResize.hiddenElement ===
                                                    'second') {
                                                    _this.props.secondaryEditorResize.setHiddenElement(null);
                                                }
                                                _this.setState({
                                                    activeSecondaryEditor: 'header',
                                                }, function () {
                                                    var _a;
                                                    (_a = _this.props.editorContext.headerEditor) === null || _a === void 0 ? void 0 : _a.refresh();
                                                });
                                            } }, "Request Headers")))),
                                React.createElement("div", { ref: this.props.secondaryEditorResize.secondRef },
                                    React.createElement("section", { className: "variable-editor secondary-editor", "aria-label": this.state.activeSecondaryEditor === 'variable'
                                            ? 'Query Variables'
                                            : 'Request Headers' },
                                        React.createElement(VariableEditor, { onEdit: this.props.onEditVariables, editorTheme: this.props.editorTheme, readOnly: this.props.readOnly, active: this.state.activeSecondaryEditor === 'variable', keyMap: this.props.keyMap }),
                                        headerEditorEnabled && (React.createElement(HeaderEditor, { active: this.state.activeSecondaryEditor === 'header', editorTheme: this.props.editorTheme, onEdit: this.props.onEditHeaders, readOnly: this.props.readOnly, keyMap: this.props.keyMap })))))),
                        React.createElement("div", { ref: this.props.editorResize.dragBarRef },
                            React.createElement("div", { className: "editor-drag-bar" })),
                        React.createElement("div", { ref: this.props.editorResize.secondRef },
                            React.createElement("div", { className: "resultWrap" },
                                this.props.executionContext.isFetching && (React.createElement("div", { className: "spinner-container" },
                                    React.createElement("div", { className: "spinner" }))),
                                React.createElement(ResultViewer, { value: this.props.response, editorTheme: this.props.editorTheme, ResponseTooltip: this.props.ResultsTooltip, keyMap: this.props.keyMap }),
                                footer))))),
            React.createElement("div", { ref: this.props.docResize.dragBarRef },
                React.createElement("div", { className: "docExplorerResizer" })),
            React.createElement("div", { ref: this.props.docResize.secondRef },
                React.createElement("div", { className: "docExplorerWrap" },
                    React.createElement(DocExplorer, { onClose: function () { return _this.props.docResize.setHiddenElement('second'); } })))));
    };
    GraphiQLWithContext.prototype.getQueryEditor = function () {
        return this.props.editorContext.queryEditor || null;
    };
    GraphiQLWithContext.prototype.getVariableEditor = function () {
        return this.props.editorContext.variableEditor || null;
    };
    GraphiQLWithContext.prototype.getHeaderEditor = function () {
        return this.props.editorContext.headerEditor || null;
    };
    GraphiQLWithContext.prototype.refresh = function () {
        var _a, _b, _c, _d;
        (_a = this.props.editorContext.queryEditor) === null || _a === void 0 ? void 0 : _a.refresh();
        (_b = this.props.editorContext.variableEditor) === null || _b === void 0 ? void 0 : _b.refresh();
        (_c = this.props.editorContext.headerEditor) === null || _c === void 0 ? void 0 : _c.refresh();
        (_d = this.props.editorContext.responseEditor) === null || _d === void 0 ? void 0 : _d.refresh();
    };
    GraphiQLWithContext.prototype.autoCompleteLeafs = function () {
        return this.props.autoCompleteLeafs();
    };
    return GraphiQLWithContext;
}(React.Component));
function GraphiQLLogo(props) {
    return (React.createElement("div", { className: "title" }, props.children || (React.createElement("span", null,
        "Graph",
        React.createElement("em", null, "i"),
        "QL"))));
}
GraphiQLLogo.displayName = 'GraphiQLLogo';
function GraphiQLToolbar(props) {
    return (React.createElement("div", { className: "toolbar", role: "toolbar", "aria-label": "Editor Commands" }, props.children));
}
GraphiQLToolbar.displayName = 'GraphiQLToolbar';
function GraphiQLFooter(props) {
    return React.createElement("div", { className: "footer" }, props.children);
}
GraphiQLFooter.displayName = 'GraphiQLFooter';
function isChildComponentType(child, component) {
    var _a;
    if (((_a = child === null || child === void 0 ? void 0 : child.type) === null || _a === void 0 ? void 0 : _a.displayName) &&
        child.type.displayName === component.displayName) {
        return true;
    }
    return child.type === component;
}
//# sourceMappingURL=GraphiQL.js.map