Float region ​

Place a short description, image, or small table on the left or right and let the body text flow beside it. You can edit the region's content directly in the same editor. A dashed border appears only while editing; the preview and published view show only the content and layout.

Place the cursor inside the region in the example below and use the property tools to change its side and maximum width. In the preview, you can see the body text flowing without the dashed border.

Wings
Base typefaceOffset
HTMLLoading the editor…
JSONnabi-treeLoading the editor…
Install
npm install nabi-note
Code
import {
  createLocale, createNabiWith, mountSurface, mountToolbar,
  mountContextToolbar, mountHints, watchSettle, boldWing, linkWing,
  headingWing, alignWing, dropCapWing, bulletListWing, orderedListWing,
  taskListWing, quoteWing, floatWing, detailsWing, codeWing,
  dividerWing, tableWings, imageWing, youtubeWing, uploadWing,
  mountUpload, mountUploadView, mountViewTools,
} from 'nabi-note'

const selected = [
  boldWing,
  linkWing,
  headingWing,
  alignWing,
  dropCapWing,
  bulletListWing,
  orderedListWing,
  taskListWing,
  quoteWing,
  floatWing,
  detailsWing,
  codeWing,
  dividerWing,
  ...tableWings,
  imageWing,
  youtubeWing,
  uploadWing,
]
const locale = createLocale('en')
const { nabi, registry } = createNabiWith(selected, { locale })

// Bring your own highlighter (Prism, highlight.js, Shiki, …) — the wing stays as it is
// and only the attach is swapped (`makeCodeAttach` ships from the same door)
// { ...codeWing, attach: makeCodeAttach({ highlight: (source, lang) => [{ text: source }] }) }

const root = document.querySelector('.nabi')!
const content = document.querySelector('.nabi-content')!

const view = mountUploadView({ nabi, surface: content, locale })
const upload = mountUpload({
  nabi, root: content, locale,
  // your upload goes here — report progress with task.onProgress(0–100)
  uploader: async (task) => ({ uri: 'https://cdn.example/uploaded' }),
  extensions: ['png', 'jpg', 'pdf'], maxFileSize: 10 * 1024 * 1024,
  onStart: (tasks) => view.start(tasks),
  onProgress: (id, percent) => view.progress(id, percent),
  onSettle: () => view.settle(),
  onDone: () => view.done(),
})

// The locale also sets the direction — Arabic and Urdu run right to left
mountSurface({ nabi, registry, root: content, locale, fileSink: upload.take })

const settle = watchSettle(document, { surface: content })
const shared = { nabi, registry, surface: content, settle, locale }
const toolbar = mountToolbar({ ...shared, root: document.querySelector('#toolbar')!, onFiles: upload.take })
const context = mountContextToolbar({ ...shared, root: document.querySelector('#context')! })
mountHints({ toolbar, context, root, surface: content })
// The preview and fullscreen buttons — they stand their own box at the end of the row
mountViewTools({ ...shared, root, container: document.querySelector('#toolbar')! })

// on every change — hook up your own code here
// nabi.onChange(() => user_callback(nabi.getHtml()))

// Call from your language selector. Content and editing history stay intact.
// locale.setLocale('ko')
ts
const selected = wings().allBasic().build()

Float regions are included in the basic wings. If you assemble only the wings you need, use wings().use('float') or register floatWing directly. Also register the wings for images, tables, lists, and any other content used inside the region.

Creating and positioning ​

Place the cursor in the body text and click Float region to create an empty region. The defaults are the right side and a maximum width of 40%. Clicking after selecting several paragraphs wraps every paragraph touched by the selection in one region. You cannot wrap an existing float region again or create another float region inside one.

ts
nabi.applyCommand('insertFloat', { side: 'right', w: 40 })

With the cursor inside the region, use the property tools to change the side and maximum width. Choose a maximum width of 20%, 30%, 40%, or 50%. It is relative to the body text width, not the whole screen; short content may make the actual region narrower.

ts
nabi.applyCommand('setFloatSide', { side: 'left' })
nabi.applyCommand('setFloatWidth', { w: 30 })

Pasting text, images, or tables, converting blocks, and uploading remain inside the region. Deleting an inner table removes only that table. Inserting or converting inner blocks is unavailable when a selection spans both the inside and outside of the region.

The Unwrap float region button beside the width value returns the region's contents to the body text without deleting them. Creating, repositioning, and unwrapping all support undo and redo.

ts
nabi.applyCommand('unwrapFloat')

How text flows around the region ​

Following paragraphs flow beside the region and return to the full body width when it ends. The next heading, table, code block, divider, or new float region starts below the preceding region.

When the body width is less than 36rem, the region and body text are arranged in one column. Printing also uses one column, while preserving the saved side and maximum width. The document comparison view keeps each region's side and maximum width but places the next block separately below it to make changes easier to read.

Saving and loading ​

JSON stores the float node's a.side and a.w along with its inner blocks. HTML uses data-nabi-float and data-nabi-float-width attributes on a div inside a regular object paragraph.

html
<div data-nabi-p>
  <div data-nabi-float="right" data-nabi-float-width="40">
    <p>A description to place beside the body text.</p>
  </div>
</div>
<p>This paragraph flows beside the region.</p>

Markdown export preserves the region as HTML. Arbitrary CSS float styles are not imported, so use JSON or HTML generated by NABI NOTE for saving and restoring. Connect the same wings and CSS in the editor, SSR, preview, and published view to retain the side and width.

CSS styles ​

Style the region's colors and spacing with the [data-nabi-float] selector. The outer paragraph manages positioning and maximum width, so do not directly override float, display, or width.

css
.brand-note .nabi-content [data-nabi-float] {
  background: var(--nabi-soft);
  border-radius: var(--nabi-radius);
  padding: .75rem;
}