Skip to content

fix(ui-table): make TableColHeader focus outline and sorted icon over…#2142

Merged
ToMESSKa merged 1 commit intomasterfrom
INSTUI-4378-tables-focus-outline-and-sorted-icon-color-should-be-affected-by-setting-ic-brand-primary-theme-color
Sep 25, 2025
Merged

fix(ui-table): make TableColHeader focus outline and sorted icon over…#2142
ToMESSKa merged 1 commit intomasterfrom
INSTUI-4378-tables-focus-outline-and-sorted-icon-color-should-be-affected-by-setting-ic-brand-primary-theme-color

Conversation

@ToMESSKa
Copy link
Contributor

@ToMESSKa ToMESSKa commented Sep 12, 2025

…ridable by brand overrides

INSTUI-4378

ISSUE:

  • TableColHeader focus outline and sorted icon cannot be overridden by brand overrides

TEST PLAN:

  • change the value of 'ic-brand-primary' in the <InstUISettingsProvider> enclosing the <Table> in the code below
  • click on one of the headers to sort the table, the color of the header's focus outline and the sorted arrow icon should be the value set above
  • the color of the header's focus outline and that of the sorted arrow icon should be the default color without <InstUISettingsProvider>
class SortableTable extends React.Component {
    constructor(props) {
      super(props)
      const { headers } = props

      const initialColWidth = {}
      headers.forEach((header) => {
        initialColWidth[header.id] = 'start'
      })

      this.state = {
        sortBy: headers && headers[0] && headers[0].id,
        ascending: true,
        colTextAligns: initialColWidth
      }
    }

    handleSort = (event, { id }) => {
      const { sortBy, ascending } = this.state

      if (id === sortBy) {
        this.setState({
          ascending: !ascending
        })
      } else {
        this.setState({
          sortBy: id,
          ascending: true
        })
      }
    }

    handleColTextAlignChange(id, value) {
      this.setState((state) => ({
        colTextAligns: {
          ...state.colTextAligns,
          [id]: value
        }
      }))
    }

    renderHeaderRow(direction) {
      const { headers } = this.props
      const { colTextAligns, sortBy } = this.state

      return (
        <Table.Row>
          {(headers || []).map(({ id, text, width }) => (
            <Table.ColHeader
              key={id}
              id={id}
              width={width}
              {...(direction && {
                textAlign: colTextAligns[id],
                stackedSortByLabel: text,
                onRequestSort: this.handleSort,
                sortDirection: id === sortBy ? direction : 'none'
              })}
            >
              {id === sortBy ? (
                text
              ) : (
                <>
                  <span aria-hidden="true">{text}</span>
                  <ScreenReaderContent>sort by {text}</ScreenReaderContent>
                </>
              )}
            </Table.ColHeader>
          ))}
        </Table.Row>
      )
    }


    render() {
      const { caption, headers, rows } = this.props
      const { sortBy, ascending, colTextAligns } = this.state
      const direction = ascending ? 'ascending' : 'descending'
      const sortedRows = [...(rows || [])].sort((a, b) => {
        if (a[sortBy] < b[sortBy]) {
          return -1
        }
        if (a[sortBy] > b[sortBy]) {
          return 1
        }
        return 0
      })

      if (!ascending) {
        sortedRows.reverse()
      }
      return (
        <Responsive
          query={{
            small: { maxWidth: '40rem' },
            large: { minWidth: '41rem' }
          }}
          props={{
            small: { layout: 'stacked' },
            large: { layout: 'auto' }
          }}
        >
          {(props) => (
            <div>
              {props.layout !== 'stacked' && (
                <View display="block" margin="0 0 medium"></View>
              )}
              <InstUISettingsProvider
                theme={{
                  ...canvas,
                  ...{
                    'ic-brand-primary': '#127A1B'
                  }
                }}
              >
              <div>
                <Table
                  caption={`${caption}: sorted by ${sortBy} in ${direction} order`}
                  {...props}
                >
                  <Table.Head renderSortLabel="Sort by">
                    {this.renderHeaderRow(direction)}
                  </Table.Head>
                  <Table.Body>
                    {sortedRows.map((row) => (
                      <Table.Row key={row.id}>
                        {headers.map(({ id, renderCell }) => (
                          <Table.Cell key={id} textAlign={colTextAligns[id]}>
                            {renderCell ? renderCell(row[id]) : row[id]}
                          </Table.Cell>
                        ))}
                      </Table.Row>
                    ))}
                  </Table.Body>
                </Table>
                </div>
              </InstUISettingsProvider>
              <Alert
                liveRegion={() => document.getElementById('flash-messages')}
                liveRegionPoliteness="polite"
                screenReaderOnly
              >
                {`Sorted by ${sortBy} in ${direction} order`}
              </Alert>
            </div>
          )}
        </Responsive>
      )
    }
  }

  render(
    <SortableTable
      caption="Top rated movies"
      headers={[
        {
          id: 'rank',
          text: 'Rank',
          width: '15%'
        },
        {
          id: 'title',
          text: 'Title',
          width: '55%'
        },
        {
          id: 'year',
          text: 'Year',
          width: '15%'
        },
        {
          id: 'rating',
          text: 'Rating',
          width: '15%',
          renderCell: (rating) => rating.toFixed(1)
        }
      ]}
      rows={[
        {
          id: '1',
          rank: 1,
          title: 'The Shawshank Redemption',
          year: 1994,
          rating: 9.3
        }
      ]}
    />
  )

@ToMESSKa ToMESSKa self-assigned this Sep 12, 2025
@github-actions
Copy link

github-actions bot commented Sep 12, 2025

PR Preview Action v1.6.2
Preview removed because the pull request was closed.
2025-09-25 07:42 UTC

@ToMESSKa ToMESSKa force-pushed the INSTUI-4378-tables-focus-outline-and-sorted-icon-color-should-be-affected-by-setting-ic-brand-primary-theme-color branch from b8ab72f to 507ba7c Compare September 12, 2025 13:23
@ToMESSKa ToMESSKa requested a review from Copilot September 12, 2025 13:28
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR makes the TableColHeader focus outline and sorted icon colors overridable by brand theme overrides. Previously, these colors were hardcoded to use the default theme colors and could not be customized.

  • Updates the theme function to use brand primary color for focus outline and sorted icon
  • Adds theme-specific styling support with canvas theme configuration
  • Allows the 'ic-brand-primary' brand override to control both the focus outline and sorted icon colors

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

@ToMESSKa ToMESSKa requested review from HerrTopi and balzss September 12, 2025 14:31
@ToMESSKa ToMESSKa merged commit 5b8231d into master Sep 25, 2025
10 of 11 checks passed
@ToMESSKa ToMESSKa deleted the INSTUI-4378-tables-focus-outline-and-sorted-icon-color-should-be-affected-by-setting-ic-brand-primary-theme-color branch September 25, 2025 07:41
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.

3 participants