Files
AFFiNE-Mirror/blocksuite/affine/widgets/drag-handle/src/components/add-block-widget.ts
T
Ahsan Khaleeq 75f4c0eede feat(editor): add block button for hovering blocks (#14879)
This PR implements [feature request] #14845 

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Add-block control that appears when hovering blocks in page mode to
insert and auto-focus a new paragraph; control hides after insertion.

* **Improvements**
* Improved hover and interaction handling to avoid accidental triggers
when interacting with the drag handle or add-block control.
* Consistent sizing, positioning, and visibility behavior for the
add-block control.

* **Style**
  * Moved heading icon slightly for improved visual alignment.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: DarkSky <25152247+darkskygit@users.noreply.github.com>
2026-06-02 01:16:17 +08:00

79 lines
1.8 KiB
TypeScript

import { PlusIcon } from '@blocksuite/icons/lit';
import { css, html, LitElement } from 'lit';
import { property } from 'lit/decorators.js';
import type { AFFINE_ADD_BLOCK_WIDGET } from '../consts.js';
export class AffineAddBlockWidget extends LitElement {
static override styles = css`
:host {
display: block;
pointer-events: none;
}
.affine-add-block-widget {
display: flex;
align-items: center;
justify-content: center;
width: 18px;
height: 18px;
margin-top: 8px;
cursor: pointer;
border-radius: 4px;
color: var(--affine-placeholder-color);
background: transparent;
border: none;
padding: 0;
transition:
color 0.2s ease,
background 0.2s ease;
pointer-events: auto;
user-select: none;
box-sizing: border-box;
}
.affine-add-block-widget:hover {
background: var(--affine-hover-color);
color: var(--affine-text-primary-color);
}
.affine-add-block-widget svg {
width: 12px;
height: 12px;
flex-shrink: 0;
}
`;
@property({ type: Boolean })
accessor visible = false;
private readonly _handleClick = (e: MouseEvent) => {
e.stopPropagation();
e.preventDefault();
this.dispatchEvent(
new CustomEvent('add-block', { bubbles: true, composed: true })
);
};
override render() {
if (!this.visible) return html``;
return html`
<button
class="affine-add-block-widget"
title="Click to add a block below"
aria-label="Add block below"
@click=${this._handleClick}
>
${PlusIcon({ width: '12', height: '12' })}
</button>
`;
}
}
declare global {
interface HTMLElementTagNameMap {
[AFFINE_ADD_BLOCK_WIDGET]: AffineAddBlockWidget;
}
}