본문으로 건너뛰기

ErdEditorElement

에디터는 단순한 HTMLElement입니다.
타입 정의는 다음과 같습니다.

interface ErdEditorElement extends HTMLElement {
readonly: boolean;
systemDarkMode: boolean; // system dark/light auto
enableThemeBuilder: boolean;
value: string;
focus: () => void;
blur: () => void;
clear: () => void;
destroy: () => void;
setInitialValue: (value: string) => void;
setPresetTheme: (themeOptions: Partial<ThemeOptions>) => void;
setTheme: (theme: Partial<Theme>) => void;
setKeyBindingMap: (
keyBindingMap: Partial<
Omit<
KeyBindingMap,
| 'edit'
| 'stop'
| 'undo'
| 'redo'
| 'zoomIn'
| 'zoomOut'
| 'zoomReset'
>
>
) => void;
setSchemaSQL: (value: string) => void;
setSchemaGraphQL: (value: string) => void;
setSchemaDBML: (value: string) => void;
setSchemaAML: (value: string) => void;
getSchemaSQL: (databaseVendor?: DatabaseVendor) => string;
getSharedStore: (
config?: SharedStoreConfig & {
mouseTracker?: boolean;
focusTracker?: boolean;
}
) => SharedStore;
setDiffValue: (value: string) => void;
}

에디터는 closed shadow root에 렌더링되므로 editor.shadowRoot는 null이고 페이지 스타일이 안팎으로 새지 않습니다.
내부 요소는 선택자로 접근할 수 없기 때문에, 스타일은 setTheme과 --erd-editor-* 커스텀 프로퍼티로 지정하세요.

속성은 readonly, system-dark-mode, enable-theme-builder 3개뿐이며, 셋 다 기본값은 false입니다.

readonly​

에디터 편집 가능 여부를 설정합니다.
설정된 동안에는 value 할당, clear(), setSchemaSQL(), setSchemaGraphQL(), setSchemaDBML(), setSchemaAML(), Undo, Redo가 모두 무시되고 change 이벤트도 발행되지 않습니다. 문서를 불러올 때는 setInitialValue를 사용하세요.
보기는 그대로 동작합니다. 확대/축소, 화면 이동, 손 도구, Zen 모드, 캔버스 탭, 두 모드와 테이블 포커스를 포함한 Visualization 탭, 데이터베이스 벤더, SQL과 코드 생성 출력 설정이 모두 적용되므로, readonly 상태에서도 다른 벤더의 SQL을 내보내거나 생성된 코드를 확인할 수 있습니다.
3.10.0부터는 찾기와 바꾸기도 열리며, 제목이 Find이고 Replace 입력란과 버튼이 없는 찾기 전용 패널로 표시됩니다. 일치 항목으로 이동하면 여전히 그 항목을 화면에 표시하고 선택합니다.
테이블 속성도 그대로 열리며, 3.10.0부터는 제목 옆에 Read only 배지가 표시되고 Indexes 탭에서는 아무것도 편집할 수 없습니다. 테이블 속성 문서를 참고하세요.
속성만 쓰거나 ="", ="true"는 모두 true로 읽힙니다. ="false"는 false로 읽히고, HTML 관용 표기인 readonly="readonly"를 포함해 그 밖의 문자열도 마찬가지입니다.

editor.readonly = true;
// or
editor.setAttribute('readonly', 'true');
<erd-editor readonly></erd-editor>

systemDarkMode​

시스템의 다크/라이트 모드를 자동으로 동기화할지 설정합니다.
켜면 테마의 appearance를 운영체제 설정으로 지정하며, setPresetTheme으로 지정했던 값을 덮어씁니다. 운영체제가 모드를 전환하면 다시 덮어씁니다. 그 사이에 호출한 setPresetTheme은 다음 운영체제 변경 전까지 그대로 적용됩니다. 끄면 마지막 값이 그대로 유지됩니다.

editor.systemDarkMode = true;
// or
editor.setAttribute('system-dark-mode', 'true');
<erd-editor system-dark-mode></erd-editor>

enableThemeBuilder​

preset 테마를 쉽게 사용자 정의할 수 있는 UI를 제공할지 여부입니다.

테마 빌더를 열어 액센트 색상과 그레이 색상 변경

editor.enableThemeBuilder = true;
// or
editor.setAttribute('enable-theme-builder', 'true');
<erd-editor enable-theme-builder></erd-editor>

이 패널에서 preset 테마를 변경하면 changePresetTheme 이벤트를 발행합니다.

value​

getter​

현재 에디터 상태를 에디터가 정의한 스키마 형식의 JSON 문자열로 받아옵니다.
직렬화할 때 해당 문서의 ignoreSaveSettings가 적용되어, 스크롤 비트가 설정되어 있으면 화면 원점이 0, 0으로, 확대/축소 비트가 설정되어 있으면 확대/축소 레벨이 1로 기록됩니다.
3.10.0부터 새 문서는 두 비트가 모두 설정되어 있으며, 값을 전달받기 전에 엘리먼트가 표시하는 문서와 빈 값으로 불러온 문서 모두 해당합니다. 이런 문서의 value는 Save Scroll Information을 켜기 전까지 화면 원점을 0, 0으로, Save Zoom Information을 켜기 전까지 확대/축소 레벨을 1로 계속 기록합니다. 각 비트는 Settings 문서를 참고하세요.

