Skip to content

Early previewhamur is not on npm yet. The components are being built in the open, follow along on GitHub.

CompareOverlays

Floating Panel in five frameworks

The same example, live in each framework. One core underneath, so they should behave the same.

Back to the Floating Panel docs

Live

React

Loading19.3.1

Loading React…

No event yet

Vue

Loading3.5.44

Loading Vue…

No event yet

Svelte

Loading5.57.3

Loading Svelte…

No event yet

Solid

Loading2.0.0-rc.21

Loading Solid…

No event yet

Angular

Loading22.2.4

Loading Angular…

No event yet

The attributes each framework puts on the open popup, read from the page.

AttributeReactVueSvelteSolidAngular
roleClosedClosedClosedClosedClosed
aria-modalClosedClosedClosedClosedClosed
aria-labelledbyClosedClosedClosedClosedClosed
data-openClosedClosedClosedClosedClosed

Nothing open. Open a tile to fill its column.

The same example, in each framework

Each tile above runs this file.

FloatingPanel.tsx
import { FloatingPanel } from '@hamur/react/floating-panel'

const layers = ['Header', 'Hero image', 'Headline', 'Body copy', 'Sign-up form', 'Footer']

export default function FloatingPanelExample() {
  return (
    <FloatingPanel.Root defaultSize={{ width: 320, height: 260 }}>
      <FloatingPanel.Trigger className="button">
        Open layers
      </FloatingPanel.Trigger>
      <FloatingPanel.Portal>
        <FloatingPanel.Popup className="floating-panel">
          <FloatingPanel.DragHandle className="floating-panel-bar">
            <FloatingPanel.Title className="floating-panel-title">
              Layers
            </FloatingPanel.Title>
            <FloatingPanel.Minimize className="floating-panel-button">
              <svg viewBox="0 0 24 24" aria-hidden="true">
                <path d="M5 12h14" />
              </svg>
            </FloatingPanel.Minimize>
            <FloatingPanel.Maximize className="floating-panel-button">
              <svg className="floating-panel-icon-maximize" viewBox="0 0 24 24" aria-hidden="true">
                <rect width="16" height="16" x="4" y="4" />
              </svg>
              <svg className="floating-panel-icon-restore" viewBox="0 0 24 24" aria-hidden="true">
                <path d="M8 8V4h12v12h-4M4 8h12v12H4z" />
              </svg>
            </FloatingPanel.Maximize>
            <FloatingPanel.Close
              className="floating-panel-button"
              aria-label="Close layers"
            >
              <svg viewBox="0 0 24 24" aria-hidden="true">
                <path d="M18 6 6 18M6 6l12 12" />
              </svg>
            </FloatingPanel.Close>
          </FloatingPanel.DragHandle>
          <FloatingPanel.Body className="floating-panel-body">
            <FloatingPanel.Description className="muted">
              Drag the title bar to move the panel. Focused, the arrow keys move it and Alt with the
              arrow keys resizes it.
            </FloatingPanel.Description>
            <ul className="floating-panel-list">
              {layers.map((layer) => (
                <li key={layer}>{layer}</li>
              ))}
            </ul>
          </FloatingPanel.Body>
          <FloatingPanel.ResizeHandle
            className="floating-panel-resize"
            position="bottom-right"
          >
            <svg viewBox="0 0 24 24" aria-hidden="true">
              <path d="M21 13 13 21M21 19l-2 2" />
            </svg>
          </FloatingPanel.ResizeHandle>
        </FloatingPanel.Popup>
      </FloatingPanel.Portal>
    </FloatingPanel.Root>
  )
}

Measured, per framework

The frameworks against each other only, on the same machine and the same example.

FrameworkTestsSizeOpenCloseMemory
ReactNot measured yetNot measured yetNot measured yetNot measured yetNot measured yet
Vue355Not measured yetNot measured yetNot measured yetNot measured yet
Svelte355Not measured yetNot measured yetNot measured yetNot measured yet
Solid355Not measured yetNot measured yetNot measured yetNot measured yet
Angular355Not measured yetNot measured yetNot measured yetNot measured yet

Size is the gzip of the component's entry with core and dom. Open, Close and Memory are medians in Chromium 156 on Apple M3 Max; Memory is what one open and close leaves on the heap. Tests are Floating Panel's passing tests in each framework's suites. [N] is a value not measured yet.

Same props, five spellings

The FloatingPanel.Root names in each framework's own syntax.

PropReactVueSvelteSolidAngular
openopenopenopenopen[open]
defaultOpendefaultOpendefault-opendefaultOpendefaultOpen[defaultOpen]
onOpenChangeeventonOpenChange@open-changeonOpenChangeonOpenChange(openChange)
onOpenChangeCompleteeventonOpenChangeComplete@open-change-completeonOpenChangeCompleteonOpenChangeComplete(openChangeComplete)
actionsRefactionsRefactions-refactionsRefactionsRef[actionsRef]
handlehandlehandlehandlehandle[handle]
childrenchildren#defaultchildrenchildrenng-content
triggerIdtriggerIdtrigger-idtriggerIdtriggerId[triggerId]
defaultTriggerIddefaultTriggerIddefault-trigger-iddefaultTriggerIddefaultTriggerId[defaultTriggerId]
positionpositionpositionpositionposition[position]
defaultPositiondefaultPositiondefault-positiondefaultPositiondefaultPosition[defaultPosition]
onPositionChangeeventonPositionChange@position-changeonPositionChangeonPositionChange(positionChange)
onPositionCommittedeventonPositionCommitted@position-committedonPositionCommittedonPositionCommitted(positionCommitted)
sizesizesizesizesize[size]
defaultSizedefaultSizedefault-sizedefaultSizedefaultSize[defaultSize]
onSizeChangeeventonSizeChange@size-changeonSizeChangeonSizeChange(sizeChange)
onSizeCommittedeventonSizeCommitted@size-committedonSizeCommittedonSizeCommitted(sizeCommitted)
stagestagestagestagestage[stage]
defaultStagedefaultStagedefault-stagedefaultStagedefaultStage[defaultStage]
onStageChangeeventonStageChange@stage-changeonStageChangeonStageChange(stageChange)
minSizeminSizemin-sizeminSizeminSize[minSize]
maxSizemaxSizemax-sizemaxSizemaxSize[maxSize]
boundaryboundaryboundaryboundaryboundary[boundary]
draggabledraggabledraggabledraggabledraggable[draggable]
resizableresizableresizableresizableresizable[resizable]
stepstepstepstepstep[step]
largeSteplargeSteplarge-steplargeSteplargeStep[largeStep]
labelslabelslabelslabelslabels[labels]