@blocksuite/blocks
Advanced tools
Comparing version 0.3.0-alpha.0 to 0.3.0-alpha.1
@@ -395,2 +395,5 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { | ||
} | ||
.debug-menu > button > * { | ||
flex: 1; | ||
} | ||
`; | ||
@@ -397,0 +400,0 @@ __decorate([ |
@@ -0,4 +1,4 @@ | ||
import { showLinkPopover } from '../../../components/link-popover'; | ||
import { assertExists, getRichTextByModel, getStartModelBySelection, isRangeSelection, } from '../../utils'; | ||
import './link-node'; | ||
import { showLinkPopover } from './link-popover/create-link-popover'; | ||
import { MockSelectNode } from './mock-select-node'; | ||
@@ -5,0 +5,0 @@ export const createLink = async (space, e) => { |
import './link-node'; | ||
import './link-popover'; | ||
export { LinkNodeComponent } from './link-node'; | ||
export { createLink } from './create-link'; | ||
//# sourceMappingURL=index.d.ts.map |
import './link-node'; | ||
import './link-popover'; | ||
export { LinkNodeComponent } from './link-node'; | ||
export { createLink } from './create-link'; | ||
//# sourceMappingURL=index.js.map |
import { css, svg } from 'lit'; | ||
// Control Icons with Font Size | ||
// Set the width and height to be 1em, which will be the font-size of its parent element | ||
// See https://css-tricks.com/control-icons-with-font-size/ | ||
const iconStyle = css ` | ||
@@ -9,5 +12,2 @@ width: 0.8em; | ||
`; | ||
// Control Icons with Font Size | ||
// Set the width and height to be 1em, which will be the font-size of its parent element | ||
// See https://css-tricks.com/control-icons-with-font-size/ | ||
export const LinkIcon = svg `<svg | ||
@@ -14,0 +14,0 @@ width="14" |
@@ -10,6 +10,5 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { | ||
import Quill from 'quill'; | ||
import { ALLOWED_SCHEMES, showLinkPopover, } from '../../../components/link-popover'; | ||
import { assertExists, getModelByElement, hotkey } from '../../utils'; | ||
import { LinkIcon } from './link-icon'; | ||
import { showLinkPopover } from './link-popover/create-link-popover'; | ||
import { ALLOWED_SCHEMES } from './link-popover/link-popover'; | ||
let LinkNodeComponent = class LinkNodeComponent extends LitElement { | ||
@@ -72,4 +71,6 @@ constructor() { | ||
// TODO save the format of the original text | ||
// for make a distinction between user type in and set | ||
model.text?.delete(offset, blot.length()); | ||
model.text?.insert(text, offset, { link }); | ||
model.text?.insert(text, offset); | ||
model.text?.format(offset, text.length, { link }); | ||
} | ||
@@ -76,0 +77,0 @@ else { |
@@ -11,5 +11,7 @@ import { LitElement } from 'lit'; | ||
model: BaseBlockModel; | ||
placeholder?: string; | ||
createRenderRoot(): this; | ||
firstUpdated(): void; | ||
disconnectedCallback(): void; | ||
updated(): void; | ||
render(): import("lit").TemplateResult<1>; | ||
@@ -16,0 +18,0 @@ } |
@@ -31,3 +31,3 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { | ||
firstUpdated() { | ||
const { host, model, _textContainer } = this; | ||
const { host, model, placeholder, _textContainer } = this; | ||
const { space } = host; | ||
@@ -47,15 +47,26 @@ const keyboardBindings = createKeyboardBindings(space, model); | ||
}, | ||
placeholder, | ||
}); | ||
space.attachRichText(model.id, this.quill); | ||
space.awareness.updateLocalCursor(); | ||
this.model.propsUpdated.on(() => this.requestUpdate()); | ||
// If you type a character after the code or link node, | ||
// the character should not be inserted into the code or link node. | ||
// So we check and remove the corresponding format manually. | ||
this.quill.on('text-change', delta => { | ||
// only length is 2 need to be handled | ||
let selector = ''; | ||
// only length is 2 need to be handled | ||
const selectorMap = { | ||
code: 'code', | ||
link: 'link-code', | ||
}; | ||
let attr = ''; | ||
if (delta.ops[1]?.attributes?.code) { | ||
selector = 'code'; | ||
attr = 'code'; | ||
} | ||
if (delta.ops[1]?.attributes?.link) { | ||
selector = 'link-node'; | ||
attr = 'link'; | ||
} | ||
if (delta.ops.length === 2 && delta.ops[1]?.insert && selector) { | ||
// only length is 2 need to be handled | ||
if (delta.ops.length === 2 && delta.ops[1]?.insert && attr) { | ||
const retain = delta.ops[0].retain; | ||
const selector = selectorMap[attr]; | ||
if (retain !== undefined) { | ||
@@ -69,33 +80,13 @@ const currentLeaf = this.quill.getLeaf(retain + Number(delta.ops[1]?.insert.toString().length)); | ||
const insertedString = delta.ops[1]?.insert.toString(); | ||
if (nextEmbedElement && nextEmbedElement !== currentEmbedElement) { | ||
this.quill.deleteText(retain, delta.ops[1]?.insert.toString().length); | ||
// @ts-ignore | ||
if (!this.host.isCompositionStart) { | ||
this.quill.insertText(retain, delta.ops[1]?.insert.toString() || ''); | ||
} | ||
else { | ||
// FIXME we must add a noon width space to fix cursor | ||
this.quill.insertEmbed(retain, 'text', ' '); | ||
this.quill.setSelection(retain + 1, 0, 'api'); | ||
} | ||
} | ||
if (!nextEmbedElement && insertedString) { | ||
this.quill.deleteText(retain, delta.ops[1]?.insert.toString().length); | ||
this.quill.insertEmbed(retain, 'text', | ||
// @ts-ignore | ||
if ((nextEmbedElement && nextEmbedElement !== currentEmbedElement) || | ||
!nextEmbedElement) { | ||
model.text?.replace(retain, insertedString.length, | ||
// @ts-expect-error | ||
!this.host.isCompositionStart | ||
? delta.ops[1]?.insert.toString() || '' | ||
: // FIXME we must add a noon width space to fix cursor | ||
' '); | ||
this.quill.setSelection(retain + | ||
// @ts-ignore | ||
(!this.host.isCompositionStart ? insertedString.length : 1), 0, 'api'); | ||
: ' ', { [attr]: false }); | ||
} | ||
} | ||
} | ||
// }); | ||
}); | ||
space.attachRichText(model.id, this.quill); | ||
space.awareness.updateLocalCursor(); | ||
this.model.propsUpdated.on(() => this.requestUpdate()); | ||
} | ||
@@ -106,2 +97,6 @@ disconnectedCallback() { | ||
} | ||
updated() { | ||
// Update placeholder if block`s type changed | ||
this.quill?.root.setAttribute('data-placeholder', this.placeholder ?? ''); | ||
} | ||
render() { | ||
@@ -125,2 +120,5 @@ return html ` | ||
], RichText.prototype, "model", void 0); | ||
__decorate([ | ||
property() | ||
], RichText.prototype, "placeholder", void 0); | ||
RichText = __decorate([ | ||
@@ -127,0 +125,0 @@ customElement('rich-text') |
@@ -358,2 +358,5 @@ import { assertExists, caretRangeFromPoint, matchFlavours } from './std'; | ||
const leafNodes = leftFirstSearchLeafNodes(editableContainer); | ||
if (!leafNodes.length) { | ||
return; | ||
} | ||
let startNode = leafNodes[0]; | ||
@@ -360,0 +363,0 @@ let startOffset = 0; |
@@ -10,3 +10,3 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { | ||
import { customElement, property } from 'lit/decorators.js'; | ||
import { BLOCK_ID_ATTR } from '../__internal__'; | ||
import { BLOCK_ID_ATTR, getBlockElementByModel, getDefaultPageBlock, } from '../__internal__'; | ||
import { getListIcon } from './utils/get-list-icon'; | ||
@@ -16,2 +16,12 @@ import { getListInfo } from './utils/get-list-info'; | ||
import style from './style.css'; | ||
function selectList(model) { | ||
const selectionManager = getDefaultPageBlock(model).selection; | ||
const blockElement = getBlockElementByModel(model); | ||
if (!blockElement) { | ||
console.error('list block model:', model, 'blockElement:', blockElement); | ||
throw new Error('Failed to select list! blockElement not found!'); | ||
} | ||
const selectionRect = blockElement.getBoundingClientRect(); | ||
selectionManager.selectBlockByRect(selectionRect); | ||
} | ||
let ListBlockComponent = class ListBlockComponent extends LitElement { | ||
@@ -34,4 +44,6 @@ // disable shadow DOM to workaround quill | ||
onClick: () => { | ||
if (this.model.type !== 'todo') | ||
if (this.model.type !== 'todo') { | ||
selectList(this.model); | ||
return; | ||
} | ||
this.host.space.captureSync(); | ||
@@ -38,0 +50,0 @@ this.host.space.updateBlock(this.model, { |
@@ -45,4 +45,5 @@ import type { Space } from '@blocksuite/store'; | ||
dispose(): void; | ||
selectBlockByRect(selectionRect: DOMRect): void; | ||
} | ||
export {}; | ||
//# sourceMappingURL=selection-manager.d.ts.map |
@@ -165,3 +165,12 @@ import { initMouseEventHandlers, caretRangeFromPoint, resetNativeSelection, assertExists, noop, handleNativeRangeDragMove, isBlankArea, handleNativeRangeClick, isPageTitle, handleNativeRangeDblClick, } from '../../__internal__'; | ||
} | ||
selectBlockByRect(selectionRect) { | ||
this.state.type = 'block'; | ||
this.state.refreshRichTextBoundsCache(this._container); | ||
const { richTextCache } = this.state; | ||
const selectedRichTexts = filterSelectedRichText(richTextCache, selectionRect); | ||
this.state.selectedRichTexts = selectedRichTexts; | ||
const selectedBounds = [selectionRect]; | ||
this._signals.updateSelectedRects.emit(selectedBounds); | ||
} | ||
} | ||
//# sourceMappingURL=selection-manager.js.map |
@@ -13,2 +13,21 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { | ||
import style from './style.css'; | ||
const getPlaceholder = (model) => { | ||
const { type } = model; | ||
switch (type) { | ||
case 'h1': | ||
return 'Heading 1'; | ||
case 'h2': | ||
return 'Heading 2'; | ||
case 'h3': | ||
return 'Heading 3'; | ||
case 'h4': | ||
return 'Heading 4'; | ||
case 'h5': | ||
return 'Heading 5'; | ||
case 'h6': | ||
return 'Heading 6'; | ||
default: | ||
return ''; | ||
} | ||
}; | ||
let ParagraphBlockComponent = class ParagraphBlockComponent extends LitElement { | ||
@@ -27,5 +46,10 @@ // disable shadow DOM to workaround quill | ||
const childrenContainer = BlockChildrenContainer(this.model, this.host); | ||
const placeholder = getPlaceholder(this.model); | ||
return html ` | ||
<div class="affine-paragraph-block-container ${type}"> | ||
<rich-text .host=${this.host} .model=${this.model}></rich-text> | ||
<rich-text | ||
.host=${this.host} | ||
.model=${this.model} | ||
.placeholder=${placeholder} | ||
></rich-text> | ||
${childrenContainer} | ||
@@ -32,0 +56,0 @@ </div> |
{ | ||
"name": "@blocksuite/blocks", | ||
"version": "0.3.0-alpha.0", | ||
"version": "0.3.0-alpha.1", | ||
"description": "Default BlockSuite editable blocks.", | ||
@@ -11,3 +11,3 @@ "main": "dist/index.js", | ||
"dependencies": { | ||
"@blocksuite/store": "0.3.0-alpha.0", | ||
"@blocksuite/store": "0.3.0-alpha.1", | ||
"hotkeys-js": "^3.10.0", | ||
@@ -14,0 +14,0 @@ "lit": "^2.3.1", |
@@ -259,2 +259,5 @@ import { LitElement, html, css } from 'lit'; | ||
} | ||
.debug-menu > button > * { | ||
flex: 1; | ||
} | ||
`; | ||
@@ -261,0 +264,0 @@ |
import type { Space } from '@blocksuite/store'; | ||
import { showLinkPopover } from '../../../components/link-popover'; | ||
import { | ||
@@ -9,3 +10,2 @@ assertExists, | ||
import './link-node'; | ||
import { showLinkPopover } from './link-popover/create-link-popover'; | ||
import { MockSelectNode } from './mock-select-node'; | ||
@@ -12,0 +12,0 @@ |
import './link-node'; | ||
import './link-popover'; | ||
export { LinkNodeComponent } from './link-node'; | ||
export { createLink } from './create-link'; |
import { css, svg } from 'lit'; | ||
// Control Icons with Font Size | ||
// Set the width and height to be 1em, which will be the font-size of its parent element | ||
// See https://css-tricks.com/control-icons-with-font-size/ | ||
const iconStyle = css` | ||
@@ -11,5 +14,2 @@ width: 0.8em; | ||
// Control Icons with Font Size | ||
// Set the width and height to be 1em, which will be the font-size of its parent element | ||
// See https://css-tricks.com/control-icons-with-font-size/ | ||
export const LinkIcon = svg`<svg | ||
@@ -16,0 +16,0 @@ width="14" |
import { css, html, LitElement } from 'lit'; | ||
import { customElement, property, state } from 'lit/decorators.js'; | ||
import Quill from 'quill'; | ||
import { | ||
ALLOWED_SCHEMES, | ||
showLinkPopover, | ||
} from '../../../components/link-popover'; | ||
import { assertExists, getModelByElement, hotkey } from '../../utils'; | ||
import { LinkIcon } from './link-icon'; | ||
import { showLinkPopover } from './link-popover/create-link-popover'; | ||
import { ALLOWED_SCHEMES } from './link-popover/link-popover'; | ||
@@ -104,4 +106,6 @@ // TODO fix Blot types | ||
// TODO save the format of the original text | ||
// for make a distinction between user type in and set | ||
model.text?.delete(offset, blot.length()); | ||
model.text?.insert(text, offset, { link }); | ||
model.text?.insert(text, offset); | ||
model.text?.format(offset, text.length, { link }); | ||
} else { | ||
@@ -108,0 +112,0 @@ space.captureSync(); |
@@ -42,2 +42,5 @@ import { LitElement, html, css, unsafeCSS } from 'lit'; | ||
@property() | ||
placeholder?: string; | ||
// disable shadow DOM to workaround quill | ||
@@ -49,3 +52,3 @@ createRenderRoot() { | ||
firstUpdated() { | ||
const { host, model, _textContainer } = this; | ||
const { host, model, placeholder, _textContainer } = this; | ||
const { space } = host; | ||
@@ -66,15 +69,28 @@ const keyboardBindings = createKeyboardBindings(space, model); | ||
}, | ||
placeholder, | ||
}); | ||
space.attachRichText(model.id, this.quill); | ||
space.awareness.updateLocalCursor(); | ||
this.model.propsUpdated.on(() => this.requestUpdate()); | ||
// If you type a character after the code or link node, | ||
// the character should not be inserted into the code or link node. | ||
// So we check and remove the corresponding format manually. | ||
this.quill.on('text-change', delta => { | ||
// only length is 2 need to be handled | ||
let selector = ''; | ||
// only length is 2 need to be handled | ||
const selectorMap = { | ||
code: 'code', | ||
link: 'link-code', | ||
} as const; | ||
let attr = ''; | ||
if (delta.ops[1]?.attributes?.code) { | ||
selector = 'code'; | ||
attr = 'code'; | ||
} | ||
if (delta.ops[1]?.attributes?.link) { | ||
selector = 'link-node'; | ||
attr = 'link'; | ||
} | ||
if (delta.ops.length === 2 && delta.ops[1]?.insert && selector) { | ||
// only length is 2 need to be handled | ||
if (delta.ops.length === 2 && delta.ops[1]?.insert && attr) { | ||
const retain = delta.ops[0].retain; | ||
const selector = selectorMap[attr as keyof typeof selectorMap]; | ||
if (retain !== undefined) { | ||
@@ -92,49 +108,19 @@ const currentLeaf = this.quill.getLeaf( | ||
const insertedString = delta.ops[1]?.insert.toString(); | ||
if (nextEmbedElement && nextEmbedElement !== currentEmbedElement) { | ||
this.quill.deleteText( | ||
if ( | ||
(nextEmbedElement && nextEmbedElement !== currentEmbedElement) || | ||
!nextEmbedElement | ||
) { | ||
model.text?.replace( | ||
retain, | ||
delta.ops[1]?.insert.toString().length | ||
); | ||
// @ts-ignore | ||
if (!this.host.isCompositionStart) { | ||
this.quill.insertText( | ||
retain, | ||
delta.ops[1]?.insert.toString() || '' | ||
); | ||
} else { | ||
// FIXME we must add a noon width space to fix cursor | ||
this.quill.insertEmbed(retain, 'text', ' '); | ||
this.quill.setSelection(retain + 1, 0, 'api'); | ||
} | ||
} | ||
if (!nextEmbedElement && insertedString) { | ||
this.quill.deleteText( | ||
retain, | ||
delta.ops[1]?.insert.toString().length | ||
); | ||
this.quill.insertEmbed( | ||
retain, | ||
'text', | ||
// @ts-ignore | ||
insertedString.length, | ||
// @ts-expect-error | ||
!this.host.isCompositionStart | ||
? delta.ops[1]?.insert.toString() || '' | ||
: // FIXME we must add a noon width space to fix cursor | ||
' ' | ||
: ' ', | ||
{ [attr]: false } | ||
); | ||
this.quill.setSelection( | ||
retain + | ||
// @ts-ignore | ||
(!this.host.isCompositionStart ? insertedString.length : 1), | ||
0, | ||
'api' | ||
); | ||
} | ||
} | ||
} | ||
// }); | ||
}); | ||
space.attachRichText(model.id, this.quill); | ||
space.awareness.updateLocalCursor(); | ||
this.model.propsUpdated.on(() => this.requestUpdate()); | ||
} | ||
@@ -147,2 +133,7 @@ | ||
updated() { | ||
// Update placeholder if block`s type changed | ||
this.quill?.root.setAttribute('data-placeholder', this.placeholder ?? ''); | ||
} | ||
render() { | ||
@@ -149,0 +140,0 @@ return html` |
@@ -442,2 +442,5 @@ import type { BaseBlockModel, Space } from '@blocksuite/store'; | ||
const leafNodes = leftFirstSearchLeafNodes(editableContainer); | ||
if (!leafNodes.length) { | ||
return; | ||
} | ||
let startNode = leafNodes[0]; | ||
@@ -444,0 +447,0 @@ let startOffset = 0; |
/// <reference types="vite/client" /> | ||
import { LitElement, html, css, unsafeCSS } from 'lit'; | ||
import { customElement, property } from 'lit/decorators.js'; | ||
import { BLOCK_ID_ATTR, BlockHost } from '../__internal__'; | ||
import { | ||
BLOCK_ID_ATTR, | ||
BlockHost, | ||
getBlockElementByModel, | ||
getDefaultPageBlock, | ||
} from '../__internal__'; | ||
@@ -12,2 +17,13 @@ import type { ListBlockModel } from './list-model'; | ||
function selectList(model: ListBlockModel) { | ||
const selectionManager = getDefaultPageBlock(model).selection; | ||
const blockElement = getBlockElementByModel(model); | ||
if (!blockElement) { | ||
console.error('list block model:', model, 'blockElement:', blockElement); | ||
throw new Error('Failed to select list! blockElement not found!'); | ||
} | ||
const selectionRect = blockElement.getBoundingClientRect(); | ||
selectionManager.selectBlockByRect(selectionRect); | ||
} | ||
@customElement('list-block') | ||
@@ -47,3 +63,6 @@ export class ListBlockComponent extends LitElement { | ||
onClick: () => { | ||
if (this.model.type !== 'todo') return; | ||
if (this.model.type !== 'todo') { | ||
selectList(this.model); | ||
return; | ||
} | ||
this.host.space.captureSync(); | ||
@@ -50,0 +69,0 @@ this.host.space.updateBlock(this.model, { |
@@ -148,3 +148,2 @@ import type { Space } from '@blocksuite/store'; | ||
this.state.selectedRichTexts = selectedRichTexts; | ||
const selectedBounds = selectedRichTexts.map(richText => { | ||
@@ -239,2 +238,14 @@ return richTextCache.get(richText) as DOMRect; | ||
} | ||
selectBlockByRect(selectionRect: DOMRect) { | ||
this.state.type = 'block'; | ||
this.state.refreshRichTextBoundsCache(this._container); | ||
const { richTextCache } = this.state; | ||
const selectedRichTexts = filterSelectedRichText( | ||
richTextCache, | ||
selectionRect | ||
); | ||
this.state.selectedRichTexts = selectedRichTexts; | ||
const selectedBounds: DOMRect[] = [selectionRect]; | ||
this._signals.updateSelectedRects.emit(selectedBounds); | ||
} | ||
} |
@@ -10,2 +10,22 @@ /// <reference types="vite/client" /> | ||
const getPlaceholder = (model: ParagraphBlockModel) => { | ||
const { type } = model; | ||
switch (type) { | ||
case 'h1': | ||
return 'Heading 1'; | ||
case 'h2': | ||
return 'Heading 2'; | ||
case 'h3': | ||
return 'Heading 3'; | ||
case 'h4': | ||
return 'Heading 4'; | ||
case 'h5': | ||
return 'Heading 5'; | ||
case 'h6': | ||
return 'Heading 6'; | ||
default: | ||
return ''; | ||
} | ||
}; | ||
@customElement('paragraph-block') | ||
@@ -41,6 +61,11 @@ export class ParagraphBlockComponent extends LitElement { | ||
const childrenContainer = BlockChildrenContainer(this.model, this.host); | ||
const placeholder = getPlaceholder(this.model); | ||
return html` | ||
<div class="affine-paragraph-block-container ${type}"> | ||
<rich-text .host=${this.host} .model=${this.model}></rich-text> | ||
<rich-text | ||
.host=${this.host} | ||
.model=${this.model} | ||
.placeholder=${placeholder} | ||
></rich-text> | ||
${childrenContainer} | ||
@@ -47,0 +72,0 @@ </div> |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1287754
298
27443
+ Added@blocksuite/store@0.3.0-alpha.1(transitive)
+ Addedcall-bound@1.0.2(transitive)
- Removed@blocksuite/store@0.3.0-alpha.0(transitive)
- Removedcall-bound@1.0.3(transitive)