const data = editor.value;

setter​

이전에 저장했던 에디터 상태를 불러옵니다. 문서 전체를 교체하며, 현재 문서는 먼저 비워집니다.
clear(), setInitialValue(), setSchema* 메서드와 마찬가지로 Visualization 탭의 Flow 뷰도 버립니다. 배치, 범위를 좁혀 둔 테이블, 행 표시, 확대/축소, 화면 이동 상태가 모두 해당합니다.
히스토리 목록에 기록되어 Undo, Redo가 가능하고, change 이벤트를 발행합니다.
빈 문자열이나 문자열이 아닌 값은 에러가 아니라 새 문서로 불러오므로, 할당하기 전에 값을 확인하세요.
3.10.0부터 이 새 문서는 setInitialValue('')로 시작하는 문서와 같습니다. 비어 있고 기본 설정을 사용하며, 스크롤 위치와 확대/축소 레벨을 모두 저장하지 않습니다. 이전에는 둘 다 저장하는 빈 문서였습니다.
shared store는 이 불러오기를 새 문서의 전체 JSON과 함께 공동 편집자에게 전달하므로, 이전 릴리스를 사용하는 참여자를 포함해 모든 참여자가 같은 문서를 불러옵니다.
병합 충돌 표시가 남은 파일처럼 JSON이 아닌 텍스트도 에러를 발생시키지 않습니다. 문서는 비워지고 설정은 그대로 유지되며, 파싱 에러는 콘솔에 기록됩니다.
readonly가 설정된 동안에는 무시되며, readonly 에디터에 문서를 불러올 때는 setInitialValue를 사용하세요.

editor.value = 'json...';

setInitialValue​

이전에 저장했던 에디터 상태를 불러옵니다. 불러오기 자체는 히스토리 목록에 기록되지 않아 되돌릴 수 없고, change 이벤트도 발행되지 않습니다.
불러올 때 Undo 기록도 비우므로, 불러오기 전에 한 작업을 불러온 문서 위에서 Undo, Redo할 수 없습니다.
빈 문자열이나 문자열이 아닌 값은 에러가 아니라 새 문서로 불러오므로, setInitialValue('')는 빈 다이어그램으로 시작합니다.
3.10.0부터 이 새 문서는 값을 전달받기 전에 엘리먼트가 표시하는 문서이기도 하며, 스크롤 위치와 확대/축소 레벨을 모두 저장하지 않으므로 스크롤하거나 확대/축소해도 value는 그대로 유지됩니다. 이전에는 둘 다 저장했습니다.
텍스트에서 불러온 문서는 그 안에 기록된 스위치 값을 유지하며, 3.2.3 이전에 저장한 파일이나 v2 .vuerd 파일처럼 스위치가 기록되지 않은 문서는 둘 다 저장합니다.
JSON이 아닌 텍스트도 에러를 발생시키지 않습니다. 문서는 비워지고 설정은 그대로 유지되며, 파싱 에러는 콘솔에 기록됩니다.
value 할당과 달리 readonly에 막히지 않기 때문에, readonly 에디터에 문서를 불러오는 방법입니다.

editor.setInitialValue('json...');

시작할 때 불러오고, 변경될 때 저장합니다.

editor.setInitialValue(localStorage.getItem('my-diagram') ?? '');
editor.addEventListener('change', () => {
localStorage.setItem('my-diagram', editor.value);
});

Event​

공개 이벤트는 change와 changePresetTheme 2개뿐입니다.
엘리먼트는 내부 연결을 위해 자기 자신에게 @dineug/erd-editor/internal-* 이벤트도 발행하지만, 이는 API가 아닙니다.

change​

