Skip to content

feat: add new impl for header and toolbar items#3657

Draft
satya164 wants to merge 1 commit intosoftware-mansion:mainfrom
satya164:@satya164/toolbar
Draft

feat: add new impl for header and toolbar items#3657
satya164 wants to merge 1 commit intosoftware-mansion:mainfrom
satya164:@satya164/toolbar

Conversation

@satya164
Copy link
Contributor

Description

This adds a new component based API and implementation for a unified header and toolbar API. It looks like following:

<Bar placement="header">
  <Bar.Item
    placement="left"
    title="Menu"
    icon={{ type: 'sfSymbol', name: 'line.3.horizontal' }}
    onPress={() => Alert.alert('Menu opened')}
  />
</Bar>

The `placement: 'header' | 'toolbar' controls where the items are placed.

This is primarily done by Codex, so it needs proper review from someone familiar with iOS.

It also doesn't implement many things currently present in the header items API, and has missing things:

  • No support for images
  • No support for custom views
  • Toolbar has some warnings related to layout
  • iOS renders right items in reverse which will be confusing looking at component order, need a way to reverse the render order
  • Anything else I have overlooked

I wasn't able to build the example app in the repo - so didn't manage to test this. Help welcome - I can add an example once I'm able to build.

Changes

  • Added the codegen references to package.json
  • Added JS files in src/bar
  • Added the native files in ios/bar

Visual documentation

92714
Code
<Bar placement="header">
  <Bar.Item
    placement="left"
    title="Menu"
    icon={{ type: 'sfSymbol', name: 'line.3.horizontal' }}
    onPress={() => Alert.alert('Menu opened')}
  />
  <Bar.Spacer />
  <Bar.Item title="Inbox" />
  <Bar.Spacer size={16} />
  <Bar.Item
    title="Notifications"
    icon={{ type: 'sfSymbol', name: 'bell' }}
    badge={{ value: 5 }}
    onPress={() => Alert.alert('Notifications')}
  />
  <Bar.Menu
    title="Actions"
    icon={{ type: 'sfSymbol', name: 'ellipsis.circle' }}
    menuTitle="Inbox Actions"
    selectedId={selectedActionId}
    onSelectionChange={({ id }) => setSelectedActionId(id)}
  >
    <Bar.MenuAction
      identifier="read"
      title="Mark as Read"
      icon={{ type: 'sfSymbol', name: 'envelope.open' }}
      keepsMenuPresented
    />
    <Bar.MenuAction
      identifier="archive"
      title="Archive"
      icon={{ type: 'sfSymbol', name: 'archivebox' }}
      onPress={() => Alert.alert('Archived')}
    />
    <Bar.MenuAction
      identifier="delete"
      title="Delete"
      destructive
      icon={{ type: 'sfSymbol', name: 'trash' }}
      onPress={() => Alert.alert('Deleted')}
    />
    <Bar.MenuAction
      identifier="disabled"
      title="Disabled"
      disabled
      icon={{ type: 'sfSymbol', name: 'slash.circle' }}
    />
    <Bar.MenuSubmenu
      identifier="sort"
      title="Sort"
      icon={{ type: 'sfSymbol', name: 'arrow.up.arrow.down' }}
      layout="palette"
    >
      <Bar.MenuAction
        identifier="sort-sender"
        title="By Sender"
        onPress={() => Alert.alert('Sorted by sender')}
      />
      <Bar.MenuAction
        identifier="sort-date"
        title="By Date"
        onPress={() => Alert.alert('Sorted by date')}
      />
    </Bar.MenuSubmenu>
  </Bar.Menu>
</Bar>
<Bar placement="toolbar">
  <Bar.Item
    title="Home"
    icon={{ type: 'sfSymbol', name: 'house' }}
    onPress={() => Alert.alert('Home')}
  />
  <Bar.Item
    title="Search"
    icon={{ type: 'sfSymbol', name: 'magnifyingglass' }}
    onPress={() => Alert.alert('Search')}
  />
  <Bar.Spacer />
  <Bar.Menu
    title="Account"
    icon={{ type: 'sfSymbol', name: 'person.crop.circle' }}
    menuTitle="Account"
    menuLayout="palette"
    menuMultiselectable
    selectedIds={selectedAccountIds}
    onSelectionChange={({ ids }) => setSelectedAccountIds(ids)}
  >
    <Bar.MenuAction
      identifier="profile"
      title="Profile"
      subtitle="View details"
      icon={{ type: 'sfSymbol', name: 'person' }}
      onPress={() => navigation.navigate('Profile')}
    />
    <Bar.MenuAction
      identifier="settings"
      title="Settings"
      icon={{ type: 'sfSymbol', name: 'gearshape' }}
      onPress={() => Alert.alert('Settings')}
    />
    <Bar.MenuAction
      identifier="logout"
      title="Logout"
      destructive
      icon={{
        type: 'sfSymbol',
        name: 'rectangle.portrait.and.arrow.right',
      }}
      onPress={() => Alert.alert('Logged out')}
    />
    <Bar.MenuSubmenu
      title="Preferences"
      icon={{ type: 'sfSymbol', name: 'slider.horizontal.3' }}
      layout="palette"
    >
      <Bar.MenuAction
        title="Notifications"
        onPress={() => Alert.alert('Notifications preferences')}
      />
      <Bar.MenuAction
        title="Privacy"
        onPress={() => Alert.alert('Privacy preferences')}
      />
    </Bar.MenuSubmenu>
  </Bar.Menu>
</Bar>

Test plan

Checklist

  • Included code example that can be used to test this change.
  • Updated / created local changelog entries in relevant test files.
  • For visual changes, included screenshots / GIFs / recordings documenting the change.
  • For API changes, updated relevant public types.
  • Ensured that CI passes

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant