@antscorp/antsomi-ui 1.3.5-beta.273 → 1.3.5-beta.274

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.
Files changed (25) hide show
  1. package/es/components/atoms/ContentEditable/ContentEditable.d.ts +16 -0
  2. package/es/components/atoms/ContentEditable/ContentEditable.js +76 -0
  3. package/es/components/atoms/ContentEditable/index.d.ts +1 -0
  4. package/es/components/atoms/ContentEditable/index.js +1 -0
  5. package/es/components/atoms/ContentEditable/styled.d.ts +4 -0
  6. package/es/components/atoms/ContentEditable/styled.js +20 -0
  7. package/es/components/atoms/index.d.ts +1 -0
  8. package/es/components/atoms/index.js +1 -0
  9. package/es/components/molecules/ChartTab/ChartTab.d.ts +19 -0
  10. package/es/components/molecules/ChartTab/ChartTab.js +36 -0
  11. package/es/components/molecules/ChartTab/components/Item.d.ts +16 -0
  12. package/es/components/molecules/ChartTab/components/Item.js +47 -0
  13. package/es/components/molecules/ChartTab/components/styled.d.ts +3 -0
  14. package/es/components/molecules/ChartTab/components/styled.js +30 -0
  15. package/es/components/molecules/ChartTab/styled.d.ts +1 -0
  16. package/es/components/molecules/ChartTab/styled.js +23 -0
  17. package/es/components/molecules/EditorTab/EditorTab.d.ts +35 -0
  18. package/es/components/molecules/EditorTab/EditorTab.js +159 -0
  19. package/es/components/molecules/EditorTab/index.d.ts +1 -0
  20. package/es/components/molecules/EditorTab/index.js +1 -0
  21. package/es/components/molecules/EditorTab/styled.d.ts +1 -0
  22. package/es/components/molecules/EditorTab/styled.js +132 -0
  23. package/es/components/molecules/index.d.ts +1 -0
  24. package/es/components/molecules/index.js +1 -0
  25. package/package.json +4 -1
