Skip to content

Commit

Permalink
Fix/at panels (#87)
Browse files Browse the repository at this point in the history
* fix: at panels

* feat: command panel

* feat: unify fonts

* refactor: font size

* fix: remove unused vars
  • Loading branch information
vincentdchan authored Nov 25, 2023
1 parent 6ec132a commit e22f1b6
Show file tree
Hide file tree
Showing 13 changed files with 196 additions and 184 deletions.
22 changes: 12 additions & 10 deletions packages/blocky-core/css/blocky-core.css
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
.blocky-default-fonts {
font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif;
}

.blocky-documents {
max-width: 580px;
font-family: var(--blocky-font);
}

.blocky-documents:focus {
Expand Down Expand Up @@ -64,25 +60,30 @@
color: rgb(52, 184, 220);
}

.blocky-block-text-content {
font-weight: 400;
font-size: 15px;
}

.blocky-h1 {
padding-top: 8px;
padding-bottom: 4px;
font-size: 28px;
font-weight: 600;
font-weight: 500;
}

.blocky-h2 {
padding-top: 8px;
padding-bottom: 4px;
font-size: 24px;
font-weight: 600;
font-weight: 500;
}

.blocky-h3 {
padding-top: 8px;
padding-bottom: 4px;
font-size: 20px;
font-weight: 600;
font-weight: 500;
}

.blocky-default-block-outline {
Expand Down Expand Up @@ -132,13 +133,13 @@
}

.blocky-cursor-label {
font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif;
font-family: var(--blocky-font);
position: absolute;
pointer-events: none;
padding: 4px;
color: white;
font-size: 11px;
z-index: 9;
}

.blocky-text-body {
Expand All @@ -156,6 +157,7 @@

.blocky-follow-widget {
position: absolute;
z-index: 10;
}

.blocky-checkbox {
Expand Down
4 changes: 4 additions & 0 deletions packages/blocky-core/src/model/theme.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
export const blockyDefaultFonts = `system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif`;

export interface ParagraphStyle {
color?: string;
fontFamily?: string;
fontSize?: number;
}

export interface ThemeData {
font?: string;

/**
* The style of primary text
*/
Expand Down
44 changes: 30 additions & 14 deletions packages/blocky-core/src/view/editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
type IDisposable,
type Position,
} from "blocky-common/es";
import { Subject, takeUntil, take, fromEvent } from "rxjs";
import { Subject, takeUntil, take, fromEvent, BehaviorSubject } from "rxjs";
import {
debounce,
isFunction,
Expand All @@ -15,7 +15,7 @@ import {
isNumber,
} from "lodash-es";
import { DocRenderer, RenderFlag, RenderOption } from "@pkg/view/renderer";
import { EditorState, SearchContext } from "@pkg/model";
import { EditorState, SearchContext, blockyDefaultFonts } from "@pkg/model";
import {
type CursorStateUpdateEvent,
BlockyTextModel,
Expand Down Expand Up @@ -133,7 +133,7 @@ export class Editor {
* So we need an array to store them.
*/
#stagedInput: TextInputEvent[] = [];
#themeData?: ThemeData;
#themeData = new BehaviorSubject<ThemeData | undefined>(undefined);
#searchContext: SearchContext | undefined;

darggingNode: BlockDataElement | undefined;
Expand Down Expand Up @@ -284,20 +284,11 @@ export class Editor {
}

get themeData(): ThemeData | undefined {
return this.#themeData;
return this.#themeData.value;
}

set themeData(themeData: ThemeData | undefined) {
this.#themeData = themeData;

if (isString(themeData?.primary?.color)) {
this.#container.style.setProperty(
"--blocky-primary-color",
themeData!.primary!.color
);
} else {
this.#container.style.setProperty("--blocky-primary-color", null);
}
this.#themeData.next(themeData);
}

addStagedInput(inputEvent: TextInputEvent) {
Expand Down Expand Up @@ -432,6 +423,31 @@ export class Editor {
newDom.spellcheck = false;
}

this.#themeData
.pipe(takeUntil(this.dispose$))
.subscribe((themeData) => {
if (isString(themeData?.primary?.color)) {
this.#container.style.setProperty(
"--blocky-primary-color",
themeData!.primary!.color
);
} else {
this.#container.style.setProperty("--blocky-primary-color", null);
}

if (isString(themeData?.font)) {
this.#container.style.setProperty(
"--blocky-font",
themeData!.font!
);
} else {
this.#container.style.setProperty(
"--blocky-font",
blockyDefaultFonts
);
}
});

fromEvent(newDom, "input")
.pipe(takeUntil(this.dispose$))
.subscribe(() => {
Expand Down
11 changes: 8 additions & 3 deletions packages/blocky-example/app/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import SpannerMenu from "./spannerMenu";
import ToolbarMenu from "./toolbarMenu";
import TianShuiWeiImage from "./tianshuiwei.jpg";
import Image from "next/image";
import { Theme } from "./themeSwitch";
import { blockyExampleFont, Theme } from "./themeSwitch";
import { isHotkey } from "is-hotkey";
import { Subject, takeUntil } from "rxjs";
import "blocky-core/css/blocky-core.css";
Expand Down Expand Up @@ -195,9 +195,14 @@ function BlockyEditorWithTheme(props: BlockyEditorWithThemeProps) {
const { darkMode, controller } = props;
useEffect(() => {
if (darkMode) {
controller.themeData = darkTheme;
controller.themeData = {
...darkTheme,
font: blockyExampleFont,
};
} else {
controller.themeData = undefined;
controller.themeData = {
font: blockyExampleFont,
};
}
}, [darkMode]);
return (
Expand Down
89 changes: 45 additions & 44 deletions packages/blocky-example/app/plugins/atPanel.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { PureComponent } from "react";
import { memo, useCallback } from "react";
import { Panel, SelectablePanel, PanelItem } from "@pkg/components/panel";
import {
type IPlugin,
Expand All @@ -9,7 +9,7 @@ import {
type PluginContext,
Delta,
} from "blocky-core";
import { makePreactFollowerWidget } from "blocky-react";
import { makeReactFollowerWidget } from "blocky-react";
import { takeUntil } from "rxjs";
import "./atPanel.scss";

Expand All @@ -18,9 +18,10 @@ interface AtPanelProps {
controller: EditorController;
}

class AtPanel extends PureComponent<AtPanelProps> {
#handleSelect = () => {
this.props.controller.applyDeltaAtCursor((index) =>
const AtPanel = memo((props: AtPanelProps) => {
const { controller, closeWidget } = props;
const handleSelect = useCallback(() => {
controller.applyDeltaAtCursor((index) =>
new Delta()
.retain(Math.max(index - 1, 0))
.delete(1)
Expand All @@ -29,31 +30,29 @@ class AtPanel extends PureComponent<AtPanelProps> {
mention: "Vincent Chan",
})
);
};
}, [controller]);

#handleClose = () => {
this.props.closeWidget();
};
const handleClose = useCallback(() => {
closeWidget();
}, [closeWidget]);

override render() {
return (
<SelectablePanel
onSelect={this.#handleSelect}
onClose={this.#handleClose}
controller={this.props.controller}
length={1}
>
{(index: number) => (
<Panel>
<div className="blocky-commands-container">
<PanelItem selected={index === 0}>Vincent Chan</PanelItem>
</div>
</Panel>
)}
</SelectablePanel>
);
}
}
return (
<SelectablePanel
onSelect={handleSelect}
onClose={handleClose}
controller={props.controller}
length={1}
>
{(index: number) => (
<Panel>
<div className="blocky-commands-container">
<PanelItem selected={index === 0}>Vincent Chan</PanelItem>
</div>
</Panel>
)}
</SelectablePanel>
);
});

class MyEmbed extends Embed {
static type = "mention";
Expand All @@ -75,25 +74,27 @@ export function makeAtPanelPlugin(): IPlugin {
embeds: [MyEmbed],
onInitialized(context: PluginContext) {
const { editor, dispose$ } = context;
editor.keyDown.pipe(takeUntil(dispose$)).subscribe((e: KeyboardEvent) => {
if (e.key !== "@") {
return;
}
editor.controller.enqueueNextTick(() => {
const blockElement = editor.controller.getBlockElementAtCursor();
if (!blockElement) {
return;
}
if (blockElement.t !== TextBlock.Name) {
editor.keyDown$
.pipe(takeUntil(dispose$))
.subscribe((e: KeyboardEvent) => {
if (e.key !== "@") {
return;
}
editor.insertFollowerWidget(
makePreactFollowerWidget(({ controller, closeWidget }) => (
<AtPanel controller={controller} closeWidget={closeWidget} />
))
);
editor.controller.enqueueNextTick(() => {
const blockElement = editor.controller.getBlockElementAtCursor();
if (!blockElement) {
return;
}
if (blockElement.t !== TextBlock.Name) {
return;
}
editor.insertFollowerWidget(
makeReactFollowerWidget(({ controller, closeWidget }) => (
<AtPanel controller={controller} closeWidget={closeWidget} />
))
);
});
});
});
},
};
}
Loading

1 comment on commit e22f1b6

@vercel
Copy link

@vercel vercel bot commented on e22f1b6 Nov 25, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.