-
Notifications
You must be signed in to change notification settings - Fork 155
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: Table roles helper and role="grid" for editable table #1365
Conversation
Codecov ReportPatch coverage:
Additional details and impacted files@@ Coverage Diff @@
## main #1365 +/- ##
==========================================
+ Coverage 93.47% 93.48% +0.01%
==========================================
Files 624 625 +1
Lines 16778 16819 +41
Branches 5550 5562 +12
==========================================
+ Hits 15683 15724 +41
Misses 1022 1022
Partials 73 73
☔ View full report in Codecov by Sentry. |
* ARIA role of the table component ("table", "grid", "treegrid") but also roles and other semantic attributes | ||
* of the child elements. The TableRole helper encapsulates table's semantic structure. | ||
*/ | ||
export class TableRole { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We use React and this encourages us to use pure functions instead of mutable objects.
Especially, objects that you propagate across components. Does not happen in your code, because all assign
functions do not modify this
, but it paves the way for bugs.
Safer option would be to propagate the role directly, without helper
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On a higher level the it looks like this task is suitable to be solved with contexts
<TableContext role={hasEditableCells ? 'grid' : 'table'} />
const {getTableRowProps} = useTableContext();
We have several more props passing down the same way, so maybe if introducing table context, we can refactor more props into it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think contexts is an overkill here - instead I am passing a stable object's reference - it is simpler and no pub/sub is required. What do you think if I make the tableRole property readonly?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You could just propagate a string role instead of the object
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think of that class as a way of binding the helper functions to the tableRole value - surely can have a module with the functions that would accept the tableRole as an additional argument, but I like the semantics of the helper more. I think it is a good idea to ensure the internal state never changes after initialisation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Classes are not suitable for this job. If you want to know more details, welcome to my DM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I updated the helper to be a function instead, please check.
I do not understand one thing How is this better: const tableRole = createTableRoleHelper('table');
tableRole.assignTableRowProps({ firstIndex, rowIndex }); than this getRowProps({role: 'table', firstIndex, rowIndex }) I am trying really hard to understand the original motivation for grouping this, but I do not see it |
Same as you suggested above with the contexts. When there is a single helper it can be instantiated with more properties. |
export function assignTableCellProps( | ||
options: { tableRole: TableRole }, | ||
nativeProps: React.TdHTMLAttributes<HTMLTableCellElement> = {} | ||
): React.TdHTMLAttributes<HTMLTableCellElement> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On Object.assign()
, the first argument receives new properties not the last. Let's avoid confusing people and stick to the convention at least.
or the best solution, avoid using mutable objects at all, like this
{...getTableProps(tableRole)} // the object gets inside that function, no chances of overwriting something that we should not
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or for table cell
nativeAttributes.role = getTableCellRole(tableRole)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, can change the attributes order. The assignment is made to avoid objects cloning which is then has to be done for all cells and is unnecessary. Sure, can create 10 utility methods to set all attributes individually but the point was to make a single place where the semantic attributes are assigned.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You still can group all of this attribute management in a single file without mutating objects.
The ask is only about avoiding mutations, the grouping of the code is up to you
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
Description
Encapsulated table's semantic structure in a helper module and changed the table's role to "grid" for tables with editable cells.
How has this been tested?
New unit tests to verify "grid" role for tables with editable cells.
Manual testing with VO+Chrome, VO+Safari, NVDA+Chrome, NVDA+Firefox.
Review checklist
The following items are to be evaluated by the author(s) and the reviewer(s).
Correctness
CONTRIBUTING.md
.CONTRIBUTING.md
.Security
checkSafeUrl
function.Testing
By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.