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

DateTimePicker: re-implement component with react-datepicker component #25428

Closed
wants to merge 34 commits into from

Conversation

retrofox
Copy link
Contributor

@retrofox retrofox commented Sep 17, 2020

Description

This PR exposes several issues in the current implementation of the <PostSchdule /> component, suggesting some solutions. Please take it as a look-into PR. The goal here is to be able to decide if these changes could work.

Fixes #13713
Fixes #22387
Fixes #15348
Fixes #21820

react-dates vs react-datepicker

The biggest change here is replacing the react-dates component with the react-datepicker one. It's funny because we did the opposite almost two years ago.

Why switching again?

  • Last change in react-dates was made almost one year ago.
  • react-datepicker got rid of moment.js in favor of date-fns. There are many reasons why date-fns could be better than moment.js. Here there is a good comparison and analysis page. This is something that could be beneficial for the core-editor.
  • Primary reason why react-datepicker was replaced was some a11y issues. It has changed considerably, and now it has nice support for a11y. Not sure if it will enough.
  • The component extensibility and integration seem to be better with react-datepicker than with react-dates.
    For instance, we've used <Button /> component to redefine the calendar header nav buttons, and <Tooltip /> to show date events for each calendar day when it's appropriated. Both of these components belong to @wordpress/components. The integration was almost flawless.

a11y

As we said above, one of the tougher points of react-datepicker was about accessibility. Pleasantly, it has changed considerably lately on this component. It supports key navigation very well. And again, the integration with other components is very good too. Navigation through tabbing works as expected.
Another important improvement added on this Pull Request is the screen reader support, allowing us fixing #15348.

It worths mentioning there are some weird issues (in master branch) when setting the date via the TimePicker component. Something about dealing with onBlur event. Here another hacky solution to attempt to handle it.

Highligh events

Highlighting site events in the Calendar is one of the goals behind all these changes. We tried with the react-dates library and it doesn't work in an acceptable way, IMO.
This PR was the first attempt to tackle it. The bigger issue is how to propagate the events to the calendar to finally highlight them.
From the point of view if the <PostSchedule />, events are site posts with publish and future status. Naturally, these data are gotten asynchronously using the getEntityRecords() selector. The problem is there isn't a good way (AFAIK) to refresh these data in the react-dates components.
Also, this async flows happens when the month changes since we'd like to perform a request per month.
We've done some hacky solutions to deal with this, for instance, when hack to force the calendar to update on month or year change. In short, it's a lack of onMonthChange component event.

Events Tooltip

As a nice extra improvement, we'd like to show events per day (no more than four) by each day. It's very useful to know if there already are scheduled posts on the site, for instance. It was kind of easily implemented using the react-datepicker component.

Other changes / improvements

  • Do not move the popover when the date changes
  • Fix some visual issues. Some of them have been reported here.

Issue / Fixes

  • ...
  • ...
  • ...

How has this been tested?

Editing a post / page / etc. Try to add other posts defining different dates in order to get some days highlighted. Also, for these days, do a mouse over the day in order to see the events tooltip.

Screenshots

Before After

Highlighted events

Events tooltip

Only one event many events per day

📹 Live: Site events

It fetches events per month, every time that the month view changes. In this example,

  • Open the calendar, focused in the month of today
  • Fetch events by month
  • Highlight the events
  • Show day-events tooltip when mouse over the day.

calendar-events-2

📹 Live: a11y

All interactions are performed via the keyboard,

calendar-a11y

Types of changes

Checklist:

  • My code is tested.
  • My code follows the WordPress code style.
  • My code follows the accessibility standards.
  • My code has proper inline documentation.
  • I've included developer documentation if appropriate.
  • I've updated all React Native files affected by any refactorings/renamings in this PR.

@retrofox retrofox self-assigned this Sep 17, 2020
@retrofox retrofox added [Feature] UI Components Impacts or related to the UI component system [Status] In Progress Tracking issues with work in progress Storybook Storybook and its stories for components labels Sep 17, 2020
@github-actions
Copy link

github-actions bot commented Sep 21, 2020

Size Change: +102 kB (8%) 🔍

Total Size: 1.27 MB

