@pdfme/ui 0.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. package/README.md +9 -0
  2. package/__mocks__/assetsTransformer.js +7 -0
  3. package/__mocks__/form-render.js +7 -0
  4. package/__mocks__/lucide-react.js +19 -0
  5. package/dist/index.es.js +159393 -0
  6. package/dist/index.umd.js +1041 -0
  7. package/dist/types/__tests__/assets/helper.d.ts +3 -0
  8. package/dist/types/__tests__/components/Designer.test.d.ts +1 -0
  9. package/dist/types/__tests__/components/PluginIcon.test.d.ts +1 -0
  10. package/dist/types/__tests__/components/Preview.test.d.ts +1 -0
  11. package/dist/types/__tests__/helper.test.d.ts +1 -0
  12. package/dist/types/src/Designer.d.ts +21 -0
  13. package/dist/types/src/Form.d.ts +24 -0
  14. package/dist/types/src/Viewer.d.ts +15 -0
  15. package/dist/types/src/class.d.ts +89 -0
  16. package/dist/types/src/components/AppContextProvider.d.ts +11 -0
  17. package/dist/types/src/components/CtlBar.d.ts +14 -0
  18. package/dist/types/src/components/Designer/Canvas/Guides.d.ts +9 -0
  19. package/dist/types/src/components/Designer/Canvas/Mask.d.ts +4 -0
  20. package/dist/types/src/components/Designer/Canvas/Moveable.d.ts +37 -0
  21. package/dist/types/src/components/Designer/Canvas/Padding.d.ts +6 -0
  22. package/dist/types/src/components/Designer/Canvas/Selecto.d.ts +10 -0
  23. package/dist/types/src/components/Designer/Canvas/index.d.ts +22 -0
  24. package/dist/types/src/components/Designer/LeftSidebar.d.ts +8 -0
  25. package/dist/types/src/components/Designer/PluginIcon.d.ts +10 -0
  26. package/dist/types/src/components/Designer/RightSidebar/DetailView/AlignWidget.d.ts +4 -0
  27. package/dist/types/src/components/Designer/RightSidebar/DetailView/ButtonGroupWidget.d.ts +4 -0
  28. package/dist/types/src/components/Designer/RightSidebar/DetailView/WidgetRenderer.d.ts +7 -0
  29. package/dist/types/src/components/Designer/RightSidebar/DetailView/index.d.ts +8 -0
  30. package/dist/types/src/components/Designer/RightSidebar/ListView/Item.d.ts +45 -0
  31. package/dist/types/src/components/Designer/RightSidebar/ListView/SelectableSortableContainer.d.ts +4 -0
  32. package/dist/types/src/components/Designer/RightSidebar/ListView/SelectableSortableItem.d.ts +14 -0
  33. package/dist/types/src/components/Designer/RightSidebar/ListView/index.d.ts +4 -0
  34. package/dist/types/src/components/Designer/RightSidebar/index.d.ts +4 -0
  35. package/dist/types/src/components/Designer/RightSidebar/layout.d.ts +15 -0
  36. package/dist/types/src/components/Designer/index.d.ts +11 -0
  37. package/dist/types/src/components/ErrorScreen.d.ts +7 -0
  38. package/dist/types/src/components/Paper.d.ts +20 -0
  39. package/dist/types/src/components/Preview.d.ts +15 -0
  40. package/dist/types/src/components/Renderer.d.ts +13 -0
  41. package/dist/types/src/components/Root.d.ts +9 -0
  42. package/dist/types/src/components/Spinner.d.ts +3 -0
  43. package/dist/types/src/components/StaticSchema.d.ts +10 -0
  44. package/dist/types/src/components/UnitPager.d.ts +10 -0
  45. package/dist/types/src/constants.d.ts +11 -0
  46. package/dist/types/src/contexts.d.ts +10 -0
  47. package/dist/types/src/helper.d.ts +73 -0
  48. package/dist/types/src/hooks.d.ts +46 -0
  49. package/dist/types/src/i18n.d.ts +3 -0
  50. package/dist/types/src/index.d.ts +4 -0
  51. package/dist/types/src/theme.d.ts +2 -0
  52. package/dist/types/src/types.d.ts +19 -0
  53. package/eslint.config.mjs +41 -0
  54. package/package.json +127 -0
  55. package/src/Designer.tsx +107 -0
  56. package/src/Form.tsx +102 -0
  57. package/src/Viewer.tsx +59 -0
  58. package/src/class.ts +188 -0
  59. package/src/components/AppContextProvider.tsx +78 -0
  60. package/src/components/CtlBar.tsx +183 -0
  61. package/src/components/Designer/Canvas/Guides.tsx +49 -0
  62. package/src/components/Designer/Canvas/Mask.tsx +20 -0
  63. package/src/components/Designer/Canvas/Moveable.tsx +91 -0
  64. package/src/components/Designer/Canvas/Padding.tsx +56 -0
  65. package/src/components/Designer/Canvas/Selecto.tsx +45 -0
  66. package/src/components/Designer/Canvas/index.tsx +536 -0
  67. package/src/components/Designer/LeftSidebar.tsx +120 -0
  68. package/src/components/Designer/PluginIcon.tsx +87 -0
  69. package/src/components/Designer/RightSidebar/DetailView/AlignWidget.tsx +229 -0
  70. package/src/components/Designer/RightSidebar/DetailView/ButtonGroupWidget.tsx +78 -0
  71. package/src/components/Designer/RightSidebar/DetailView/WidgetRenderer.tsx +28 -0
  72. package/src/components/Designer/RightSidebar/DetailView/index.tsx +469 -0
  73. package/src/components/Designer/RightSidebar/ListView/Item.tsx +158 -0
  74. package/src/components/Designer/RightSidebar/ListView/SelectableSortableContainer.tsx +204 -0
  75. package/src/components/Designer/RightSidebar/ListView/SelectableSortableItem.tsx +88 -0
  76. package/src/components/Designer/RightSidebar/ListView/index.tsx +116 -0
  77. package/src/components/Designer/RightSidebar/index.tsx +72 -0
  78. package/src/components/Designer/RightSidebar/layout.tsx +75 -0
  79. package/src/components/Designer/index.tsx +389 -0
  80. package/src/components/ErrorScreen.tsx +33 -0
  81. package/src/components/Paper.tsx +117 -0
  82. package/src/components/Preview.tsx +220 -0
  83. package/src/components/Renderer.tsx +165 -0
  84. package/src/components/Root.tsx +38 -0
  85. package/src/components/Spinner.tsx +45 -0
  86. package/src/components/StaticSchema.tsx +50 -0
  87. package/src/components/UnitPager.tsx +119 -0
  88. package/src/constants.ts +21 -0
  89. package/src/contexts.ts +14 -0
  90. package/src/helper.ts +534 -0
  91. package/src/hooks.ts +308 -0
  92. package/src/i18n.ts +903 -0
  93. package/src/index.ts +5 -0
  94. package/src/theme.ts +20 -0
  95. package/src/types.ts +20 -0
  96. package/tsconfig.json +48 -0
  97. package/vite.config.mts +22 -0
