Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add S2 ActionBar component #7446

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft

feat: Add S2 ActionBar component #7446

wants to merge 1 commit into from

Conversation

devongovett
Copy link
Member

This adds the ActionBar component to S2. It works slightly differently from S1:

  • It appears on top of the collection component rather than shrinking the collection and appearing below it. This is better for performance since it doesn't require an animated relayout which is especially expensive with virtualizer. To still allow users to scroll to the bottom and see the last rows, padding is added at the end of the scrollable content to make room for the action bar.
  • Instead of wrapping a collection component in an ActionBarContainer, there is a renderActionBar prop of each collection. This allows it to be more integrated, giving CardView/TableView more control over how the action bar is positioned. It also means you don't need to make selection controlled anymore, and you don't need to wire up the selectedItemsCount and onClearSelection props. The selected keys are passed into renderActionBar so you can conditionally adjust which actions are available, and trigger actions on those items on press.

selectionMode="multiple"
renderActionBar={selectedKeys => (
<ActionBar {...args}>
<ActionButtonGroup>
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want to accept action buttons directly as children of the ActionBar or have them pass in the group themselves? Depends if we want to allow more customization.

setLastCount(selectedItemCount);
}

let staticColor = isEmphasized ? 'black' as const : undefined;
Copy link
Member Author

@devongovett devongovett Nov 28, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Somehow we need to make this swap to white in light theme and I haven't figured out how to do that yet. We don't always have a way of reading the current theme via JS anymore, it's all in CSS.

@rspbot
Copy link

rspbot commented Nov 28, 2024

@rspbot
Copy link

rspbot commented Nov 28, 2024

## API Changes

@react-spectrum/s2

/@react-spectrum/s2:ActionButtonGroup

 ActionButtonGroup {
   UNSAFE_className?: string
   UNSAFE_style?: CSSProperties
+  aria-describedby?: string
+  aria-details?: string
+  aria-label?: string
+  aria-labelledby?: string
   children: ReactNode
   density?: 'compact' | 'regular' = "regular"
   isDisabled?: boolean
   isJustified?: boolean
   orientation?: 'horizontal' | 'vertical' = 'horizontal'
   size?: 'XS' | 'S' | 'M' | 'L' | 'XL' = "M"
   slot?: string | null
   staticColor?: 'white' | 'black'
   styles?: StylesPropWithHeight
 }

/@react-spectrum/s2:CardView

 CardView <T extends {}> {
   UNSAFE_className?: string
   UNSAFE_style?: CSSProperties
   aria-describedby?: string
   aria-details?: string
   aria-label?: string
   aria-labelledby?: string
   children?: ReactNode | (T) => ReactNode
   defaultSelectedKeys?: 'all' | Iterable<Key>
   density?: 'compact' | 'regular' | 'spacious' = 'regular'
   dependencies?: Array<any>
   disabledBehavior?: DisabledBehavior
   disabledKeys?: Iterable<Key>
   disallowEmptySelection?: boolean
   dragAndDropHooks?: DragAndDropHooks
   id?: string
   items?: Iterable<T>
   layout?: 'grid' | 'waterfall' = 'grid'
   loadingState?: LoadingState
   onAction?: (Key) => void
   onLoadMore?: () => void
   onScroll?: (UIEvent<Element>) => void
   onSelectionChange?: (Selection) => void
+  renderActionBar?: ('all' | Set<Key>) => ReactElement
   renderEmptyState?: (GridListRenderProps) => ReactNode
   selectedKeys?: 'all' | Iterable<Key>
   selectionMode?: SelectionMode
   selectionStyle?: 'checkbox' | 'highlight' = 'checkbox'
   slot?: string | null
   styles?: StylesPropWithHeight
   variant?: 'primary' | 'secondary' | 'tertiary' | 'quiet' = 'primary'
 }

/@react-spectrum/s2:CloseButton

 CloseButton {
   UNSAFE_className?: string
   UNSAFE_style?: CSSProperties
   isDisabled?: boolean
+  onPress?: (PressEvent) => void
   size?: 'S' | 'M' | 'L' | 'XL' = 'M'
   staticColor?: 'white' | 'black'
   styles?: StylesProp
 }

/@react-spectrum/s2:TableView

 TableView {
   UNSAFE_className?: string
   UNSAFE_style?: CSSProperties
   aria-describedby?: string
   aria-details?: string
   aria-label?: string
   aria-labelledby?: string
   children?: ReactNode
   defaultSelectedKeys?: 'all' | Iterable<Key>
   density?: 'compact' | 'spacious' | 'regular' = 'regular'
   disabledKeys?: Iterable<Key>
   disallowEmptySelection?: boolean
   isQuiet?: boolean
   loadingState?: LoadingState
   onAction?: (Key) => void
   onLoadMore?: () => any
   onResize?: (Map<Key, ColumnSize>) => void
   onResizeEnd?: (Map<Key, ColumnSize>) => void
   onResizeStart?: (Map<Key, ColumnSize>) => void
   onSelectionChange?: (Selection) => void
   onSortChange?: (SortDescriptor) => any
   overflowMode?: 'wrap' | 'truncate' = 'truncate'
+  renderActionBar?: ('all' | Set<Key>) => ReactElement
   selectedKeys?: 'all' | Iterable<Key>
   selectionMode?: SelectionMode
   slot?: string | null
   sortDescriptor?: SortDescriptor
 }

/@react-spectrum/s2:ActionButtonGroupProps

 ActionButtonGroupProps {
   UNSAFE_className?: string
   UNSAFE_style?: CSSProperties
+  aria-describedby?: string
+  aria-details?: string
+  aria-label?: string
+  aria-labelledby?: string
   children: ReactNode
   density?: 'compact' | 'regular' = "regular"
   isDisabled?: boolean
   isJustified?: boolean
   orientation?: 'horizontal' | 'vertical' = 'horizontal'
   size?: 'XS' | 'S' | 'M' | 'L' | 'XL' = "M"
   slot?: string | null
   staticColor?: 'white' | 'black'
   styles?: StylesPropWithHeight
 }

/@react-spectrum/s2:CardViewProps

 CardViewProps <T> {
   UNSAFE_className?: string
   UNSAFE_style?: CSSProperties
   aria-describedby?: string
   aria-details?: string
   aria-label?: string
   aria-labelledby?: string
   children?: ReactNode | (T) => ReactNode
   defaultSelectedKeys?: 'all' | Iterable<Key>
   density?: 'compact' | 'regular' | 'spacious' = 'regular'
   dependencies?: Array<any>
   disabledBehavior?: DisabledBehavior
   disabledKeys?: Iterable<Key>
   disallowEmptySelection?: boolean
   dragAndDropHooks?: DragAndDropHooks
   id?: string
   items?: Iterable<T>
   layout?: 'grid' | 'waterfall' = 'grid'
   loadingState?: LoadingState
   onAction?: (Key) => void
   onLoadMore?: () => void
   onScroll?: (UIEvent<Element>) => void
   onSelectionChange?: (Selection) => void
+  renderActionBar?: ('all' | Set<Key>) => ReactElement
   renderEmptyState?: (GridListRenderProps) => ReactNode
   selectedKeys?: 'all' | Iterable<Key>
   selectionMode?: SelectionMode
   selectionStyle?: 'checkbox' | 'highlight' = 'checkbox'
   slot?: string | null
   styles?: StylesPropWithHeight
   variant?: 'primary' | 'secondary' | 'tertiary' | 'quiet' = 'primary'
 }

/@react-spectrum/s2:CloseButtonProps

 CloseButtonProps {
   UNSAFE_className?: string
   UNSAFE_style?: CSSProperties
   isDisabled?: boolean
+  onPress?: (PressEvent) => void
   size?: 'S' | 'M' | 'L' | 'XL' = 'M'
   staticColor?: 'white' | 'black'
   styles?: StylesProp
 }

/@react-spectrum/s2:TableViewProps

 TableViewProps {
   UNSAFE_className?: string
   UNSAFE_style?: CSSProperties
   aria-describedby?: string
   aria-details?: string
   aria-label?: string
   aria-labelledby?: string
   children?: ReactNode
   defaultSelectedKeys?: 'all' | Iterable<Key>
   density?: 'compact' | 'spacious' | 'regular' = 'regular'
   disabledKeys?: Iterable<Key>
   disallowEmptySelection?: boolean
   isQuiet?: boolean
   loadingState?: LoadingState
   onAction?: (Key) => void
   onLoadMore?: () => any
   onResize?: (Map<Key, ColumnSize>) => void
   onResizeEnd?: (Map<Key, ColumnSize>) => void
   onResizeStart?: (Map<Key, ColumnSize>) => void
   onSelectionChange?: (Selection) => void
   onSortChange?: (SortDescriptor) => any
   overflowMode?: 'wrap' | 'truncate' = 'truncate'
+  renderActionBar?: ('all' | Set<Key>) => ReactElement
   selectedKeys?: 'all' | Iterable<Key>
   selectionMode?: SelectionMode
   slot?: string | null
   sortDescriptor?: SortDescriptor
 }

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.

2 participants