Skip to content

Commit

Permalink
feat: color picker
Browse files Browse the repository at this point in the history
  • Loading branch information
dineug committed Nov 24, 2023
1 parent fa4d426 commit 8d81b2c
Show file tree
Hide file tree
Showing 19 changed files with 3,354 additions and 170 deletions.
2 changes: 2 additions & 0 deletions packages/erd-editor/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@
"@dineug/r-html": "workspace:*",
"@dineug/shared": "workspace:*",
"@dineug/vite-plugin-r-html": "workspace:*",
"@easylogic/colorpicker": "1.10.11",
"@floating-ui/dom": "1.5.3",
"@fortawesome/free-solid-svg-icons": "6.4.2",
"@mdi/js": "7.2.96",
"@radix-ui/colors": "2.1.0",
Expand Down
4 changes: 4 additions & 0 deletions packages/erd-editor/src/components/appContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
} from '@/engine/context';
import { createRxStore, RxStore } from '@/engine/rx-store';
import { Ctx } from '@/internal-types';
import { Emitter } from '@/utils/emitter';
import {
createKeyBindingMap,
KeyBindingMap,
Expand All @@ -26,6 +27,7 @@ export type AppContext = EngineContext & {
keyBindingMap: KeyBindingMap;
shortcut$: Subject<KeyBindingName>;
keydown$: Subject<KeyboardEvent>;
emitter: Emitter;
};

export type InjectAppContext = InjectEngineContext;
Expand All @@ -36,6 +38,7 @@ export function createAppContext(ctx: InjectAppContext): AppContext {
const keyBindingMap = observable(createKeyBindingMap(), { shallow: true });
const shortcut$ = new Subject<KeyBindingName>();
const keydown$ = new Subject<KeyboardEvent>();
const emitter = new Emitter();

if (import.meta.env.DEV) {
reduxDevtools(store);
Expand All @@ -48,6 +51,7 @@ export function createAppContext(ctx: InjectAppContext): AppContext {
keyBindingMap,
shortcut$,
keydown$,
emitter,
});
}

Expand Down
4 changes: 2 additions & 2 deletions packages/erd-editor/src/components/erd-editor/ErdEditor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ const ErdEditor: FC<ErdEditorProps, ErdEditorElement> = (props, ctx) => {
const root = createRef<HTMLDivElement>();
useKeyBindingMap(ctx, root);

const { theme } = useErdEditorAttachElement({
const { theme, isDarkMode } = useErdEditorAttachElement({
props,
ctx,
app: appContextValue,
Expand Down Expand Up @@ -126,7 +126,7 @@ const ErdEditor: FC<ErdEditorProps, ErdEditorElement> = (props, ctx) => {
<${Theme} .theme=${theme} />
<div
${ref(root)}
class=${styles.root}
class=${['root', styles.root, { dark: isDarkMode() }]}
tabindex="-1"
@keydown=${handleKeydown}
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -197,5 +197,6 @@ export function useErdEditorAttachElement({

return {
theme,
isDarkMode: () => themeState.options.appearance === Appearance.dark,
};
}
80 changes: 72 additions & 8 deletions packages/erd-editor/src/components/erd/Erd.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
import { createRef, FC, html, observable, ref } from '@dineug/r-html';
import {
createRef,
FC,
html,
observable,
onMounted,
ref,
} from '@dineug/r-html';

import { useAppContext } from '@/components/appContext';
import Canvas from '@/components/erd/canvas/Canvas';
Expand All @@ -7,13 +14,19 @@ import ErdContextMenu, {
ErdContextMenuType,
} from '@/components/erd/erd-context-menu/ErdContextMenu';
import Minimap from '@/components/erd/minimap/Minimap';
import ColorPicker from '@/components/primitives/color-picker/ColorPicker';
import { useContextMenuRootProvider } from '@/components/primitives/context-menu/context-menu-root/contextMenuRootContext';
import { unselectAllAction$ } from '@/engine/modules/editor/generator.actions';
import {
changeColorAllAction$,
unselectAllAction$,
} from '@/engine/modules/editor/generator.actions';
import {
streamScrollToAction,
streamZoomLevelAction,
} from '@/engine/modules/settings/atom.actions';
import { useUnmounted } from '@/hooks/useUnmounted';
import { isMouseEvent } from '@/utils/domEvent';
import { closeColorPickerAction } from '@/utils/emitter';
import { drag$, DragMove } from '@/utils/globalEventObservable';
import { getRelationshipIcon } from '@/utils/icon';
import { isMod } from '@/utils/keyboard-shortcut';
Expand All @@ -33,11 +46,17 @@ const Erd: FC<ErdProps> = (props, ctx) => {
dragSelectX: 0,
dragSelectY: 0,
contextMenuType: ErdContextMenuType.ERD as ErdContextMenuType,
relationshipId: '',
tableId: '',
relationshipId: '' as string | undefined,
tableId: '' as string | undefined,
colorPickerShow: false,
colorPickerX: 0,
colorPickerY: 0,
colorPickerInitialColor: '',
});
useErdShortcut(ctx);

const { addUnsubscribe } = useUnmounted();

const resetScroll = () => {
if (root.value.scrollTop === 0 && root.value.scrollLeft === 0) {
return;
Expand All @@ -54,10 +73,10 @@ const Erd: FC<ErdProps> = (props, ctx) => {
const $relationship = el.closest('.relationship') as HTMLElement | null;

if ($table) {
state.tableId = $table.dataset.id as string;
state.tableId = $table.dataset.id;
state.contextMenuType = ErdContextMenuType.table;
} else if ($relationship) {
state.relationshipId = $relationship.dataset.id as string;
state.relationshipId = $relationship.dataset.id;
state.contextMenuType = ErdContextMenuType.relationship;
} else {
state.contextMenuType = ErdContextMenuType.ERD;
Expand Down Expand Up @@ -91,13 +110,18 @@ const Erd: FC<ErdProps> = (props, ctx) => {
const el = event.target as HTMLElement | null;
if (!el) return;

const canHideColorPicker = !el.closest('.color-picker');

const canUnselectAll =
!el.closest('.table') &&
!el.closest('.memo') &&
!el.closest('.edit-input');
!el.closest('.edit-input') &&
!el.closest('.context-menu-content') &&
canHideColorPicker;

const canDrag =
canUnselectAll &&
canHideColorPicker &&
!el.closest('.minimap') &&
!el.closest('.minimap-viewport');

Expand All @@ -106,6 +130,11 @@ const Erd: FC<ErdProps> = (props, ctx) => {
store.dispatch(unselectAllAction$());
}

if (canHideColorPicker) {
const { emitter } = app.value;
emitter.emit(closeColorPickerAction());
}

if (!canDrag) return;

if (isMouseEvent(event) && isMod(event)) {
Expand All @@ -122,6 +151,31 @@ const Erd: FC<ErdProps> = (props, ctx) => {
state.dragSelect = false;
};

const handleChangeColorPicker = (color: string) => {
const { store } = app.value;
store.dispatch(changeColorAllAction$(color));
};

onMounted(() => {
const { emitter } = app.value;
const $root = root.value;

addUnsubscribe(
emitter.on({
openColorPicker: ({ payload: { x, y, color } }) => {
const rect = $root.getBoundingClientRect();
state.colorPickerX = x - rect.x;
state.colorPickerY = y - rect.y;
state.colorPickerInitialColor = color;
state.colorPickerShow = true;
},
closeColorPicker: () => {
state.colorPickerShow = false;
},
})
);
});

return () => {
const { store } = app.value;
const {
Expand Down Expand Up @@ -159,11 +213,21 @@ const Erd: FC<ErdProps> = (props, ctx) => {
: null}
<${ErdContextMenu}
type=${state.contextMenuType}
root=${canvas}
canvas=${canvas}
relationshipId=${state.relationshipId}
tableId=${state.tableId}
.onClose=${handleContextmenuClose}
/>
${state.colorPickerShow
? html`
<${ColorPicker}
color=${state.colorPickerInitialColor}
x=${state.colorPickerX}
y=${state.colorPickerY}
.onChange=${handleChangeColorPicker}
/>
`
: null}
</div>
`;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
fontSize9,
} from '@/styles/typography.styles';
import { calcTableHeight, calcTableWidths } from '@/utils/calcTable';
import { openColorPickerAction } from '@/utils/emitter';

import * as highLevelTableStyle from './HighLevelTable.styles';

Expand Down Expand Up @@ -46,6 +47,17 @@ const HighLevelTable: FC<HighLevelTableProps> = (props, ctx) => {
return fontSize;
};

const handleOpenColorPicker = (event: MouseEvent) => {
const { emitter } = app.value;
emitter.emit(
openColorPickerAction({
x: event.clientX,
y: event.clientY,
color: props.table.ui.color,
})
);
};

return () => {
const { store } = app.value;
const { table } = props;
Expand Down Expand Up @@ -76,6 +88,7 @@ const HighLevelTable: FC<HighLevelTableProps> = (props, ctx) => {
style=${{
'background-color': table.ui.color,
}}
@click=${handleOpenColorPicker}
></div>
</div>
<div
Expand Down
13 changes: 13 additions & 0 deletions packages/erd-editor/src/components/erd/canvas/memo/Memo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
import { Memo } from '@/internal-types';
import { calcMemoHeight, calcMemoWidth } from '@/utils/calcMemo';
import { onStop } from '@/utils/domEvent';
import { openColorPickerAction } from '@/utils/emitter';
import { drag$, DragMove } from '@/utils/globalEventObservable';
import { focusEvent } from '@/utils/internalEvents';
import { isMod, simpleShortcutToString } from '@/utils/keyboard-shortcut';
Expand Down Expand Up @@ -70,6 +71,17 @@ const Memo: FC<MemoProps> = (props, ctx) => {
ctx.host.dispatchEvent(focusEvent());
};

const handleOpenColorPicker = (event: MouseEvent) => {
const { emitter } = app.value;
emitter.emit(
openColorPickerAction({
x: event.clientX,
y: event.clientY,
color: props.memo.ui.color,
})
);
};

return () => {
const { store, keyBindingMap } = app.value;
const { memo } = props;
Expand Down Expand Up @@ -98,6 +110,7 @@ const Memo: FC<MemoProps> = (props, ctx) => {
style=${{
'background-color': memo.ui.color,
}}
@click=${handleOpenColorPicker}
></div>
<div class=${styles.headerButtonWrap}>
<${Icon}
Expand Down
13 changes: 13 additions & 0 deletions packages/erd-editor/src/components/erd/canvas/table/Table.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { bHas } from '@/utils/bit';
import { calcTableHeight, calcTableWidths } from '@/utils/calcTable';
import { query } from '@/utils/collection/query';
import { onPrevent } from '@/utils/domEvent';
import { openColorPickerAction } from '@/utils/emitter';
import { simpleShortcutToString } from '@/utils/keyboard-shortcut';

import * as styles from './Table.styles';
Expand Down Expand Up @@ -84,6 +85,17 @@ const Table: FC<TableProps> = (props, ctx) => {
}
};

const handleOpenColorPicker = (event: MouseEvent) => {
const { emitter } = app.value;
emitter.emit(
openColorPickerAction({
x: event.clientX,
y: event.clientY,
color: props.table.ui.color,
})
);
};

return () => {
const { store, keyBindingMap } = app.value;
const { settings, collections } = store.state;
Expand Down Expand Up @@ -117,6 +129,7 @@ const Table: FC<TableProps> = (props, ctx) => {
style=${{
'background-color': table.ui.color,
}}
@click=${handleOpenColorPicker}
></div>
<div class=${styles.headerButtonWrap}>
<${Icon}
Expand Down
Loading

0 comments on commit 8d81b2c

Please sign in to comment.