에디터에 변경이 있을 때 이벤트를 발행합니다.
200ms 디바운스되며, readonly가 true인 동안에는 발행되지 않습니다.
UI 편집, value 할당, clear(), 각 setSchema* 메서드 등 문서가 변경되는 모든 경우에 발행됩니다. setInitialValue는 발행하지 않습니다.
Visualization 탭의 Flow 모드 안에서 하는 확대/축소, 화면 이동, 카드 이동, Tidy Up, 행 표시 변경, 카드에서 뷰 범위 좁히기는 모두 문서 변경이 아니므로 어느 것도 이벤트를 발행하지 않습니다. 탭 전환은 발행하므로, ERD 탭에서 테이블 포커스를 실행하면 change가 한 번 발행되고, Flow에서 ERD 탭으로 돌아가는 외부 링크 카드 버튼도 마찬가지입니다. 다른 탭에서 찾기와 바꾸기를 열거나 빠른 검색 결과로 이동해도 ERD 탭으로 전환되므로 마찬가지로 한 번 발행됩니다.
ERD 캔버스의 스크롤과 확대/축소도 editor.value가 달라지는지와 관계없이 이벤트를 발행합니다. Save Scroll Information이 꺼져 있는 동안 스크롤은 value를 그대로 둡니다. 확대/축소는 화면 위치도 함께 이동시키므로, Save Scroll Information과 Save Zoom Information이 모두 꺼져 있을 때만 value를 그대로 둡니다. 3.10.0부터 새 문서는 둘 다 꺼져 있으므로, 새 다이어그램에서는 스크롤이나 확대/축소가 value를 바꾸지 않은 채 change를 발행합니다.
이런 쓰기를 건너뛰려면 불러온 파일이 아니라 마지막으로 저장한 값과 editor.value를 비교하세요. 다른 릴리스나 다른 기기에서 저장한 파일은 불러오자마자 value가 달라질 수 있습니다. 파일을 저장하는 호스트는 대신 복제 store의 changed로 편집과 화면 변경을 구분할 수 있습니다. on@change 문서를 참고하세요.
이벤트에는 detail이 없고 버블링되거나 shadow 경계를 넘지도 않으므로, 엘리먼트 자체에서 수신하고 핸들러에서 editor.value를 읽으세요.

editor.addEventListener('change', event => {
const data = event.target.value;
});

changePresetTheme​

내장 테마 빌더에서 preset 테마를 변경할 때 발행합니다.
직접 setPresetTheme을 호출한 경우에는 발행되지 않습니다.
event.detail은 요청한 일부 값이 아니라 모두 채워진 ThemeOptions({ appearance, grayColor, accentColor })입니다.

editor.addEventListener('changePresetTheme', event => {
const themeOptions = event.detail;
});

focus​

에디터에 포커스를 줍니다.

editor.focus();

blur​

에디터의 포커스를 제거합니다.

editor.blur();

clear​

모든 테이블, 컬럼, 관계, 인덱스, 메모를 제거해 문서를 비웁니다.
데이터베이스, 화면 위치, 확대/축소 레벨, 테이블 보기 옵션, Save Scroll Information과 Save Zoom Information 스위치를 포함해 모든 설정이 유지되므로, 비운 파일은 이전에 저장하던 것을 계속 저장합니다. 대신 새 문서로 시작하려면 value에 ''를 할당하거나 setInitialValue('')를 호출하세요.
히스토리 목록에 기록되어 Undo가 가능하고, change 이벤트를 발행합니다. readonly가 설정된 동안에는 무시됩니다.

editor.clear();

destroy​

에디터 인스턴스를 재사용 불가능하게 완전히 파괴합니다.
에디터의 리스너와 구독을 해제하고, getSharedStore로 반환된 모든 shared store를 파괴합니다.
shared store가 아직 보류하고 있는 스트림 묶음은 함께 버려지므로, 전송하려면 먼저 해당 store의 flushStreamBuffers를 호출하세요.

editor.destroy();

setKeyBindingMap​

단축키를 재정의합니다.
edit, stop, undo, redo, zoomIn, zoomOut, zoomReset은 고정이며 재정의할 수 없습니다.
아래 18개 이름만 적용되고, 고정된 이름을 포함해 객체의 나머지 값은 무시됩니다.
3.10.0부터 search를 재정의할 수 있으며, findReplace가 새로 추가되었습니다. 이전에는 search가 고정이었습니다.
값은 ShortcutOption[]이어야 합니다. 문자열만 전달하면 무시되므로 { addTable: 'Alt+KeyN' }이 아니라 { addTable: [{ shortcut: 'Alt+KeyN' }] }으로 작성하세요.
빈 배열도 허용되며 아무 키도 지정하지 않습니다. setKeyBindingMap({ findReplace: [] })는 Ctrl + F (Windows/Linux) or ⌘ + F (Mac)를 페이지에 맡기고, { search: [] }는 Ctrl + K (Windows/Linux) or ⌘ + K (Mac)를 마찬가지로 페이지에 맡깁니다. 툴바의 Search 버튼으로는 여전히 빠른 검색이 열리고, 찾기와 바꾸기도 툴바 버튼, 빠른 검색의 항목, 캔버스 컨텍스트 메뉴로 여전히 열립니다. 비워 둔 이름의 단축키는 이 중 어디에도 표시되지 않습니다.
호출은 부분 병합이라 생략한 이름은 기본값을 유지하고, 두 번 호출해도 앞선 변경이 유지됩니다. 현재 설정을 읽는 getter는 없습니다. createKeyBindingMap은 setKeyBindingMap으로 변경한 내용이 아니라 기본값을 반환합니다.

type ShortcutOption = {
shortcut: string;
preventDefault?: boolean;
stopPropagation?: boolean;
};