Filename Size Change
build/a11y/index.js 1.14 kB -1 B
build/annotations/index.js 3.54 kB +17 B (0%)
build/api-fetch/index.js 3.34 kB +1 B
build/block-directory/index.js 8.53 kB -2 B (0%)
build/block-editor/index.js 128 kB +110 B (0%)
build/block-library/index.js 135 kB -14 B (0%)
build/blocks/index.js 47.5 kB -22 B (0%)
build/components/index.js 268 kB +101 kB (37%) 🚨
build/components/style-rtl.css 16 kB +512 B (3%)
build/components/style.css 16 kB +521 B (3%)
build/compose/index.js 9.42 kB -1 B
build/core-data/index.js 12 kB +13 B (0%)
build/data-controls/index.js 1.27 kB -3 B (0%)
build/data/index.js 8.43 kB -2 B (0%)
build/date/index.js 31.9 kB +3 B (0%)
build/dom-ready/index.js 569 B +1 B
build/dom/index.js 4.42 kB -1 B
build/edit-navigation/index.js 10.4 kB -4 B (0%)
build/edit-post/index.js 306 kB +23 B (0%)
build/edit-post/style-rtl.css 6.26 kB +20 B (0%)
build/edit-post/style.css 6.25 kB +20 B (0%)
build/edit-site/index.js 19.6 kB +9 B (0%)
build/edit-widgets/index.js 17.6 kB +2 B (0%)
build/editor/index.js 45.7 kB +194 B (0%)
build/element/index.js 4.45 kB -3 B (0%)
build/format-library/index.js 7.49 kB -1 B
build/html-entities/index.js 622 B +1 B
build/i18n/index.js 3.54 kB -3 B (0%)
build/is-shallow-equal/index.js 710 B +1 B
build/keyboard-shortcuts/index.js 2.38 kB -5 B (0%)
build/media-utils/index.js 5.12 kB +2 B (0%)
build/nux/index.js 3.28 kB +7 B (0%)
build/plugins/index.js 2.44 kB -1 B
build/redux-routine/index.js 2.85 kB +1 B
build/rich-text/index.js 13.7 kB -17 B (0%)
build/url/index.js 4.06 kB +1 B
build/viewport/index.js 1.74 kB +2 B (0%)
build/warning/index.js 1.14 kB +6 B (0%)
ℹ️ View Unchanged
Filename Size Change
build/autop/index.js 2.72 kB 0 B
build/blob/index.js 620 B 0 B
build/block-directory/style-rtl.css 943 B 0 B
build/block-directory/style.css 942 B 0 B
build/block-editor/style-rtl.css 11.1 kB 0 B
build/block-editor/style.css 11.1 kB 0 B
build/block-library/editor-rtl.css 8.56 kB 0 B
build/block-library/editor.css 8.56 kB 0 B
build/block-library/style-rtl.css 7.6 kB 0 B
build/block-library/style.css 7.59 kB 0 B
build/block-library/theme-rtl.css 741 B 0 B
build/block-library/theme.css 741 B 0 B
build/block-serialization-default-parser/index.js 1.78 kB 0 B
build/block-serialization-spec-parser/index.js 3.1 kB 0 B
build/deprecated/index.js 772 B 0 B
build/edit-navigation/style-rtl.css 868 B 0 B
build/edit-navigation/style.css 871 B 0 B
build/edit-site/style-rtl.css 3.3 kB 0 B
build/edit-site/style.css 3.3 kB 0 B
build/edit-widgets/style-rtl.css 2.8 kB 0 B
build/edit-widgets/style.css 2.8 kB 0 B
build/editor/editor-styles-rtl.css 492 B 0 B
build/editor/editor-styles.css 493 B 0 B
build/editor/style-rtl.css 3.8 kB 0 B
build/editor/style.css 3.8 kB 0 B
build/escape-html/index.js 733 B 0 B
build/format-library/style-rtl.css 547 B 0 B
build/format-library/style.css 548 B 0 B
build/hooks/index.js 1.74 kB 0 B
build/keycodes/index.js 1.85 kB 0 B
build/list-reusable-blocks/index.js 3.02 kB 0 B
build/list-reusable-blocks/style-rtl.css 476 B 0 B
build/list-reusable-blocks/style.css 476 B 0 B
build/notices/index.js 1.69 kB 0 B
build/nux/style-rtl.css 671 B 0 B
build/nux/style.css 668 B 0 B
build/primitives/index.js 1.34 kB 0 B
build/priority-queue/index.js 789 B 0 B
build/server-side-render/index.js 2.61 kB 0 B
build/shortcode/index.js 1.7 kB 0 B
build/token-list/index.js 1.24 kB 0 B
build/wordcount/index.js 1.17 kB 0 B