@@ -0,0 +1,16 @@
1
+ import React, { FocusEvent } from 'react';
2
+ import { TypographyProps } from 'antd';
3
+ import { EllipsisConfig } from 'antd/es/typography/Base';
4
+ interface ContentEditableProps extends Omit<TypographyProps['Text'], 'className' | '$$typeof'> {
5
+ onSave: (innerText: string, e?: FocusEvent<any>) => void;
6
+ value?: string;
7
+ isEdit?: boolean;
8
+ disabledBlur?: boolean;
9
+ maxLength?: number;
10
+ breakWord?: boolean;
11
+ regexPattern?: RegExp;
12
+ className?: string;
13
+ ellipsis?: EllipsisConfig;
14
+ }
15
+ export declare const ContentEditable: React.FC<React.PropsWithChildren<ContentEditableProps>>;
16
+ export {};
@@ -0,0 +1,76 @@
1
+ var __rest = (this && this.__rest) || function (s, e) {
2
+ var t = {};
3
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
4
+ t[p] = s[p];
5
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
6
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
7
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
8
+ t[p[i]] = s[p[i]];
9
+ }
10
+ return t;
11
+ };
12
+ import React, { useEffect, useRef, useState } from 'react';
13
+ import { ContentEditableWrapper } from './styled';
14
+ // NOTE: User can keypress when value reach max length
15
+ const IGNORE_KEY_CODE = [
16
+ 'Backspace',
17
+ 'Delete',
18
+ 'ArrowRight',
19
+ 'ArrowLeft',
20
+ 'ControlLeft',
21
+ 'ControlRight',
22
+ 'ShiftLeft',
23
+ 'ShiftRight',
24
+ 'Tab',
25
+ ];
26
+ export const ContentEditable = React.memo(props => {
27
+ const { value, onSave, className, isEdit, disabledBlur, maxLength, breakWord, regexPattern, ellipsis } = props, restProps = __rest(props, ["value", "onSave", "className", "isEdit", "disabledBlur", "maxLength", "breakWord", "regexPattern", "ellipsis"]);
28
+ const [isEditable, setIsEditable] = useState(false);
29
+ const elementRef = useRef(null);
30
+ useEffect(() => {
31
+ if (isEdit !== undefined) {
32
+ if (!isEdit)
33
+ onSave(elementRef && elementRef.current ? elementRef.current.innerText : '');
34
+ setIsEditable(isEdit);
35
+ }
36
+ // eslint-disable-next-line react-hooks/exhaustive-deps
37
+ }, [isEdit]);
38
+ return (React.createElement(ContentEditableWrapper, Object.assign({}, restProps, { "$breakWord": breakWord, ref: elementRef, className: `${isEditable ? 'editable' : ''} ${className || ''}`, suppressContentEditableWarning: true, contentEditable: true, spellCheck: false, ellipsis: { tooltip: true }, onClick: () => {
39
+ if (!isEditable) {
40
+ setIsEditable(true);
41
+ }
42
+ }, onBlur: (e) => {
43
+ if (disabledBlur)
44
+ return;
45
+ setIsEditable(false);
46
+ onSave(e.target.innerText, e);
47
+ }, onKeyDown: (e) => {
48
+ var _a;
49
+ if (!isEditable)
50
+ e.preventDefault();
51
+ // Check letters are selected => user want to replace it => allow edit
52
+ const selectedLetter = (_a = window.getSelection()) === null || _a === void 0 ? void 0 : _a.toString().length;
53
+ // Check user want select all text
54
+ const isSelectAll = e.code === 'KeyA' && e.ctrlKey;
55
+ if (!IGNORE_KEY_CODE.includes(e.code) &&
56
+ !selectedLetter &&
57
+ !isSelectAll &&
58
+ regexPattern &&
59
+ !e.code.match(regexPattern) &&
60
+ !isSelectAll)
61
+ e.preventDefault();
62
+ if (e.code === 'Enter') {
63
+ e.preventDefault();
64
+ onSave(e.currentTarget.innerText);
65
+ setIsEditable(false);
66
+ }
67
+ // NOTE: check current text length
68
+ if (maxLength &&
69
+ e.currentTarget.innerText.length >= maxLength &&
70
+ !IGNORE_KEY_CODE.includes(e.code) &&
71
+ !selectedLetter &&
72
+ !isSelectAll) {
73
+ e.preventDefault();
74
+ }
75
+ } }), value));
76
+ });
@@ -0,0 +1 @@
1
+ export { ContentEditable } from './ContentEditable';
@@ -0,0 +1 @@
1
+ export { ContentEditable } from './ContentEditable';
@@ -0,0 +1,4 @@
1
+ /// <reference types="react" />
2
+ export declare const ContentEditableWrapper: import("styled-components").StyledComponent<import("react").ForwardRefExoticComponent<import("antd/es/typography/Text").TextProps & import("react").RefAttributes<HTMLSpanElement>>, any, {
3
+ $breakWord?: boolean | undefined;
4
+ }, never>;
@@ -0,0 +1,20 @@
1
+ // Libraries
2
+ import styled from 'styled-components';
3
+ import { Typography } from '@antscorp/antsomi-ui/es/components';
4
+ export const ContentEditableWrapper = styled(Typography.Text) `
5
+ outline-width: 0;
6
+ caret-color: transparent;
7
+ border-radius: 4px;
8
+ display: inline-flex !important;
9
+ align-items: center !important;
10
+ word-break: ${props => (props.$breakWord ? 'break-word' : 'normal')};
11
+
12
+ &.editable {
13
+ outline: 2px solid var(--text-link-color);
14
+ outline-offset: -2px;
15
+ caret-color: unset;
16
+ }
17
+
18
+ padding: 4px;
19
+ /* font-weight: bold; */
20
+ `;
@@ -32,6 +32,7 @@ export { ScrollBox } from './ScrollBox';
32
32
  export { Rate } from './Rate';
33
33
  export { SliderV2 } from './SliderV2';
34
34
  export { InputDynamic } from './InputDynamic';
35
+ export { ContentEditable } from './ContentEditable';
35
36
  export * from './Flex';
36
37
  export * from './RateV2';
37
38
  export * from './PreviewTabs';
@@ -32,6 +32,7 @@ export { ScrollBox } from './ScrollBox';
32
32
  export { Rate } from './Rate';
33
33
  export { SliderV2 } from './SliderV2';