const defaultKeyBindingMap: Omit<
KeyBindingMap,
| 'edit'
| 'stop'
| 'undo'
| 'redo'
| 'zoomIn'
| 'zoomOut'
| 'zoomReset'
> = {
search: [
{ shortcut: '$mod+KeyK', preventDefault: true, stopPropagation: true },
],
findReplace: [
{ shortcut: '$mod+KeyF', preventDefault: true, stopPropagation: true },
],
addTable: [{ shortcut: 'Alt+KeyN', preventDefault: true }],
addColumn: [{ shortcut: 'Alt+Enter', preventDefault: true }],
addMemo: [{ shortcut: 'Alt+KeyM', preventDefault: true }],
removeTable: [
{ shortcut: '$mod+Backspace', preventDefault: true },
{ shortcut: '$mod+Delete', preventDefault: true },
],
removeColumn: [
{ shortcut: 'Alt+Backspace', preventDefault: true },
{ shortcut: 'Alt+Delete', preventDefault: true },
],
primaryKey: [{ shortcut: 'Alt+KeyK', preventDefault: true }],
selectAllTable: [
{ shortcut: '$mod+KeyA', preventDefault: true },
{ shortcut: '$mod+Alt+KeyA', preventDefault: true },
],
selectAllColumn: [{ shortcut: 'Alt+KeyA', preventDefault: true }],
relationshipZeroOne: [{ shortcut: '$mod+Alt+Digit1', preventDefault: true }],
relationshipZeroN: [{ shortcut: '$mod+Alt+Digit2', preventDefault: true }],
relationshipOneOnly: [{ shortcut: '$mod+Alt+Digit3', preventDefault: true }],
relationshipOneN: [{ shortcut: '$mod+Alt+Digit4', preventDefault: true }],
tableProperties: [{ shortcut: 'Alt+Space', preventDefault: true }],
focusView: [
{ shortcut: 'Alt+KeyF', preventDefault: true, stopPropagation: true },
],
handTool: [{ shortcut: 'Space', preventDefault: true }],
zenMode: [
{ shortcut: 'Alt+KeyZ', preventDefault: true, stopPropagation: true },
],
};

// example
editor.setKeyBindingMap({
addTable: [{ shortcut: '$mod+KeyN', preventDefault: true }],
});

selectAllTable과 handTool은 커서에 양보합니다. 포커스가 input, textarea, contenteditable 안에 있는 동안에는 $mod + A가 텍스트를 선택하고 Space는 공백을 입력하며, 캔버스까지 전달되지 않습니다. 다른 단축키로 재정의해도 동작은 같습니다.

3.10.0부터 findReplace ($mod+KeyF)는 찾기와 바꾸기를 열며, 다른 탭에서는 ERD 탭으로 전환합니다.
이 키는 커서에 양보하지 않습니다. 에디터에 포커스가 있는 동안에는 캔버스에서든 에디터 안의 입력란에서든 모든 탭에서 이 키를 에디터가 처리합니다. 이 키 입력에 preventDefault()를 호출하므로 브라우저의 찾기 막대가 열리지 않고, stopPropagation()도 호출하므로 페이지의 버블링 keydown 리스너는 이 입력을 받지 않습니다. 셀이나 메모의 편집모드가 열려 있을 때도 preventDefault()와 stopPropagation()을 호출하지만 아무것도 열지 않습니다.
어느 탭에서든 Diff Viewer, Time Travel, 자동 배치 미리보기가 열려 있는 동안이나 IME가 아직 조합 중일 때는 preventDefault()도 stopPropagation()도 호출하지 않으므로, 브라우저나 호스트 자체의 찾기 기능이 이 입력을 받습니다. 찾기와 바꾸기 패널 안에서는 조합 중인 입력에 stopPropagation()만 호출하고 preventDefault()는 호출하지 않습니다. findReplace를 다른 단축키로 재정의해도 동작은 같습니다.

focusView는 ERD 탭에서만 동작합니다. 테이블이 하나 이상 선택되어 있으면 Visualization 탭을 Flow 모드로 열어, 선택한 테이블과 그 테이블에 관계 하나로 이어진 모든 테이블로 범위를 좁힙니다. 선택한 테이블이 없으면 아무 동작도 하지 않습니다. 테이블 포커스 문서를 참고하세요.