compressed-size-action

@retrofox retrofox force-pushed the update/post-schedule-switch-calendar-component branch from 5561271 to 36bf38c Compare September 21, 2020 15:07
import DayPickerSingleDateController from 'react-dates/lib/components/DayPickerSingleDateController';
import ReactDatePicker from 'react-datepicker';
import { isSameDay, format, setMonth, getMonth, getYear, getDate } from 'date-fns';
import { map, filter } from 'lodash';
Copy link
Member

Choose a reason for hiding this comment

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

I'd recommend using the native JS [].map and [].filter over the Lodash versions when possible.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

👍

@retrofox retrofox changed the title [wip] DateTimePicker: replace react-dates with react-datepicker [wip] DateTimePicker: re-implement component with react-datepicker component Sep 22, 2020
@afercia
Copy link
Contributor

afercia commented Sep 24, 2020

@retrofox I have a huge queue of tasks to go through 🙂 Will try go get to this as soon as possible.

In the meantime, can you explain please what is the value added for users here? At first glance, this change seems prioritizing developers convenience over users experience.

It has changed considerably, and now it has nice support for a11y. Not sure if it will enough.

Also, if possible, can you provide a list of the a11y improvements landed in react-datepicker? That would greatly help.

@retrofox
Copy link
Contributor Author

retrofox commented Sep 24, 2020

@retrofox I have a huge queue of tasks to go through 🙂 Will try go get to this as soon as possible.

I bet you have. Thanks in advance.

In the meantime, can you explain please what is the value added for users here? At first glance, this change seems prioritizing developers convenience over users experience.

Not at all :-). From my POV, the goal for these improvements is to be able to:

  • highlight site events in the calendar. Very useful when users want to organize their site agenda. For instance, when scheduling a post you will get aware that maybe you're going to push two posts on the same date (we need to work on the a11y for this feature)
  • Show information about events, by date. It's tackled using a Tooltip component. Again, we need to work on the a11y here too.

We tried to do the same with the current dev libraries, I ran into many issues, here yes, from the development point of view.

It has changed considerably, and now it has nice support for a11y. Not sure if it will enough.

Also, if possible, can you provide a list of the a11y improvements landed in react-datepicker? That would greatly help.

These issues reported by you here:

  • not operable with a keyboard
  • empty and not focusable prev/next month links
  • day names not in relationship with the day numbers
  • arguable values for the day aria-labels, e.g. day-15
  • missing labels for the hour/minutes fields

Not 100% sure whether the last two ones are rightly handled, but if not, I'm guessing tackle them it isn't a big deal. The most important issues were about keyboard focus issues.

Thanks for your feedback, Andrea.

@chrisvanpatten
Copy link
Member

I'm definitely excited for this — the DateTime component has been rather difficult to work with as a third party. Hope to see this land and bring some needed improvements to the date picker :) Thanks @retrofox!

@afercia
Copy link
Contributor

afercia commented Sep 24, 2020

@tellthemachines if I remember correctly you worked a lot on the current implementation. Any thoughts here? 🙂

@afercia
Copy link
Contributor

afercia commented Sep 24, 2020

Any chance that this switch will solve also #15348 ?
As mentioned on the issue, it depends also on the Date/Time setting set in WordPress but in some cases all the days in the month are announced in a way that screen readers really can't make use of. For example:

  • Monday, j F 2020
  • Tuesday, j F 2020
  • Wednesday, j F 2020
  • etc.

This has always been broken since WP 5.0 and still needs to be fixed...

@retrofox
Copy link
Contributor Author

