Mixins / foldkit-mixins-ui

Drawer

namespace · packages/mixins-ui/src/drawer.ts:26

export * as Drawer from './drawer.js'

A Drawer: a panel docked to the bottom of the screen that peeks or opens, beside the page rather than over it. Nothing is trapped, dimmed or locked: the page under it stays live, so what its controls change shows at once, as a map's or an editor's tool tray. A modal one is the Sheet.

handle or grip: Swipe -> Grabbed / Dragged / Released -> update -> open or peek
handle: click or Enter -> Pressed -> update -> the other one
view: open -> data-open; a drag -> --fk-drawer-offset, --fk-drawer-progress

Let go, a flick (faster than the Sheet's FLICK_SPEED) goes its way; a slower release goes once dragged CLOSE_SHARE of the panel, and rests where it was otherwise. A press on the handle that barely moves is a click, which toggles it; the click a browser sends after a drag is no press, and is passed over. A drag starts on the handle, or on a grip the application gives an element of its own (its tabs' row), where a vertical swipe drags and a sideways one still scrolls.

The recipe (Recipes.Drawer) docks it, below a width or always, and draws the handle a bar that bends into a chevron as the drawer goes down, along with the finger while one drags it. Undocked, it is the column it sits in, and its open state waits for the next narrow screen.

In the guides

Members

Drawer.close

function · packages/mixins-ui/src/drawer.ts:102

function close(model: Model): Model

Drawer.DrawerSlots

const · packages/mixins-ui/src/drawer.ts:45

const DrawerSlots: Slots.Contract<{
  readonly panel: Slot.UnnamedSlot<
    Capability.Capability<
      'Container',
      readonly [
        Capability.Capability<
          'Interactive',
          readonly [Capability.Capability<'Base', readonly []>]
        >,
      ]
    >,
    readonly Slot.EventName[],
    readonly Slot.AttributeName[],
    readonly Slot.RequirementName[],
    boolean
  >
  readonly handle: Slot.UnnamedSlot<
    Capability.Capability<
      'Interactive',
      readonly [Capability.Capability<'Base', readonly []>]
    >,
    readonly [Event.EventToken<'click'>],
    readonly [Attr.AttrToken<'aria-expanded'>],
    readonly Slot.RequirementName[],
    boolean
  >
  readonly body: Slot.UnnamedSlot<
    Capability.Capability<
      'Container',
      readonly [
        Capability.Capability<
          'Interactive',
          readonly [Capability.Capability<'Base', readonly []>]
        >,
      ]
    >,
    readonly Slot.EventName[],
    readonly Slot.AttributeName[],
    readonly Slot.RequirementName[],
    boolean
  >
  readonly grip: Slot.UnnamedSlot<
    Capability.Capability<
      'Container',
      readonly [
        Capability.Capability<
          'Interactive',
          readonly [Capability.Capability<'Base', readonly []>]
        >,
      ]
    >,
    readonly Slot.EventName[],
    readonly Slot.AttributeName[],
    readonly Slot.RequirementName[],
    boolean
  >
}>

Drawer.DrawerView

interface · packages/mixins-ui/src/drawer.ts:173

interface DrawerView<Outer> {
  readonly model: Model
  readonly onMessage: (message: Message) => NoInfer<Outer>
  readonly labels: {
    readonly open: string
    readonly closed: string
  }
  readonly style?: NamedStyle<typeof DrawerSlots> | undefined
  readonly mixins?: MixinList<Outer> | undefined
  readonly draw: (drawer: ResolvedDrawer<Outer>) => Html
}

Drawer.init

function · packages/mixins-ui/src/drawer.ts:91

function init(config: InitConfig): Model

Drawer.InitConfig

interface · packages/mixins-ui/src/drawer.ts:84

interface InitConfig {
  readonly id: string
  readonly open?: boolean
}

Drawer.Message

const · packages/mixins-ui/src/drawer.ts:72

const Message: MessageUnion<{
  readonly Grabbed: {
    readonly size: Schema.Number
    readonly from: Schema.Literals<readonly ['handle', 'grip']>
  }
  readonly Dragged: { readonly delta: Schema.Number }
  readonly Released: {
    readonly delta: Schema.Number
    readonly velocity: Schema.Number
    readonly completed: Schema.Boolean
  }
  readonly Pressed: {}
}>

Drawer.Model

const · packages/mixins-ui/src/drawer.ts:61

const Model: Schema.Struct<{
  readonly id: Schema.String
  readonly open: Schema.Boolean
  readonly drag: Schema.Option<
    Schema.Struct<{
      readonly size: Schema.Number
      readonly delta: Schema.Number
      readonly from: Schema.Literals<readonly ['handle', 'grip']>
    }>
  >
  readonly dragged: Schema.Boolean
}>

Drawer.open

function · packages/mixins-ui/src/drawer.ts:99

function open(model: Model): Model

Opens the Drawer, as a control elsewhere that wants its contents seen does.

Drawer.Origin

const · packages/mixins-ui/src/drawer.ts:58

const Origin: Schema.Literals<readonly ['handle', 'grip']>

Where a drag began: the handle, whose click it ends with, or a grip, which has none.

Drawer.progress

function · packages/mixins-ui/src/drawer.ts:161

function progress(
  model: Model,
  drag: {
    readonly size: number
    readonly delta: number
  },
): number

How far down it is, from 0 (open) to 1 (peeking), during a drag: what the handle bends by. The drag is read against the panel's height, which is a little more than it travels, so the chevron is not quite full at the peek.

Drawer.ResolvedDrawer

interface · packages/mixins-ui/src/drawer.ts:165

interface ResolvedDrawer<Message> {
  readonly panel: SlotAttributes<Message>
  readonly handle: SlotAttributes<Message>
  readonly body: SlotAttributes<Message>
  readonly grip: SlotAttributes<Message>
}

The attributes the Drawer's view hands draw, each slot's own.

Drawer.settle

function · packages/mixins-ui/src/drawer.ts:106

function settle(release: {
  readonly open: boolean
  readonly size: number
  readonly delta: number
  readonly velocity: number
}): boolean

Whether a drag let go at delta, moving at velocity, leaves it open.

Drawer.update

function · packages/mixins-ui/src/drawer.ts:119

function update(model: Model, message: Message): Model

The Drawer after message; the same Model when nothing changes.

Drawer.view

function · packages/mixins-ui/src/drawer.ts:191

function view<Outer>(options: DrawerView<Outer>, h: HtmlBuilder<Outer>): Html