ERD 탭에서 stop (Escape)은 셀이나 메모의 편집모드, 또는 그리는 중인 관계를 끝내고 선택은 그대로 둡니다. 에디터는 이 키 입력에 preventDefault()를 호출합니다.
그중 아무것도 열려 있지 않으면 Escape는 선택과 포커스한 셀을 해제하며, 이때는 preventDefault()를 호출하지 않습니다. 따라서 편집을 끝내고 선택까지 해제하려면 두 번 눌러야 합니다.
찾기와 바꾸기 패널 밖에서는 에디터가 Escape의 전파를 막지 않으므로, 예를 들어 자체 다이얼로그를 닫기 위해 직접 Escape를 수신하는 페이지는 두 키 입력을 모두 받으며, defaultPrevented가 true인 입력은 건너뛸 수 있습니다.
빠른 검색, 테이블 속성, Diff Viewer, 자동 배치 미리보기, Time Travel이 열려 있는 동안에는 Escape가 대신 그것을 닫고 선택은 그대로 둡니다. 이 키 입력에도 preventDefault()를 호출하지 않습니다.
3.10.0부터 포커스가 찾기와 바꾸기 패널 안에 있을 때 누른 Escape는 패널을 닫고 선택은 그대로 둡니다. 에디터는 이 키 입력에 preventDefault()와 stopPropagation()을 모두 호출하므로, 페이지의 버블링 keydown 리스너에는 전달되지 않습니다.
패널이 열려 있을 때 캔버스에서 누른 Escape는 위의 어느 것도 이 입력을 처리하지 않으면, 선택을 해제하는 바로 그 입력으로 패널도 닫습니다. 이 키 입력에는 preventDefault()도 stopPropagation()도 호출하지 않습니다.
IME가 아직 조합 중일 때 누른 Escape는 조합에 속합니다. 열려 있는 편집모드는 그대로 두고 preventDefault()도 호출하지 않으므로, 페이지는 isComposing이 true이거나 keyCode가 229인 입력도 건너뛸 수 있습니다. 찾기와 바꾸기 패널 안에서는 조합 중에 누른 다른 키와 마찬가지로 이 입력에도 stopPropagation()을 호출합니다.
3.9.2 이전에는 Escape 한 번으로 편집이나 관계 그리기를 끝내는 동시에 선택까지 해제했고, 에디터는 preventDefault()를 호출하지 않았습니다.

createKeyBindingMap​

3.9.2부터 패키지는 createKeyBindingMap()과 함께 KeyBindingMap, KeyBindingName, ShortcutOption 타입을 export합니다.
고정된 이름을 포함한 25개 이름 전체의 기본 키 바인딩을 호출할 때마다 새 맵으로 반환하므로, 반환된 맵을 변경해도 다른 곳에는 영향이 없습니다.
모든 에디터가 시작할 때 사용하는 값이며, setKeyBindingMap 호출은 여기에 반영되지 않습니다.
런타임 export는 createKeyBindingMap뿐이며, 나머지 셋은 타입입니다.

type KeyBindingName =
| 'edit'
| 'stop'
| 'search'
| 'findReplace'
| 'undo'
| 'redo'
| 'addTable'
| 'addColumn'
| 'addMemo'
| 'removeTable'
| 'removeColumn'
| 'primaryKey'
| 'selectAllTable'
| 'selectAllColumn'
| 'relationshipZeroOne'
| 'relationshipZeroN'
| 'relationshipOneOnly'
| 'relationshipOneN'
| 'tableProperties'
| 'focusView'
| 'zoomIn'
| 'zoomOut'
| 'zoomReset'
| 'handTool'
| 'zenMode';

type KeyBindingMap = Record<KeyBindingName, ShortcutOption[]>;

declare function createKeyBindingMap(): KeyBindingMap;

// example
import { createKeyBindingMap } from '@dineug/erd-editor';

const shortcuts = Object.values(createKeyBindingMap())
.flat()
.map(({ shortcut }) => shortcut); // 'Enter', 'Escape', '$mod+KeyK', ...

각 shortcut은 키를 KeyboardEvent.code로 지정하는 tinykeys 키 조합이며, $mod는 macOS에서는 ⌘, 그 외 환경에서는 Control입니다.
고정된 이름은 Enter (edit), Escape (stop), $mod+KeyZ (undo), $mod+Shift+KeyZ (redo), $mod+Equal (zoomIn), $mod+Minus (zoomOut), $mod+Digit0 (zoomReset)에 바인딩되어 있습니다. edit과 stop에는 플래그가 없고, 나머지 다섯은 preventDefault와 stopPropagation을 가집니다. search와 findReplace를 포함한 그 외 이름은 위의 기본값과 같습니다.

에디터는 자신의 엘리먼트에서 이 키들을 수신하므로, 전역 단축키나 캡처 단계의 keydown 리스너로 에디터보다 먼저 키를 받는 호스트는 에디터에 포커스가 있는 동안 이 키들을 통과시켜야 합니다.
통과시킬 목록은 createKeyBindingMap()으로 만들되, setKeyBindingMap에 전달한 바인딩으로 해당 기본값을 대체하세요.
3.10.0부터 이 목록에는 브라우저 자체의 찾기 키 조합인 $mod+KeyF가 포함됩니다. 이 키 조합에서 호스트 자체의 찾기 기능을 유지하려면 setKeyBindingMap({ findReplace: [] })를 전달하세요.

포커스가 찾기와 바꾸기 패널 안에 있는 동안에는 findReplace, search, undo, redo, zoomIn, zoomOut, zoomReset이 에디터로 전달됩니다. 현재 설정된 그 밖의 모든 바인딩은 방향키, Tab과 함께 패널에서 멈춥니다. 패널을 닫는 Escape와, Find 또는 Replace 입력란에서 일치 항목 사이를 이동하거나 바꾸기를 실행하는 Enter를 제외하면, 이 키들에는 preventDefault() 없이 stopPropagation()만 호출하므로 패널의 입력란과 버튼에서 일반 키로 동작하며, 캔버스에도 페이지의 버블링 keydown 리스너에도 전달되지 않습니다.
호스트의 저장이나 명령 팔레트 키 조합처럼 그 밖의 키는 평소대로 페이지에 전달됩니다. 패널의 키 문서를 참고하세요.