Any chance that this switch will solve also #15348 ?
As mentioned on the issue, it depends also on the Date/Time setting set in WordPress but in some cases all the days in the month are announced in a way that screen readers really can't make use of. For example:

  • Monday, j F 2020
  • Tuesday, j F 2020
  • Wednesday, j F 2020
  • etc.

This has always been broken since WP 5.0 and still needs to be fixed...

Happy to at least try to bring a solution.

@retrofox
Copy link
Contributor Author

Any chance that this switch will solve also #15348 ?

Let me cross the comment link and update the PR description, but in short, the answer is yes. It's easily doable.

icon={ 'arrow-left-alt' }
isSmall={ true }
onClick={ decreaseMonth }
/>
Copy link
Contributor

Choose a reason for hiding this comment

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

This button is empty so screen readers will only announce "button".
Te original react-datepicker button has both off-screen text and an aria-label.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes, agree. Keep in mind Andrea this PR is full of remaining issues. The primary purpose is to be able to know is switching the component will allow us to improve the whole implementation.
Anyway, I'm blad to keep update and polishing!

icon={ 'arrow-right-alt' }
isSmall={ true }
onClick={ increaseMonth }
/>
Copy link
Contributor

Choose a reason for hiding this comment

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

Same as above: empty button

@afercia
Copy link
Contributor

afercia commented Sep 28, 2020

Tested a bit this PR and, from an accessibility perspective, there are a few problems to solve mainly related to keyboard navigation with screen readers and labelling. On a general level, I'm not sure react-datepicker has full support for internationalization and RTL languages; this is a technical part that should be evaluated separately.

It's going to be a bit long so I'm going to use one comment for each issue 🙂

First: keyboard navigation with screen readers

VoiceOver on mac works pretty differently from screen readers on Windows. The Windows ones (e.g NVDA, JAWS) use two main modes to navigate the content. Let's call these modes "browse mode" and "focus mode", even if the terminology changes depending on the screen reader. In browse mode, screen readers intercept most of the key presses for their internal usage. For example, the arrow keys are used to navigate the content. In this mode, key strokes are not passed to the browser so any script relying on keyboard events simply doesn't work. This is the main navigation mode used by users. Instead, focus mode is mainly used for form elements ot with some specific ARIA roles.

Why this matters:

Since selecting the day in the calendar month relies on keyboard events, in browse mode the day selection totally fails. See the animated GIF below that illustrates the behavior with Firefox and NVDA:

  • Left and right arrows navigate the content by character: this is the expected behavior with a screen reader but in the calendar this is supposed to select the previous or next day.
  • Up and down arrows randomly make the day selection jump by 2 or 3 days: with a screen reader, these keys are expected to move to the previous / next "line" but in the calendar they're supposed to move to the previous / next week.

calendar

The reason why the calendar works in the current react-dates based implementation is that the DayPicker component uses an ARIA role="application". Instead, react-datepicker doesn't. This role, amongst other things, instructs screen readers to stop intercepting key presses so they're passed to the browser and any script relying on keyboard events "magically" works again.

The role="application" is very debated amongst specialists as it brings in also undesired side effects and its usage should be limited to very rare cases but in this specific case I can't think of another way to "fix" the day selection. Without this, the calendar would be totally unusable to Windows screen reader users.

Possible options:

1
Ideally, role="application" should be added to the container of the days:

calendar

I'm not sure there's a way to do that, though.

2
Alternatively, I see react-datepicker has a container prop that can be used to add a wrapper around the whole widget. This could be used to wrap everything in a div with the role and an aria-label. More or less:

const RoleApplicationContainer = ( { className, children } ) => {
	return (
	  <div role="application" aria-label={ __( 'Calendar' ) } className={ className }>
	      { children }
	  </div>
	);
};

and then pass the custom container to the date picker: calendarContainer={ RoleApplicationContainer }. However, this would wrap the whole widget within the ARIA role, which isn't ideal.

3
Maybe better: report upstream and ask to add the role + aria-label and wait for the change to be released.

For the records, I tested the option 2) and it fixes the problem.

@retrofox
Copy link
Contributor Author

Tested a bit this PR and, from an accessibility perspective, there are a few problems ...