34
34
  export { InputDynamic } from './InputDynamic';
35
+ export { ContentEditable } from './ContentEditable';
35
36
  export * from './Flex';
36
37
  export * from './RateV2';
37
38
  export * from './PreviewTabs';
@@ -0,0 +1,19 @@
1
+ import React from 'react';
2
+ interface Page {
3
+ id: string;
4
+ name: string;
5
+ mode?: string;
6
+ }
7
+ interface EditorTabProps {
8
+ hiddenMenuOption?: boolean;
9
+ className?: string;
10
+ pages: Page[];
11
+ pageActiveId?: string;
12
+ onChangeActivePage?: (id: string) => void;
13
+ onDuplicate?: (id: string) => void;
14
+ onRemove?: (id: string) => void;
15
+ onSaveName?: (id: string, value: string) => void;
16
+ onDnD?: (page: Page[]) => void;
17
+ }
18
+ export declare const ChartTab: React.FC<EditorTabProps>;
19
+ export {};
@@ -0,0 +1,36 @@
1
+ // Lib
2
+ import React, { useState } from 'react';
3
+ // Utils
4
+ import { ChartTabStyled } from './styled';
5
+ import { Item } from './components/Item';
6
+ import { DndContext } from '@dnd-kit/core';
7
+ import { arrayMove, horizontalListSortingStrategy, SortableContext } from '@dnd-kit/sortable';
8
+ export const ChartTab = props => {
9
+ const { hiddenMenuOption, className, pages, pageActiveId, onChangeActivePage, onDuplicate, onRemove, onSaveName, onDnD, } = props;
10
+ const [activePage, setActivePage] = useState(pageActiveId || (pages === null || pages === void 0 ? void 0 : pages[0].id));
11
+ const [pageList, setPageList] = useState(pages);
12
+ const handleChangeActivePage = (id) => {
13
+ setActivePage(id);
14
+ onChangeActivePage === null || onChangeActivePage === void 0 ? void 0 : onChangeActivePage(id);
15
+ };
16
+ const handleDragEnd = (event) => {
17
+ const { active, over } = event;
18
+ if (active.id !== (over === null || over === void 0 ? void 0 : over.id)) {
19
+ setPageList(items => {
20
+ const oldIndex = items.findIndex(item => item.id === active.id);
21
+ const newIndex = items.findIndex(item => item.id === (over === null || over === void 0 ? void 0 : over.id));
22
+ const newArray = arrayMove(items, oldIndex, newIndex);
23
+ onDnD === null || onDnD === void 0 ? void 0 : onDnD(newArray);
24
+ return arrayMove(items, oldIndex, newIndex);
25
+ });
26
+ }
27
+ };
28
+ return (React.createElement(DndContext, { onDragEnd: handleDragEnd,
29
+ // HACK: trick as click tab => set new active page
30
+ onDragStart: event => {
31
+ var _a;
32
+ handleChangeActivePage((_a = event === null || event === void 0 ? void 0 : event.active) === null || _a === void 0 ? void 0 : _a.id);
33
+ } },
34
+ React.createElement(SortableContext, { items: pageList === null || pageList === void 0 ? void 0 : pageList.map(item => item.id), strategy: horizontalListSortingStrategy },
35
+ React.createElement(ChartTabStyled, { className: className || '' }, pageList.map((pageItem, index) => (React.createElement(Item, { key: pageItem.id, page: pageItem, hiddenMenuOption: hiddenMenuOption, isActive: activePage === pageItem.id, onDuplicate: onDuplicate, onRemove: onRemove, onSaveName: onSaveName })))))));
36
+ };
@@ -0,0 +1,16 @@
1
+ import React from 'react';
2
+ interface Page {
3
+ id: string;
4
+ name: string;
5
+ mode?: string;
6
+ }
7
+ interface ItemProps {
8
+ page: Page;
9
+ hiddenMenuOption?: boolean;
10
+ isActive?: boolean;
11
+ onSaveName?: (id: string, value: string) => void;
12
+ onDuplicate?: (id: string) => void;
13
+ onRemove?: (id: string) => void;
14
+ }
15
+ export declare const Item: React.FC<ItemProps>;
16
+ export {};
@@ -0,0 +1,47 @@
1
+ // Libraries
2
+ import React, { useState } from 'react';
3
+ import { useSortable } from '@dnd-kit/sortable';
4
+ import { CSS } from '@dnd-kit/utilities';
5
+ import Icon from '@antscorp/icons';
6
+ // Styles
7
+ import { ItemStyled } from './styled';
8
+ // Components
9
+ import { ContentEditable, Dropdown, Typography } from '@antscorp/antsomi-ui/es/components';
10
+ export const Item = (props) => {
11
+ const { page, hiddenMenuOption = false, isActive, onSaveName, onDuplicate, onRemove } = props;
12
+ const [isEditable, setIsEditable] = useState(false);
13
+ const { attributes, listeners, setNodeRef, transform, transition } = useSortable({ id: page.id });
14
+ const style = {
15
+ transform: CSS.Transform.toString(transform),
16
+ transition,
17
+ };
18
+ return (React.createElement("li", Object.assign({ id: page.id, ref: setNodeRef, style: style }, attributes, listeners),
19
+ React.createElement(ItemStyled, { id: page.id, "$isActive": isActive },
20
+ isEditable ? (React.createElement(ContentEditable, { value: page.name, onSave: newValue => {
21
+ setIsEditable(false);
22
+ onSaveName === null || onSaveName === void 0 ? void 0 : onSaveName(page.id, newValue);
23
+ } })) : (React.createElement(Typography.Text, { ellipsis: { tooltip: true } }, page.name)),
24
+ !hiddenMenuOption ? (React.createElement(Dropdown, { menu: {
25
+ items: [
26
+ { label: 'Rename', key: 'rename' },
27
+ { label: 'Duplicate', key: 'duplicate' },
28
+ { label: 'Remove', key: 'remove' },
29
+ ],
30
+ onClick: ({ key }) => {
31
+ switch (key) {
32
+ case 'rename':
33
+ setIsEditable(true);
34
+ break;
35
+ case 'duplicate':
36
+ onDuplicate === null || onDuplicate === void 0 ? void 0 : onDuplicate(page.id);
37
+ break;
38
+ case 'remove':
39
+ onRemove === null || onRemove === void 0 ? void 0 : onRemove(page.id);
40
+ break;
41
+ default:
42
+ break;
43
+ }
44
+ },
45
+ }, trigger: ['hover'], placement: "topLeft" },
46
+ React.createElement(Icon, { type: "icon-ants-three-dot-vertical", style: { cursor: 'pointer' } }))) : null)));
47
+ };
@@ -0,0 +1,3 @@
1
+ export declare const ItemStyled: import("styled-components").StyledComponent<"div", any, {
2
+ $isActive?: boolean | undefined;
3
+ }, never>;
@@ -0,0 +1,30 @@
1
+ var _a;
2
+ // Libraries
3
+ import styled from 'styled-components';
4
+ // Tokens
5
+ import { THEME } from '@antscorp/antsomi-ui/es/constants';
6
+ export const ItemStyled = styled.div `
7
+ box-sizing: border-box;
8
+ display: flex;
9
+ flex-wrap: nowrap;
10
+ gap: 8px;
11
+ align-items: center;
12
+ justify-content: space-between;
13
+
14
+ height: 32px;
15
+ min-width: 80px;
16
+ max-width: 130px;
17
+
18
+ background-color: ${props => { var _a; return (props.$isActive ? 'white' : (_a = THEME.token) === null || _a === void 0 ? void 0 : _a.bw2); }};
19
+ font-weight: ${props => (props.$isActive ? 500 : 400)};
20
+ padding: 6px 10px;
21
+
22
+ &:hover {
23
+ font-weight: 500;
24
+ background-color: ${(_a = THEME.token) === null || _a === void 0 ? void 0 : _a.blue} !important;
25
+ }
26
+
27
+ span[contenteditable='true'] {
28
+ flex: 1;
29
+ }
30
+ `;
@@ -0,0 +1 @@
1
+ export declare const ChartTabStyled: import("styled-components").StyledComponent<"ul", any, {}, never>;
@@ -0,0 +1,23 @@
1
+ import { globalToken } from '@antscorp/antsomi-ui/es/constants';
2
+ import styled from 'styled-components';
3
+ export const ChartTabStyled = styled.ul `
4
+ list-style-type: none;
5
+ display: flex;
6
+
7
+ & > li {
8
+ border: 1px solid #e5e5e5;
9
+ cursor: default;
10
+
11
+ &:first-child {
12
+ overflow: hidden;
13
+ border-top-left-radius: ${globalToken === null || globalToken === void 0 ? void 0 : globalToken.borderRadius}px;
14
+ border-bottom-left-radius: ${globalToken === null || globalToken === void 0 ? void 0 : globalToken.borderRadius}px;
15
+ /* border-top-left-radius: ${globalToken === null || globalToken === void 0 ? void 0 : globalToken.borderRadius}; */
16
+ }
17
+ &:last-child {
18
+ overflow: hidden;
19
+ border-top-right-radius: ${globalToken === null || globalToken === void 0 ? void 0 : globalToken.borderRadius}px;
20
+ border-bottom-right-radius: ${globalToken === null || globalToken === void 0 ? void 0 : globalToken.borderRadius}px;
21
+ }
22
+ }
23
+ `;
@@ -0,0 +1,35 @@
1
+ import React from 'react';
2
+ interface EditorTabItem {
3
+ showIcon?: boolean;
4
+ showDropdown?: boolean;
5
+ closeable?: boolean;
6
+ formatSelectedText: string;
7
+ formattedQuery: string;
8
+ id: string;
9
+ name: string;
10
+ query: string;
11
+ type: string;
12
+ selectedTextOut: string;
13
+ queryResult: any;
14
+ cursorSql?: string;
15
+ cursorSqlOut?: string;
16
+ refreshAndFocusId?: string;
17
+ }
18
+ interface EditorTabProps {
19
+ showArrow?: boolean;
20
+ showDropdown?: boolean;
21
+ disabledScroll?: boolean;
22
+ showComposeNewQuery?: boolean;
23
+ className?: string;
24
+ leftBlockClassName?: string;
25
+ tabItemClassName?: string;
26
+ listTab?: EditorTabItem[];
27
+ activeId?: string;
28
+ onActiveTab: (id: string) => void;
29
+ onCloseTab: (tab: EditorTabItem, index: number, newTabs: EditorTabItem[]) => void;
30
+ onConfigure: (id: string) => void;
31
+ onSaveName?: (id: string, value: string) => void;
32
+ handleAddTab: () => void;
33
+ }
34
+ export declare const EditorTab: React.FC<EditorTabProps>;
35
+ export {};
@@ -0,0 +1,159 @@
1
+ // Lib
2
+ import React, { useEffect, useMemo, useRef, useState } from 'react';
3
+ import classnames from 'classnames';
4
+ // Components
5
+ import Icon from '@antscorp/icons/main';
6
+ import { Button, Typography, Dropdown, ContentEditable } from '@antscorp/antsomi-ui/es/components';
7
+ // Styles
8
+ import { EditorTabStyled } from './styled';
9
+ // Utils
10
+ import { handleError } from '@antscorp/antsomi-ui/es/utils';
11
+ const PATH = 'src/components/EditorTab/index.jsx';
12
+ const constants = {
13
+ TAB_TYPE: {
14
+ QUERY: 'query',
15
+ TABLE_DETAIL: 'table-detail',
16
+ },
17
+ };
18
+ export const EditorTab = props => {
19
+ var _a;
20
+ const { listTab = [], activeId = '', showArrow, showDropdown, disabledScroll, onCloseTab, onActiveTab, handleAddTab, onConfigure, onSaveName, showComposeNewQuery, className, leftBlockClassName, tabItemClassName, } = props;
21
+ const [activeTabId, setActiveTabId] = useState(activeId || ((_a = listTab === null || listTab === void 0 ? void 0 : listTab[0]) === null || _a === void 0 ? void 0 : _a.id));
22
+ const [arrTabs, setArrTabs] = useState(listTab || []);
23
+ const [isEditable, setIsEditable] = useState();
24
+ // Ref
25
+ const leftBlockRef = useRef(null);
26
+ const activeTabIdx = useMemo(() => {
27
+ return arrTabs.findIndex(tab => tab.id === activeId);
28
+ }, [activeId]);
29
+ useEffect(() => {
30
+ if (listTab.length - arrTabs.length === 1) {
31
+ setActiveTabId(listTab[listTab.length - 1].id);
32
+ }
33
+ setArrTabs(listTab);
34
+ }, [listTab]);
35
+ useEffect(() => {
36
+ onActiveTab(activeTabId);
37
+ setTimeout(() => {
38
+ if (!disabledScroll) {
39
+ const tabEl = document.getElementById(`tab-${activeTabId}`);
40
+ if (tabEl) {
41
+ tabEl.scrollIntoView({ block: 'center', inline: 'center', behavior: 'smooth' });
42
+ }
43
+ }
44
+ }, 500);
45
+ }, [activeTabId]);
46
+ useEffect(() => {
47
+ if (activeId && activeTabId !== activeId) {
48
+ setActiveTabId(activeId);
49
+ }
50
+ }, [activeId]);
51
+ const handleAddNew = () => {
52
+ handleAddTab();
53
+ };
54
+ const handleCloseTab = (e, tab, idx) => {
55
+ e.stopPropagation();
56
+ if (arrTabs.length < 2) {
57
+ return;
58
+ }
59
+ if (activeTabId === tab.id) {
60
+ if (idx === arrTabs.length - 1) {
61
+ setActiveTabId(arrTabs[idx - 1].id);
62
+ }
63
+ else if (arrTabs.length > 1) {
64
+ setActiveTabId(arrTabs[idx + 1].id);
65
+ }
66
+ }
67
+ setArrTabs(prevTabs => {
68
+ const newTabs = [...prevTabs];
69
+ newTabs.splice(idx, 1);
70
+ onCloseTab(tab, idx, newTabs);
71
+ return newTabs;
72
+ });
73
+ };
74
+ const handleActiveTab = (tab, idx) => {
75
+ setActiveTabId(tab.id);
76
+ };
77
+ const onWheelLeftBlock = event => {
78
+ try {
79
+ if (!event.deltaY) {
80
+ return;
81
+ }
82
+ event.currentTarget.scrollLeft += event.deltaY + event.deltaX;
83
+ }
84
+ catch (error) {
85
+ handleError(error, {
86
+ path: PATH,
87
+ name: 'onWheelLeftBlock',
88
+ args: {},
89
+ });
90
+ }
91
+ };
92
+ const onClickArrow = (direction = 'left') => {
93
+ const idx = arrTabs.findIndex(tab => tab.id === activeTabId);
94
+ if (idx !== -1) {
95
+ switch (direction) {
96
+ case 'left':
97
+ if (idx === 0) {
98
+ return;
99
+ }
100
+ setActiveTabId(arrTabs[idx - 1].id);
101
+ break;
102
+ case 'right':
103
+ if (idx === arrTabs.length - 1) {
104
+ return;
105
+ }
106
+ setActiveTabId(arrTabs[idx + 1].id);
107
+ break;
108
+ }
109
+ }
110
+ };
111
+ return (React.createElement(EditorTabStyled, { className: className || '' },
112
+ showArrow && (React.createElement("div", { className: classnames('arrow-btn', {
113
+ '--disabled': activeTabIdx === 0,
114
+ }), onClick: () => onClickArrow('left') },
115
+ React.createElement(Icon, { type: "icon-ants-angle-left" }))),
116
+ React.createElement("div", { ref: leftBlockRef, className: classnames('left-block', leftBlockClassName), onWheel: onWheelLeftBlock }, arrTabs && arrTabs.length
117
+ ? arrTabs.map((tab, idx) => {
118
+ const { showIcon = true, closeable = true } = tab;
119
+ // const { showIcon = true, showDropdown = true, closeable = true } = tab;
120
+ return (React.createElement("div", { key: tab.id, id: `tab-${tab.id}`, onClick: () => handleActiveTab(tab, idx), className: classnames('tab-item', tabItemClassName, {
121
+ active: tab.id === activeTabId,
122
+ }) },
123
+ showIcon &&
124
+ (tab.type === constants.TAB_TYPE.QUERY ? (React.createElement(Icon, { type: "icon-ants-material-outline-manage-search", overlayStyle: { fontSize: 21 } })) : (React.createElement(Icon, { type: "icon-ants-table-vertical", overlayStyle: { fontSize: 21 } }))),
125
+ isEditable === tab.id ? (React.createElement(ContentEditable, { value: tab.name, onSave: newValue => {
126
+ setIsEditable(undefined);
127
+ onSaveName === null || onSaveName === void 0 ? void 0 : onSaveName(tab.id, newValue);
128
+ } })) : (React.createElement(Typography.Text, { ellipsis: { tooltip: true } }, tab.name)),
129
+ showDropdown ? (React.createElement(Dropdown, { menu: {
130
+ items: [
131
+ { label: 'Configure', key: 'configure' },
132
+ { label: 'Remove', key: 'remove' },
133
+ ],
134
+ onClick: ({ key, domEvent }) => {
135
+ switch (key) {
136
+ case 'configure':
137
+ console.log('click configure', domEvent);
138
+ setIsEditable(tab.id);
139
+ onConfigure === null || onConfigure === void 0 ? void 0 : onConfigure(tab.id);
140
+ break;
141
+ case 'remove':
142
+ handleCloseTab(domEvent, tab, idx);
143
+ break;
144
+ default:
145
+ break;
146
+ }
147
+ },
148
+ }, placement: "bottomRight", trigger: ['click'] },
149
+ React.createElement(Button, { icon: React.createElement(Icon, { type: "icon-ants-angle-left", overlayStyle: { fontSize: 12 } }), style: { transform: 'rotate(-90deg)' }, size: "small" }))) : closeable ? (React.createElement(Button, { icon: React.createElement(Icon, { type: "icon-ants-remove-slim", onClick: e => handleCloseTab(e, tab, idx), overlayStyle: { fontSize: 12 } }), size: "small" })) : null));
150
+ })
151
+ : null),
152
+ showArrow && (React.createElement("div", { className: classnames('arrow-btn', '--right', {
153
+ '--disabled': activeTabIdx === arrTabs.length - 1,
154
+ }), onClick: () => onClickArrow('right') },
155
+ React.createElement(Icon, { type: "icon-ants-angle-right" }))),
156
+ showComposeNewQuery && (React.createElement(Button, { onClick: handleAddNew, className: "new-query-btn" },
157
+ React.createElement(Icon, { type: "icon-ants-add-square" }),
158
+ "New query"))));
159
+ };
@@ -0,0 +1 @@
1
+ export { EditorTab } from './EditorTab';
@@ -0,0 +1 @@
1
+ export { EditorTab } from './EditorTab';
@@ -0,0 +1 @@
1
+ export declare const EditorTabStyled: import("styled-components").StyledComponent<"div", any, {}, never>;
@@ -0,0 +1,132 @@
1
+ var _a, _b, _c;
2
+ import styled from 'styled-components';
3
+ import { THEME } from '@antscorp/antsomi-ui/es/constants';
4
+ // const token = theme.getDesignToken(THEME);
5
+ export const EditorTabStyled = styled.div `
6
+ position: relative;
7
+ height: 40px;
8
+ display: flex;
9
+ align-items: center;
10
+
11
+ /* Styled for icon button */
12
+ button.antsomi-btn-icon-only.antsomi-btn-sm {
13
+ margin-left: auto;
14
+ border: none !important;
15
+ background-color: transparent !important;
16
+ flex-shrink: 0;
17
+ width: 20px !important;
18
+ height: 20px !important;
19
+ &:hover {
20
+ background-color: ${(_a = THEME.token) === null || _a === void 0 ? void 0 : _a.blue} !important;
21
+ }
22
+ }
23
+
24
+ .left-block {
25
+ position: relative;
26
+ height: 100%;
27
+ width: 100%;
28
+ flex-grow: 1;
29
+ flex-flow: nowrap;
30
+ display: flex;
31
+ align-items: center;
32
+ overflow-x: auto;
33
+ overflow-y: hidden;
34
+
35
+ font-size: 14px;
36
+ color: #222;
37
+
38
+ &::-webkit-scrollbar {
39
+ display: none;
40
+ }
41
+
42
+ .tab-item {
43
+ position: relative;
44
+ box-sizing: border-box;
45
+
46
+ display: flex;
47
+ align-items: center;
48
+ flex-shrink: 0;
49
+ gap: 7px;
50
+ width: 150px;
51
+ height: 40px;
52
+ padding: 0 10px;
53
+ overflow: hidden;
54
+ max-width: 200px;
55
+ background-color: ${(_b = THEME.token) === null || _b === void 0 ? void 0 : _b.bw2};
56
+
57
+ &:hover {
58
+ background-color: ${(_c = THEME.token) === null || _c === void 0 ? void 0 : _c.blue};
59
+ }
60
+
61
+ white-space: nowrap;
62
+
63
+ transition: background-color 300ms ease-in-out;
64
+ cursor: pointer;
65
+
66
+ i {
67
+ font-size: 20px;
68
+ color: #666;
69
+ }
70
+
71
+ &::after {
72
+ content: '';
73
+ position: absolute;
74
+ bottom: 0;
75
+ left: 0;
76
+ height: 3px;
77
+ width: 100%;
78
+ background-color: #1f5fac;
79
+
80
+ transform-origin: center;
81
+ transform: scaleX(0);
82
+ transition: transform 300ms ease-in-out;
83
+ }
84
+
85
+ &.active {
86
+ &::after {
87
+ transform: scaleX(1);
88
+ }
89
+ background-color: #fff;
90
+ }
91
+ }
92
+
93
+ ::-webkit-scrollbar {
94
+ -webkit-appearance: none;
95
+ display: none !important;
96
+ }
97
+ ::-webkit-scrollbar-thumb {
98
+ display: none !important;
99
+ }
100
+ }
101
+
102
+ button.new-query-btn {
103
+ margin-left: 10px;
104
+ border: none;
105
+ }
106
+
107
+ .arrow-btn {
108
+ /* Structure Block */
109
+ flex-shrink: 0;
110
+ height: 100%;
111
+ width: 40px;
112
+ display: flex;
113
+ align-items: center;
114
+ justify-content: center;
115
+ /* border-right: 1px solid #e0e0e0; */
116
+
117
+ /* Typography Block */
118
+ font-size: 12px;
119
+
120
+ cursor: pointer;
121
+
122
+ &.--right {
123
+ border-right: 1px solid #e0e0e0;
124
+ }
125
+
126
+ &.--disabled {
127
+ cursor: not-allowed;
128
+ pointer-events: none;
129
+ opacity: 0.7;
130
+ }
131
+ }
132
+ `;
@@ -52,6 +52,7 @@ export * from './Drawer';
52
52
  export * from './DrawerDetail';