$mod​

Control 키를 환경에 따라 분기합니다.

  • Mac: $mod = Meta (⌘)
  • Windows/Linux: $mod = Control

Shortcut Table​

키보드 이벤트 key, code 프로퍼티를 사용합니다.
절대 위치에는 code를, 입력값에는 key를 사용합니다.

WindowsmacOSkeycode
N/ACommand / ⌘MetaMetaLeft / MetaRight
AltOption / ⌥AltAltLeft / AltRight
ControlControl / ^ControlControlLeft / ControlRight
ShiftShiftShiftShiftLeft / ShiftRight
SpaceSpaceN/ASpace
EnterReturnEnterEnter
EscEscEscapeEscape
1, 2, etc1, 2, etc1, 2, etcDigit1, Digit2, etc
a, b, etca, b, etca, b, etcKeyA, KeyB, etc
---Minus
===Equal
+++Equal

Theme​

setPresetTheme​

preset 테마를 설정합니다.
기본값은 appearance: 'dark', grayColor: 'slate', accentColor: 'indigo'입니다.
각 필드는 개별로 적용되므로 일부만 전달하면 나머지 두 개는 그대로 유지됩니다. 아래 목록에 없는 값은 무시되며, 호출이 에러를 발생시키지 않습니다.

type ThemeOptions = {
appearance: 'dark' | 'light';
grayColor: 'gray' | 'mauve' | 'slate' | 'sage' | 'olive' | 'sand';
accentColor:
| 'gray'
| 'gold'
| 'bronze'
| 'brown'
| 'yellow'
| 'amber'
| 'orange'
| 'tomato'
| 'red'
| 'ruby'
| 'crimson'
| 'pink'
| 'plum'
| 'purple'
| 'violet'
| 'iris'
| 'indigo'
| 'blue'
| 'cyan'
| 'teal'
| 'jade'
| 'green'
| 'grass'
| 'lime'
| 'mint'
| 'sky';
};

// example
editor.setPresetTheme({ appearance: 'light' });

setTheme​

테마 사용자 정의가 가능합니다.
호출할 때마다 사용자 정의 오버레이 전체가 교체되므로, 이미 재정의한 값 위에 토큰 하나만 바꾸려면 전체 객체를 다시 전달하고, preset으로 되돌리려면 {}를 전달하세요.
아래 토큰 이름에 문자열 값을 지정한 것만 유지되고, 그 밖의 값은 에러 없이 버려집니다.
오버레이는 preset 위에 놓이기 때문에, 이후에 setPresetTheme을 호출하면 아래쪽 preset만 바뀌고 재정의한 값은 그대로 유지됩니다.

JavaScript​

type Theme = {
grayColor1: string;
grayColor2: string;
grayColor3: string;
grayColor4: string;
grayColor5: string;
grayColor6: string;
grayColor7: string;
grayColor8: string;
grayColor9: string;
grayColor10: string;
grayColor11: string;
grayColor12: string;

accentColor1: string;
accentColor2: string;
accentColor3: string;
accentColor4: string;
accentColor5: string;
accentColor6: string;
accentColor7: string;
accentColor8: string;
accentColor9: string;
accentColor10: string;
accentColor11: string;
accentColor12: string;

canvasBackground: string;
canvasBoundaryBackground: string;

tableBackground: string;
tableHeaderBackground: string;
tableSelect: string;
tableBorder: string;
tableShadow: string;

memoBackground: string;
memoSelect: string;
memoBorder: string;
memoShadow: string;

columnSelect: string;
columnSelectHover: string;
columnHover: string;

relationshipHover: string;

visualizationLink: string;
visualizationColumn: string;
visualizationRelationship: string;

toolbarBackground: string;

contextMenuBackground: string;
contextMenuSelect: string;
contextMenuHover: string;
contextMenuBorder: string;

minimapBorder: string;
minimapShadow: string;
minimapViewportBorder: string;
minimapViewportBorderHover: string;

toastBackground: string;
toastBorder: string;

dragSelectBackground: string;
dragSelectBorder: string;

scrollbarTrack: string;
scrollbarThumb: string;
scrollbarThumbHover: string;

foreground: string;
active: string;
placeholder: string;

focus: string;
inputActive: string;

keyPK: string;
keyFK: string;
keyPFK: string;

diffInsertBackground: string;
diffDeleteBackground: string;
diffCrossBackground: string;
diffInsertForeground: string;
diffDeleteForeground: string;
diffCrossForeground: string;
};

// example
editor.setTheme({
canvasBackground: '#1b1b1f',
tableBackground: '#242429',
keyPK: '#ffc53d',
});