@@ -0,0 +1,204 @@
1
+ import React, { useState, useContext, ReactNode } from 'react';
2
+ import { createPortal } from 'react-dom';
3
+ import {
4
+ closestCorners,
5
+ DndContext,
6
+ DragOverlay,
7
+ KeyboardSensor,
8
+ PointerSensor,
9
+ useSensors,
10
+ useSensor,
11
+ } from '@dnd-kit/core';
12
+ import {
13
+ SortableContext,
14
+ arrayMove,
15
+ sortableKeyboardCoordinates,
16
+ verticalListSortingStrategy,
17
+ } from '@dnd-kit/sortable';
18
+ import { SchemaForUI } from '@pdfme/common';
19
+ import type { SidebarProps } from '../../../../types.js';
20
+ import { PluginsRegistry } from '../../../../contexts.js';
21
+ import Item from './Item.js';
22
+ import SelectableSortableItem from './SelectableSortableItem.js';
23
+ import { theme } from 'antd';
24
+ import PluginIcon from '../../PluginIcon.js';
25
+
26
+ const SelectableSortableContainer = (
27
+ props: Pick<
28
+ SidebarProps,
29
+ 'schemas' | 'onEdit' | 'onSortEnd' | 'hoveringSchemaId' | 'onChangeHoveringSchemaId'
30
+ >,
31
+ ) => {
32
+ const { token } = theme.useToken();
33
+ const { schemas, onEdit, onSortEnd, hoveringSchemaId, onChangeHoveringSchemaId } = props;
34
+ const [selectedSchemas, setSelectedSchemas] = useState<SchemaForUI[]>([]);
35
+ const [dragOverlaidItems, setClonedItems] = useState<SchemaForUI[] | null>(null);
36
+ const [activeId, setActiveId] = useState<string | null>(null);
37
+ const pluginsRegistry = useContext(PluginsRegistry);
38
+ const sensors = useSensors(
39
+ useSensor(PointerSensor, { activationConstraint: { distance: 15 } }),
40
+ useSensor(KeyboardSensor, { coordinateGetter: sortableKeyboardCoordinates }),
41
+ );
42
+
43
+ const isItemSelected = (itemId: string): boolean =>
44
+ selectedSchemas.map((i) => i.id).includes(itemId);
45
+
46
+ const onSelectionChanged = (id: string, isShiftSelect: boolean) => {
47
+ if (isShiftSelect) {
48
+ if (isItemSelected(id)) {
49
+ const newSelectedSchemas = selectedSchemas.filter((item) => item.id !== id);
50
+ setSelectedSchemas(newSelectedSchemas);
51
+ } else {
52
+ const newSelectedItem = schemas.find((schema) => schema.id === id)!;
53
+ const newSelectedSchemas = selectedSchemas.concat(newSelectedItem);
54
+ setSelectedSchemas(newSelectedSchemas);
55
+ }
56
+ } else {
57
+ setSelectedSchemas([]);
58
+ }
59
+ };
60
+
61
+ const getPluginIcon = (inSchema: string | SchemaForUI): ReactNode => {
62
+ // Get schema by ID or use directly
63
+ const thisSchema =
64
+ typeof inSchema === 'string' ? schemas.find((schema) => schema.id === inSchema) : inSchema;
65
+
66
+ if (!thisSchema) return <></>;
67
+
68
+ const [pluginLabel, activePlugin] = pluginsRegistry.findWithLabelByType(thisSchema.type);
69
+
70
+ if (!activePlugin) {
71
+ return <></>;
72
+ }
73
+
74
+ return (
75
+ <PluginIcon
76
+ plugin={activePlugin}
77
+ label={pluginLabel}
78
+ size={20}
79
+ styles={{ marginRight: '0.5rem' }}
80
+ />
81
+ );
82
+ };
83
+
84
+ return (
85
+ <DndContext
86
+ sensors={sensors}
87
+ collisionDetection={closestCorners}
88
+ onDragStart={({ active }) => {
89
+ setActiveId(String(active.id));
90
+ setClonedItems(schemas);
91
+
92
+ if (!isItemSelected(String(active.id))) {
93
+ const newSelectedSchemas: SchemaForUI[] = [];
94
+ setSelectedSchemas(newSelectedSchemas);
95
+ } else if (selectedSchemas.length > 0) {
96
+ onSortEnd(
97
+ selectedSchemas.reduce((ret, selectedItem) => {
98
+ if (selectedItem.id === String(active.id)) {
99
+ return ret;
100
+ }
101
+ return ret.filter((schema) => schema !== selectedItem);
102
+ }, schemas),
103
+ );
104
+ }
105
+ }}
106
+ onDragEnd={({ active, over }) => {
107
+ const overId = over?.id || '';
108
+
109
+ const activeIndex = schemas.map((i) => i.id).indexOf(String(active.id));
110
+ const overIndex = schemas.map((i) => i.id).indexOf(String(overId));
111
+
112
+ if (selectedSchemas.length) {
113
+ let newSchemas = [...schemas];
114
+ newSchemas = arrayMove(newSchemas, activeIndex, overIndex);
115
+ newSchemas.splice(
116
+ overIndex + 1,
117
+ 0,
118
+ ...selectedSchemas.filter((item) => item.id !== activeId),
119
+ );
120
+ onSortEnd(newSchemas);
121
+ setSelectedSchemas([]);
122
+ } else if (activeIndex !== overIndex) {
123
+ onSortEnd(arrayMove(schemas, activeIndex, overIndex));
124
+ }
125
+
126
+ setActiveId(null);
127
+ }}
128
+ onDragCancel={() => {
129
+ if (dragOverlaidItems) {
130
+ onSortEnd(dragOverlaidItems);
131
+ }
132
+
133
+ setActiveId(null);
134
+ setClonedItems(null);
135
+ }}
136
+ >
137
+ <>
138
+ <SortableContext items={schemas} strategy={verticalListSortingStrategy}>
139
+ <ul style={{ margin: 0, padding: 0, listStyle: 'none', borderRadius: 5 }}>
140
+ {schemas.map((schema) => (
141
+ <SelectableSortableItem
142
+ key={schema.id}
143
+ style={{
144
+ border: `1px solid ${
145
+ schema.id === hoveringSchemaId ? token.colorPrimary : 'transparent'
146
+ }`,
147
+ }}
148
+ schema={schema}
149
+ schemas={schemas}
150
+ isSelected={isItemSelected(schema.id) || activeId === schema.id}
151
+ onEdit={onEdit}
152
+ onSelect={onSelectionChanged}
153
+ onMouseEnter={() => onChangeHoveringSchemaId(schema.id)}
154
+ onMouseLeave={() => onChangeHoveringSchemaId(null)}
155
+ />
156
+ ))}
157
+ </ul>
158
+ </SortableContext>
159
+ {createPortal(
160
+ <DragOverlay adjustScale>
161
+ {activeId
162
+ ? (() => {
163
+ const activeSchema = schemas.find((schema) => schema.id === activeId);
164
+ if (!activeSchema) return null;
165
+ return (
166
+ <>
167
+ <ul style={{ margin: 0, padding: 0, listStyle: 'none' }}>
168
+ <Item
169
+ icon={getPluginIcon(activeId)}
170
+ value={activeSchema.name}
171
+ required={activeSchema.required}
172
+ readOnly={activeSchema.readOnly}
173
+ style={{ background: token.colorPrimary }}
174
+ dragOverlay
175
+ />
176
+ </ul>
177
+ <ul style={{ margin: 0, padding: 0, listStyle: 'none' }}>
178
+ {selectedSchemas
179
+ .filter((item) => item.id !== activeId)
180
+ .map((item) => (
181
+ <Item
182
+ icon={getPluginIcon(item)}
183
+ key={item.id}
184
+ value={item.name}
185
+ required={item.required}
186
+ readOnly={item.readOnly}
187
+ style={{ background: token.colorPrimary }}
188
+ dragOverlay
189
+ />
190
+ ))}
191
+ </ul>
192
+ </>
193
+ );
194
+ })()
195
+ : null}
196
+ </DragOverlay>,
197
+ document.body,
198
+ )}
199
+ </>
200
+ </DndContext>
201
+ );
202
+ };
203
+
204
+ export default SelectableSortableContainer;
@@ -0,0 +1,88 @@
1
+ import React, { useContext } from 'react';
2
+ import { useSortable } from '@dnd-kit/sortable';
3
+ import { SchemaForUI } from '@pdfme/common';
4
+ import { PluginsRegistry, I18nContext } from '../../../../contexts.js';
5
+ import Item from './Item.js';
6
+ import { useMountStatus } from '../../../../hooks.js';
7
+ import { theme } from 'antd';
8
+ import PluginIcon from '../../PluginIcon.js';
9
+
10
+ interface Props {
11
+ isSelected: boolean;
12
+ style?: React.CSSProperties;
13
+ onSelect: (id: string, isShiftSelect: boolean) => void;
14
+ onEdit: (id: string) => void;
15
+ schema: SchemaForUI;
16
+ schemas: SchemaForUI[];
17
+ onMouseEnter: () => void;
18
+ onMouseLeave: () => void;
19
+ }
20
+ const SelectableSortableItem = ({
21
+ isSelected,
22
+ style,
23
+ onSelect,
24
+ onEdit,
25
+ schema,
26
+ schemas,
27
+ onMouseEnter,
28
+ onMouseLeave,
29
+ }: Props) => {
30
+ const { token } = theme.useToken();
31
+
32
+ const i18n = useContext(I18nContext);
33
+ const pluginsRegistry = useContext(PluginsRegistry);
34
+ const { setNodeRef, listeners, isDragging, isSorting, transform, transition } = useSortable({
35
+ id: schema.id,
36
+ });
37
+ const mounted = useMountStatus();
38
+ const mountedWhileDragging = isDragging && !mounted;
39
+
40
+ const newListeners = {
41
+ ...listeners,
42
+ onClick: (event: React.MouseEvent) => onSelect(schema.id, event.shiftKey),
43
+ };
44
+
45
+ const [pluginLabel, thisPlugin] = pluginsRegistry.findWithLabelByType(schema.type);
46
+
47
+ let status: undefined | 'is-warning' | 'is-danger';
48
+ if (!schema.name) {
49
+ status = 'is-warning';
50
+ } else if (schemas.find((s) => schema.name && s.name === schema.name && s.id !== schema.id)) {
51
+ status = 'is-danger';
52
+ }
53
+
54
+ let title = i18n('edit');
55
+ if (status === 'is-warning') {
56
+ title = i18n('plsInputName');
57
+ } else if (status === 'is-danger') {
58
+ title = i18n('fieldMustUniq');
59
+ }
60
+
61
+ const selectedStyle = isSelected
62
+ ? { background: token.colorPrimary, opacity: isSorting || isDragging ? 0.5 : 1 }
63
+ : ({} as React.CSSProperties);
64
+
65
+ return (
66
+ <Item
67
+ ref={setNodeRef}
68
+ onMouseEnter={onMouseEnter}
69
+ onMouseLeave={onMouseLeave}
70
+ onClick={() => onEdit(schema.id)}
71
+ icon={thisPlugin && <PluginIcon plugin={thisPlugin} label={pluginLabel} size={20} />}
72
+ value={schema.name}
73
+ status={status}
74
+ title={title}
75
+ required={schema.required}
76
+ readOnly={schema.readOnly}
77
+ style={{ ...selectedStyle, ...style }}
78
+ dragging={isDragging}
79
+ sorting={isSorting}
80
+ transition={transition}
81
+ transform={transform}
82
+ fadeIn={mountedWhileDragging}
83
+ listeners={newListeners}
84
+ />
85
+ );
86
+ };
87
+
88
+ export default SelectableSortableItem;
@@ -0,0 +1,116 @@
1
+ import React, { useContext, useState } from 'react';
2
+ import type { SidebarProps } from '../../../../types.js';
3
+ import { DESIGNER_CLASSNAME } from '../../../../constants.js';
4
+ import { I18nContext } from '../../../../contexts.js';
5
+ import { Input, Typography, Button } from 'antd';
6
+ import SelectableSortableContainer from './SelectableSortableContainer.js';
7
+ import { SidebarBody, SidebarFooter, SidebarFrame, SidebarHeader } from '../layout.js';
8
+
9
+ const { Text } = Typography;
10
+ const { TextArea } = Input;
11
+
12
+ const ListView = (
13
+ props: Pick<
14
+ SidebarProps,
15
+ | 'schemas'
16
+ | 'onSortEnd'
17
+ | 'onEdit'
18
+ | 'hoveringSchemaId'
19
+ | 'onChangeHoveringSchemaId'
20
+ | 'changeSchemas'
21
+ >,
22
+ ) => {
23
+ const { schemas, onSortEnd, onEdit, hoveringSchemaId, onChangeHoveringSchemaId, changeSchemas } =
24
+ props;
25
+ const i18n = useContext(I18nContext);
26
+ const [isBulkUpdateFieldNamesMode, setIsBulkUpdateFieldNamesMode] = useState(false);
27
+ const [fieldNamesValue, setFieldNamesValue] = useState('');
28
+
29
+ const commitBulk = () => {
30
+ const names = fieldNamesValue.split('\n');
31
+ if (names.length !== schemas.length) {
32
+ alert(i18n('errorBulkUpdateFieldName'));
33
+ } else {
34
+ changeSchemas(
35
+ names.map((value, index) => ({
36
+ key: 'name',
37
+ value,
38
+ schemaId: schemas[index].id,
39
+ })),
40
+ );
41
+ setIsBulkUpdateFieldNamesMode(false);
42
+ }
43
+ };
44
+
45
+ const startBulk = () => {
46
+ setFieldNamesValue(schemas.map((s) => s.name).join('\n'));
47
+ setIsBulkUpdateFieldNamesMode(true);
48
+ };
49
+
50
+ return (
51
+ <SidebarFrame className={DESIGNER_CLASSNAME + 'list-view'}>
52
+ <SidebarHeader>
53
+ <Text strong style={{ textAlign: 'center', width: '100%' }}>
54
+ {i18n('fieldsList')}
55
+ </Text>
56
+ </SidebarHeader>
57
+ <SidebarBody>
58
+ {isBulkUpdateFieldNamesMode ? (
59
+ <TextArea
60
+ wrap="off"
61
+ value={fieldNamesValue}
62
+ onChange={(e) => setFieldNamesValue(e.target.value)}
63
+ style={{
64
+ height: '100%',
65
+ width: '100%',
66
+ resize: 'none',
67
+ lineHeight: '2.75rem',
68
+ }}
69
+ />
70
+ ) : (
71
+ <SelectableSortableContainer
72
+ schemas={schemas}
73
+ hoveringSchemaId={hoveringSchemaId}
74
+ onChangeHoveringSchemaId={onChangeHoveringSchemaId}
75
+ onSortEnd={onSortEnd}
76
+ onEdit={onEdit}
77
+ />
78
+ )}
79
+ </SidebarBody>
80
+ <SidebarFooter>
81
+ {isBulkUpdateFieldNamesMode ? (
82
+ <>
83
+ <Button
84
+ className={DESIGNER_CLASSNAME + 'bulk-commit'}
85
+ size="small"
86
+ type="text"
87
+ onClick={commitBulk}
88
+ >
89
+ <u> {i18n('commitBulkUpdateFieldName')}</u>
90
+ </Button>
91
+ <span>/</span>
92
+ <Button
93
+ className={DESIGNER_CLASSNAME + 'bulk-cancel'}
94
+ size="small"
95
+ type="text"
96
+ onClick={() => setIsBulkUpdateFieldNamesMode(false)}
97
+ >
98
+ <u> {i18n('cancel')}</u>
99
+ </Button>
100
+ </>
101
+ ) : (
102
+ <Button
103
+ className={DESIGNER_CLASSNAME + 'bulk-update'}
104
+ size="small"
105
+ type="text"
106
+ onClick={startBulk}
107
+ >
108
+ <u> {i18n('bulkUpdateFieldName')}</u>
109
+ </Button>
110
+ )}
111
+ </SidebarFooter>
112
+ </SidebarFrame>
113
+ );
114
+ };
115
+
116
+ export default ListView;
@@ -0,0 +1,72 @@
1
+ import React from 'react';
2
+ import { theme, Button } from 'antd';
3
+ import type { SidebarProps } from '../../../types.js';
4
+ import { RIGHT_SIDEBAR_WIDTH, DESIGNER_CLASSNAME } from '../../../constants.js';
5
+ import { ArrowLeft, ArrowRight } from 'lucide-react';
6
+ import ListView from './ListView/index.js';
7
+ import DetailView from './DetailView/index.js';
8
+
9
+ const Sidebar = (props: SidebarProps) => {
10
+ const { sidebarOpen, setSidebarOpen, activeElements, schemas } = props;
11
+
12
+ const { token } = theme.useToken();
13
+ const getActiveSchemas = () =>
14
+ schemas.filter((s) => activeElements.map((ae) => ae.id).includes(s.id));
15
+ const getLastActiveSchema = () => {
16
+ const activeSchemas = getActiveSchemas();
17
+ return activeSchemas[activeSchemas.length - 1];
18
+ };
19
+
20
+ const iconProps = { strokeWidth: 1.5, size: 20 };
21
+
22
+ return (
23
+ <div
24
+ className={DESIGNER_CLASSNAME + 'right-sidebar'}
25
+ style={{
26
+ position: 'absolute',
27
+ right: 0,
28
+ zIndex: 1,
29
+ height: '100%',
30
+ width: sidebarOpen ? RIGHT_SIDEBAR_WIDTH : 0,
31
+ }}
32
+ >
33
+ <Button
34
+ className={DESIGNER_CLASSNAME + 'sidebar-toggle'}
35
+ style={{
36
+ position: 'absolute',
37
+ display: 'flex',
38
+ alignItems: 'center',
39
+ justifyContent: 'center',
40
+ top: '14px',
41
+ right: '16px',
42
+ paddingTop: '2px',
43
+ zIndex: 100,
44
+ }}
45
+ icon={sidebarOpen ? <ArrowRight {...iconProps} /> : <ArrowLeft {...iconProps} />}
46
+ onClick={() => setSidebarOpen(!sidebarOpen)}
47
+ />
48
+ <div
49
+ style={{
50
+ width: RIGHT_SIDEBAR_WIDTH,
51
+ height: '100%',
52
+ display: sidebarOpen ? 'flex' : 'none',
53
+ top: 0,
54
+ right: 0,
55
+ position: 'absolute',
56
+ fontFamily: "'Open Sans', sans-serif",
57
+ boxSizing: 'border-box',
58
+ background: token.colorBgLayout,
59
+ borderLeft: `1px solid ${token.colorSplit}`,
60
+ }}
61
+ >
62
+ {getActiveSchemas().length === 0 ? (
63
+ <ListView {...props} />
64
+ ) : (
65
+ <DetailView {...props} activeSchema={getLastActiveSchema()} />
66
+ )}
67
+ </div>
68
+ </div>
69
+ );
70
+ };
71
+
72
+ export default Sidebar;
@@ -0,0 +1,75 @@
1
+ import React from 'react';
2
+ import { Divider } from 'antd';
3
+
4
+ export const SIDEBAR_H_PADDING_PX = 16;
5
+ export const SIDEBAR_V_PADDING_PX = 8;
6
+ export const SIDEBAR_HEADER_HEIGHT = 60;
7
+
8
+ type SectionProps = {
9
+ children: React.ReactNode;
10
+ };
11
+ type SidebarFrameProps = SectionProps & {
12
+ className?: string;
13
+ };
14
+
15
+ export const SidebarFrame = ({ children, className }: SidebarFrameProps) => (
16
+ <div
17
+ className={className}
18
+ style={{
19
+ height: '100%',
20
+ display: 'flex',
21
+ flex: 1,
22
+ flexDirection: 'column',
23
+ }}
24
+ >
25
+ {children}
26
+ </div>
27
+ );
28
+
29
+ export const SidebarHeader = ({ children }: SectionProps) => (
30
+ <div
31
+ style={{
32
+ position: 'relative',
33
+ minHeight: SIDEBAR_HEADER_HEIGHT,
34
+ display: 'flex',
35
+ flexShrink: 0,
36
+ flexDirection: 'column',
37
+ justifyContent: 'center',
38
+ padding: `${SIDEBAR_V_PADDING_PX}px ${SIDEBAR_H_PADDING_PX}px 0`,
39
+ }}
40
+ >
41
+ <div style={{ minHeight: 40, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
42
+ {children}
43
+ </div>
44
+ <Divider style={{ marginTop: `${SIDEBAR_V_PADDING_PX}px`, marginBottom: 0 }} />
45
+ </div>
46
+ );
47
+
48
+ export const SidebarBody = ({ children }: SectionProps) => (
49
+ <div
50
+ style={{
51
+ flex: 1,
52
+ minHeight: 0,
53
+ overflowY: 'auto',
54
+ overflowX: 'hidden',
55
+ padding: `${SIDEBAR_V_PADDING_PX}px ${SIDEBAR_H_PADDING_PX}px`,
56
+ }}
57
+ >
58
+ {children}
59
+ </div>
60
+ );
61
+
62
+ export const SidebarFooter = ({ children }: SectionProps) => (
63
+ <div
64
+ style={{
65
+ display: 'flex',
66
+ flexShrink: 0,
67
+ alignItems: 'center',
68
+ justifyContent: 'flex-end',
69
+ gap: `${SIDEBAR_V_PADDING_PX}px`,
70
+ padding: `${SIDEBAR_H_PADDING_PX}px`,
71
+ }}
72
+ >
73
+ {children}
74
+ </div>
75
+ );