Thanks for your awesome feedback, Andrea. Very useful <3. I'm going to create a checklist in the PR description to organize the next actions to take. Please, feel free to add/edit.

@afercia
Copy link
Contributor

afercia commented Sep 28, 2020

Labelling and localization / internationalization

While the dates are "automatically" translated based on the locale, I see that react-datepicker uses some strings for its on user interface. I'm not sure these strings are translatable: they appear to be hardcoded. Also, at least one of these strings seems to be a bit pointless. For example:

  • The month container has an aria-label="month 2020-09" which doesn't appear to be translatable and I'm not sure it adds great value: it's on an unfocusable div element with no ARIA role. Also, the month is already visible in plain text.
  • More importantly, all the day buttons have an aria label that by default has also a text prefix "Choose":

aria-label="Choose Friday, October 2nd, 2020"

The "Choose" prefix is hardcoded and seems it's not translatable: https://github.com/Hacker0x01/react-datepicker/blob/6d789febf11630ef4080084ad4744add92a89ab8/src/day.jsx#L240-L253

This prefix can be changed via the ariaLabelPrefixWhenEnabled prop and I'd recommend to remove it by passing an empty string. It's redundant for screen reader users and a problem for speech recognition software users. However, we'd need to investigate on the aria-label in the first place because we need a way to communicate the Events, more on this later.

Other strings that seem not translatable:

I do see these can be changed via props but I'm not sure I understand how can they be translated?

One more interesting question is: does react-datepicker support RTL languages. In the react-dates codebase I can see methods to support RTL but at a first glance I can't find anything related to RTL in react-datepicker.

@afercia
Copy link
Contributor

afercia commented Sep 28, 2020

Labelling and Events

The main purpose of this change is to add "events" on the calendar days. To start with, these events would be other posts published or scheduled for that day. Screenshot:

calendar events

However, the tooltips alone are only a "visual thing". The tooltip documentation itself specifies that:

Accessibility note: the tooltip text is hidden from screen readers and assistive technologies that understand ARIA. To make it accessible, use an aria-label attribute on the same element the tooltip is applied to, preferably using the same text used for the tooltip.

It is also worth reminding that the tooltip is rendered in the DOM very far from the element it is applied to so it can't be reached (nor it should be) via keyboard navigation. Also, tooltips can't contain interactive elements (e.g. links) because they would not be available to keyboard users. A tooltip is only a visual "hint" that should be accompanied with other accessible text to convey the same information to assistive technology users.

Basically, when navigating through the days with a screen reader, there's no information whatsoever about the Events on that day that can be announced. So the point is: how do we communicate the Events information in a way that is available on the day buttons themselves?

As noted in a previous comment, the buttons use an aria-label that overrides their content:

aria-label="Choose Friday, October 2nd, 2020"

As far as I see, there's no way to change this aria-label. Only the "Choose" prefix can be changed.

There are a few options that could be used to add the Events info within the day buttons but they would need the ability to change or remove the aria-label. This would require some investigation:

  • Is there a way to change or, better, remove the aria-label?
  • Can this be reported upstream to ask for a prop to remove the aria-label?
  • If not, can we "hack" it in some way?

If the aria-label could be removed, we could just use renderDayContents() to add some visually hidden text with all the information we want to provide about the Events.

This is probably the most challenging point for the Events implementation.

@afercia
Copy link
Contributor

afercia commented Sep 28, 2020