tableShadow와 memoShadow는 ERD 캔버스에서 테이블과 메모가 드리우는 그림자의 색상입니다. 다크 preset은 이 값을 transparent로 두어, setTheme에 none이나 빈 문자열을 넘겼을 때와 마찬가지로 그림자를 드리우지 않고, 라이트 preset은 rgba(0, 0, 0, 0.18)을 사용합니다.

CSS Variables​

Theme의 모든 토큰은 --erd-editor-에 케밥 케이스 키를 붙인 CSS 훅을 가집니다. grayColor10은 --erd-editor-gray-color-10, keyPK는 --erd-editor-key-pk, keyPFK는 --erd-editor-key-pfk입니다.
훅은 에디터로 상속되므로 적용하려는 위치 어디에나 지정할 수 있습니다. :root에 지정하면 페이지의 모든 에디터에, 엘리먼트에 지정하면 해당 에디터에만 적용됩니다.

erd-editor {
--erd-editor-canvas-background: #1b1b1f;
}

3.4.0부터 잘못 표기되어 있던 dargSelect 토큰이 dragSelect로 바뀌었고, 훅도 --erd-editor-darg-select-background, --erd-editor-darg-select-border에서 --erd-editor-drag-select-background, --erd-editor-drag-select-border로 변경되었습니다. 예전 이름을 그대로 쓰는 스타일시트는 무시됩니다.

기본 테마 값
:root {
--erd-editor-gray-color-1: #111113;
--erd-editor-gray-color-2: #18191b;
--erd-editor-gray-color-3: #212225;
--erd-editor-gray-color-4: #272a2d;
--erd-editor-gray-color-5: #2e3135;
--erd-editor-gray-color-6: #363a3f;
--erd-editor-gray-color-7: #43484e;
--erd-editor-gray-color-8: #5a6169;
--erd-editor-gray-color-9: #696e77;
--erd-editor-gray-color-10: #777b84;
--erd-editor-gray-color-11: #b0b4ba;
--erd-editor-gray-color-12: #edeef0;
--erd-editor-accent-color-1: #11131f;
--erd-editor-accent-color-2: #141726;
--erd-editor-accent-color-3: #182449;
--erd-editor-accent-color-4: #1d2e62;
--erd-editor-accent-color-5: #253974;
--erd-editor-accent-color-6: #304384;
--erd-editor-accent-color-7: #3a4f97;
--erd-editor-accent-color-8: #435db1;
--erd-editor-accent-color-9: #3e63dd;
--erd-editor-accent-color-10: #5472e4;
--erd-editor-accent-color-11: #9eb1ff;
--erd-editor-accent-color-12: #d6e1ff;
--erd-editor-canvas-background: #212225;
--erd-editor-canvas-boundary-background: #111113;
--erd-editor-table-background: #18191b;
--erd-editor-table-header-background: #2e3135;
--erd-editor-table-select: #435db1;
--erd-editor-table-border: #363a3f;
--erd-editor-table-shadow: transparent;
--erd-editor-memo-background: #18191b;
--erd-editor-memo-select: #435db1;
--erd-editor-memo-border: #363a3f;
--erd-editor-memo-shadow: transparent;
--erd-editor-column-select: #182449;
--erd-editor-column-select-hover: #1d2e62;
--erd-editor-column-hover: #272a2d;
--erd-editor-relationship-hover: #435db1;
--erd-editor-visualization-link: #43484e;
--erd-editor-visualization-column: #5a6169;
--erd-editor-visualization-relationship: #5a6169;
--erd-editor-toolbar-background: #111113;
--erd-editor-context-menu-background: #18191b;
--erd-editor-context-menu-select: #272a2d;
--erd-editor-context-menu-hover: #3a4f97;
--erd-editor-context-menu-border: #363a3f;
--erd-editor-minimap-border: black;
--erd-editor-minimap-shadow: black;
--erd-editor-minimap-viewport-border: #3a4f97;
--erd-editor-minimap-viewport-border-hover: #435db1;
--erd-editor-toast-background: #18191b;
--erd-editor-toast-border: #363a3f;
--erd-editor-drag-select-background: #253974;
--erd-editor-drag-select-border: #435db1;
--erd-editor-scrollbar-track: #ddeaf814;
--erd-editor-scrollbar-thumb: #696e77;
--erd-editor-scrollbar-thumb-hover: #777b84;
--erd-editor-foreground: #b0b4ba;
--erd-editor-active: #edeef0;
--erd-editor-placeholder: #e5edfd7b;
--erd-editor-focus: #435db1;
--erd-editor-input-active: #5472e4;
--erd-editor-key-pk: #ffc53d;
--erd-editor-key-fk: #e54666;
--erd-editor-key-pfk: #00a2c7;
--erd-editor-diff-insert-background: #113b29;
--erd-editor-diff-delete-background: #500f1c;
--erd-editor-diff-cross-background: #003362;
--erd-editor-diff-insert-foreground: #3dd68c;
--erd-editor-diff-delete-foreground: #ff9592;
--erd-editor-diff-cross-foreground: #70b8ff;
}

setSchemaSQL​

