Плавающая область ​

Разместите короткое описание, изображение или небольшую таблицу слева или справа, чтобы основной текст обтекал их. Содержимое области можно редактировать непосредственно в том же редакторе. Пунктирная рамка появляется только при редактировании; в предпросмотре и опубликованном представлении остаются только содержимое и расположение.

Установите курсор внутри области в примере ниже и измените сторону и максимальную ширину с помощью инструментов свойств. В предпросмотре можно увидеть обтекание текста без пунктирной рамки.

Крылья
Гарнитура по умолчаниюОтступ
HTMLЗагрузка редактора…
JSONnabi-treeЗагрузка редактора…
Установка
npm install nabi-note
Код
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('ru')
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()

Плавающие области входят в базовые крылья. Если вы собираете только нужные крылья, используйте wings().use('float') или зарегистрируйте floatWing напрямую. Также зарегистрируйте крылья изображений, таблиц, списков и другого содержимого, используемого внутри области.

Создание и размещение ​

Установите курсор в основном тексте и нажмите Плавающая область, чтобы создать пустую область. По умолчанию она располагается справа с максимальной шириной 40%. Если перед нажатием выбрать несколько абзацев, все абзацы, затронутые выделением, целиком объединяются в одну область. Нельзя повторно оборачивать существующую плавающую область или создавать другую плавающую область внутри неё.

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

Когда курсор находится внутри области, инструменты свойств позволяют выбрать левую или правую сторону и максимальную ширину. Доступны 20%, 30%, 40% и 50%. Ширина задаётся относительно основного текста, а не всего экрана; при коротком содержимом фактическая область может быть уже.

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

Вставка текста, изображений и таблиц, преобразование блоков и загрузки остаются внутри области. Удаление внутренней таблицы удаляет только эту таблицу. Если выделение одновременно охватывает содержимое внутри и снаружи области, вставка и преобразование внутренних блоков недоступны.

Кнопка Убрать плавающую область рядом со значением ширины возвращает содержимое в основной текст, не удаляя его. Создание, изменение расположения и снятие обёртки поддерживают отмену и повтор.

ts
nabi.applyCommand('unwrapFloat')

Как текст обтекает область ​

Следующие абзацы обтекают область, а после её окончания снова занимают всю ширину основного текста. Следующий заголовок, таблица, блок кода, разделитель или новая плавающая область начинается ниже предыдущей области.

При ширине основного текста меньше 36rem область и текст располагаются в одну колонку. При печати также используется одна колонка, а сохранённые сторона и максимальная ширина остаются неизменными. Представление сравнения документов сохраняет сторону и максимальную ширину каждой области, но показывает следующий блок отдельно под ней, чтобы изменения было легче читать.

Сохранение и загрузка ​

JSON сохраняет a.side и a.w узла float вместе с его внутренними блоками. В HTML атрибуты data-nabi-float и data-nabi-float-width задаются на div внутри обычного объектного абзаца.

html
<div data-nabi-p>
  <div data-nabi-float="right" data-nabi-float-width="40">
    <p>Описание, расположенное рядом с основным текстом.</p>
  </div>
</div>
<p>Этот абзац продолжается рядом с областью.</p>

При экспорте в Markdown область сохраняется как HTML. Произвольные CSS-стили float не импортируются, поэтому для сохранения и восстановления используйте JSON или HTML, созданный NABI NOTE. Подключайте одинаковые крылья и CSS в редакторе, SSR, предпросмотре и опубликованном представлении, чтобы сохранить сторону и ширину.

Стили CSS ​

Цвета и отступы внутри области можно настроить селектором [data-nabi-float]. Внешний абзац управляет расположением и максимальной шириной, поэтому не переопределяйте напрямую float, display или ширину.

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