Other issues worth mentioning (some of them are present also on the current implementation):

  • the prev/next month buttons should have an aria-label and tooltip: this can be fixed by passing a label prop with appropriate text to the buttons (the label prop will also add the tooltip)
  • when pressing the prev/next month buttons there's no audible confirmation message for screen reader users: they won't have a clue what happened
  • the prev/next month buttons contrast ratio is too low
  • not sure why the prev/next month buttons use dashicons, i thought SVG icons were the standard in Gutenberg
  • the Events tooltips are displayed only on hover: they should be displayed also on focus
  • the Events are rendered in an unordered list: this is okay but a bit pointless because the list is visually reset via CSS and the tooltip can't be announced by assistive technologies so the semantics used isn't greatly relevant
  • the day buttons contrast ratio on hover is not sufficient: color: #757575, background: #f0f0f0, contrast ratio 4.04:1
  • the selected day button has no semantic indication it's the selected one
  • when setting a date by clicking (or pressing Enter/Spacebar) on a day, there's no audible confirmation message
  • Calendar Help
    • it will need to be updated with the new keyboard shortcuts (also, the headings hierarchy is not correct)
    • it would be better to make the Calendar Help a modal dialog and also add a X close button at the top to improve the tab order
    • the keyboard shortcuts should use the same pattern that is used for the editor keyboard shortcuts, and we should make sure everything is announced correctly by screen readers
    • the usage of the <abbr> element is not correct
  • clicking "Reset" empties all the fields but the month one and the Reset button disappears: not sure if the fields should be emptied in the first place: best would be to "reset" to previous date or to now
  • after clicking "Reset", clicking or navigating via keyboard through the input fields triggers a JS error and the editor crashes this appears to happen a bit inconsistently: click randomly on the input fields and outside them multiple times to trigger the error Uncaught RangeError: Invalid time value

@sgomes
Copy link
Contributor

sgomes commented Oct 8, 2020

FYI: The increase in build size that the bot is reporting worried me at first, but I think this is just due to the fact that components has grown in size due to other changes since this PR was created. Rebasing on the main branch should once again show the bundle size going down as a result of this PR.

@retrofox
Copy link
Contributor Author

retrofox commented Oct 8, 2020

FYI: The increase in build size that the bot is reporting worried me at first, but I think this is just due to the fact that components has grown in size due to other changes since this PR was created. Rebasing on the main branch should once again show the bundle size going down as a result of this PR.

do you mean to the following?

@sgomes
Copy link
Contributor

sgomes commented Oct 8, 2020

do you mean to the following?

Yes, that's what I meant. The 101KB gzipped would have been a worryingly large increase for changes to a single component, on the order of 2.5 times the size of react + react-dom, or 1.5 times the size of the full moment with all locales.

@retrofox
Copy link
Contributor Author

retrofox commented Oct 8, 2020

do you mean to the following?

Yes, that's what I meant. The 101KB gzipped would have been a worryingly large increase for changes to a single component, on the order of 2.5 times the size of react + react-dom, or 1.5 times the size of the full moment with all locales.

Thanks. Nice, we're going to create a new PR only for the component replacement. There, we're going pay attention to this. Do you mind if I add you as a reviewer?

@sgomes
Copy link
Contributor

sgomes commented Oct 8, 2020

Do you mind if I add you as a reviewer?

Not at all, happy to take a look! 🙂

Base automatically changed from master to trunk March 1, 2021 15:44
@paaljoachim
Copy link
Contributor

paaljoachim commented Apr 1, 2021

The issue #15348 came up in a Core Editor triage held by @gwwar Kerry and myself. It looks like this PR has stopped up.
@retrofox Damian. It would be great with an update here. How can we help move this PR forward? What is holding it back?

@retrofox
Copy link
Contributor Author

retrofox commented Apr 1, 2021

The issue #15348 came up in a Core Editor triage held by @gwwar Kerry and myself.

It's nice to hear that :-)

It looks like this PR has stopped up.
@retrofox Damian. It would be great with an update here. How can we help move this PR forward? What is holding it back?

That would be very nice. However, this PR suggests a huge refactoring that will take a lot of time, time that now I'm not sure whether I'll be able to provide.
We have a related PR, smaller, ready to review. Would you mind take a look at this one before introducing us to a bigger change?

Thanks, folks.

@retrofox retrofox mentioned this pull request Apr 8, 2021
2 tasks
@ciampo
Copy link
Contributor

ciampo commented Aug 23, 2022

With #43005 merged, I believe that this PR can probably be closed.

Of course, more a11y feedback on the current status of the component is welcome!

cc @noisysocks

@ciampo ciampo closed this Aug 23, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Feature] UI Components Impacts or related to the UI component system [Focus] Accessibility (a11y) Changes that impact accessibility and need corresponding review (e.g. markup changes). Needs Accessibility Feedback Need input from accessibility [Package] Components /packages/components [Package] Editor /packages/editor [Status] In Progress Tracking issues with work in progress
Projects
None yet
7 participants