Schema SQL 파일을 불러옵니다.
현재 문서에 병합하지 않고 교체합니다. 화면 위치와 확대/축소 레벨을 제외한 기존 설정은 저장 스위치를 포함해 유지되며, 파일을 읽고 나면 테이블이 자동으로 배치됩니다. 따라서 3.10.0부터 값을 한 번도 전달받지 않은 엘리먼트로 가져온 문서는 새 문서와 마찬가지로 스크롤 위치와 확대/축소 레벨을 저장하지 않습니다.
히스토리 목록에 기록되어 Undo, Redo가 가능하고, change 이벤트를 발행합니다. 빈 문자열은 무시되고, readonly가 설정된 동안에는 아무 동작도 하지 않습니다.
setSchemaGraphQL, setSchemaDBML, setSchemaAML도 동일하게 동작하며, 각 파서는 실패하지 않습니다. 읽을 수 없는 텍스트는 에러가 아니라 빈 문서로 불러옵니다.
3.10.0부터 setSchemaSQL은 문서에 현재 선택된 데이터베이스에 맞춰 파일을 읽습니다. Databricks가 선택되어 있으면 작은따옴표로 감싼 문자열은 Spark의 백슬래시 이스케이프를 따릅니다. 코멘트 문서를 참고하세요.
3.10.0부터 setSchemaSQL은 두 개 이상의 컬럼에 걸친 UNIQUE를 각 컬럼의 Unique 플래그가 아니라 하나의 unique 인덱스로 읽습니다. Unique 키와 인덱스 문서를 참고하세요.
3.10.0부터 SQL, DBML, AML 가져오기는 읽어 들인 foreign key의 ON DELETE와 ON UPDATE 동작을 유지합니다.
각 파서가 지원하는 문법은 파일 가져오기와 내보내기 문서를 참고하세요.

editor.setSchemaSQL('Schema SQL...');

setSchemaGraphQL​

GraphQL SDL 문서를 불러옵니다.
오브젝트 타입 정의는 테이블이 되고, 다른 테이블을 타입으로 갖는 필드는 관계가 됩니다.

editor.setSchemaGraphQL('GraphQL SDL...');

setSchemaDBML​

dbdiagram.io와 dbdocs에서 사용하는 형식인 DBML 파일을 불러옵니다.

editor.setSchemaDBML('DBML...');

setSchemaAML​

AML(Azimutt Markup Language) 파일을 불러옵니다. 현재 표기와 예전 v1 표기를 모두 지원합니다.

editor.setSchemaAML('AML...');

getSchemaSQL​

현재 에디터 상태를 Schema SQL로 추출합니다.
databaseVendor가 없으면 현재 에디터에 설정된 벤더로 동작합니다. 아래 목록에 없는 이름도 에러 없이 동일하게 처리됩니다.
3.10.0부터 각 foreign key에는 관계의 ON DELETE와 ON UPDATE 절이 포함됩니다. 절은 동작이 설정되어 있고 해당 벤더가 지원할 때만 작성되므로, 그 벤더가 지원하지 않는 동작은 생략되고 기본 동작이 적용됩니다. 데이터베이스별로 작성되는 내용은 ON DELETE와 ON UPDATE 문서를 참고하세요.
3.10.0부터 테이블이나 컬럼 코멘트 안의 작은따옴표를 이스케이프하므로, it's 같은 코멘트가 더 이상 구문을 깨뜨리지 않습니다. 코멘트를 문자열 리터럴로 작성하는 모든 벤더는 따옴표를 두 번 겹쳐 쓰며, Databricks만 각 따옴표와 각 백슬래시 앞에 백슬래시를 붙입니다. SQLite는 여전히 코멘트를 -- 줄로 작성합니다.

type DatabaseVendor =
| 'Databricks'
| 'MariaDB'
| 'MSSQL'
| 'MySQL'
| 'Oracle'
| 'PostgreSQL'
| 'Snowflake'
| 'SQLite';

const schemaSQL = editor.getSchemaSQL();
// or
const postgresSQL = editor.getSchemaSQL('PostgreSQL');

getSharedStore​

실시간 공동 편집을 위한 store를 반환합니다.
config는 { getNickname?, mouseTracker?, focusTracker? }입니다. 두 tracker의 기본값은 모두 true이며, mouseTracker는 이 에디터의 커서를, focusTracker는 포커스된 셀, 선택 영역, 드래그 박스를 다른 참여자에게 전송합니다.
공동 편집 문서를 참고하세요.

const sharedStore = editor.getSharedStore({
mouseTracker: false,
focusTracker: false,
});

setDiffValue​

전달한 문서와 현재 열려 있는 문서를 비교하는 Diff Viewer를 엽니다.
반환값이 없고 문서를 변경하지 않기 때문에, 뷰어를 닫으면 에디터는 그대로 유지됩니다.
빈 값이나 문자열이 아닌 값은 빈 문서와 비교합니다.
캔버스 컨텍스트 메뉴의 Diff Viewer와 동일한 화면입니다.

editor.setDiffValue('prev json...');