53
53
  export { EditorScript } from './EditorScript';
54
54
  export { CalendarSelection, CalendarSelectionConstants } from './CalendarSelection';
55
+ export { EditorTab } from './EditorTab';
55
56
  export type { AdvancedPickerProps, TAdvancedPickerOption, TAdvancedRangePickerTimeRange, } from './DatePicker';
56
57
  export type { ColorPickerProps } from './ColorPicker';
57
58
  export type { AlignEditProps, AlignSettingProps } from './AlignSetting';
@@ -52,3 +52,4 @@ export * from './Drawer';
52
52
  export * from './DrawerDetail';
53
53
  export { EditorScript } from './EditorScript';
54
54
  export { CalendarSelection, CalendarSelectionConstants } from './CalendarSelection';
55
+ export { EditorTab } from './EditorTab';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@antscorp/antsomi-ui",
3
- "version": "1.3.5-beta.273",
3
+ "version": "1.3.5-beta.274",
4
4
  "description": "An enterprise-class UI design language and React UI library.",
5
5
  "sideEffects": [
6
6
  "dist/*",
@@ -63,6 +63,9 @@
63
63
  "@antscorp/icons": "^0.27.23",
64
64
  "@antscorp/image-editor": "1.0.2",
65
65
  "@antscorp/processing-notification": "^1.0.3",
66
+ "@dnd-kit/core": "^6.1.0",
67
+ "@dnd-kit/sortable": "^8.0.0",
68
+ "@dnd-kit/utilities": "^3.2.2",
66
69
  "@emotion/react": "^11.11.1",
67
70
  "@fortawesome/fontawesome-svg-core": "6.1.1",
68
71
  "@fortawesome/free-brands-svg-icons": "6.1.1",