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

[i18n] support user defined component #5236

Closed
wants to merge 63 commits into from
Closed

[i18n] support user defined component #5236

wants to merge 63 commits into from

Conversation

ym
Copy link
Contributor

@ym ym commented Oct 4, 2021

Summary

We noticed that Chrome's built-in translation feature will break any page with EuiTable.

After investigation, I found that it's caused by the <Fragment> component used by EuiI18n and React or Chrome Trasnlate can't work together when we're using <Fragment> rather than a real DOM component here.

I see i18next has the option to use a different component and we can use the same approach in Eui to make a workaround. That's what the PR is for.

Reference:

[1] i18next/react-i18next#1254
[2] facebook/react#17256

Checklist

  • Check against all themes for compatibility in both light and dark modes
  • Checked in mobile
  • Checked in Chrome, Safari, Edge, and Firefox
  • Props have proper autodocs and playground toggles
  • Added documentation
  • Checked Code Sandbox works for any docs examples
  • Added or updated jest tests
  • Checked for breaking changes and labeled appropriately
  • Checked for accessibility including keyboard-only and screenreader modes
  • A changelog entry exists and is marked appropriately

@kibanamachine
Copy link

Since this is a community submitted pull request, a Jenkins build has not been kicked off automatically. Can an Elastic organization member please verify the contents of this patch and then kick off a build manually?

@cla-checker-service
Copy link

cla-checker-service bot commented Oct 4, 2021

💚 CLA has been signed

@thompsongl
Copy link
Contributor

👋 Thanks, @ym!
If you haven't already, please sign the CLA and comment here if/when done.

@ym
Copy link
Contributor Author

ym commented Oct 4, 2021

👋 Thanks, @ym! If you haven't already, please sign the CLA and comment here if/when done.

Just signed :-)

@thompsongl
Copy link
Contributor

jenkins test this

@kibanamachine
Copy link

Preview documentation changes for this PR: https://eui.elastic.co/pr_5236/

Copy link
Contributor

@thompsongl thompsongl left a comment

Choose a reason for hiding this comment

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

Makes sense and looks good!
Only change I'd like to see is a name change. We typically name custom render functions render, so let's use that name across the board here

+ render
- componentRenderFunc

@cchaos
Copy link
Contributor

cchaos commented Oct 5, 2021

Let's also make sure we add a docs example under https://elastic.github.io/eui/#/utilities/i18n

Copy link
Contributor

@cee-chen cee-chen left a comment

Choose a reason for hiding this comment

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

Some small nit type comments, definitely not a blocker. Thanks for the contribution! ++ to Caroline's comments that it'd be great to see a documentation section for this with an example use case / usage. Let us know if that's something we can help with.

src/components/i18n/i18n.tsx Outdated Show resolved Hide resolved
src/components/i18n/i18n.tsx Outdated Show resolved Hide resolved
src/components/i18n/i18n.test.tsx Outdated Show resolved Hide resolved
@ym ym force-pushed the master branch 3 times, most recently from 72515ad to 49d238e Compare October 5, 2021 19:27
@ym
Copy link
Contributor Author

ym commented Oct 5, 2021

Let's also make sure we add a docs example under https://elastic.github.io/eui/#/utilities/i18n

I've just added an example, please check and let me know if there's anything that needs to be improved.

@thompsongl
Copy link
Contributor

jenkins test this

@kibanamachine
Copy link

Preview documentation changes for this PR: https://eui.elastic.co/pr_5236/

src-docs/src/views/i18n/context.js Outdated Show resolved Hide resolved
src-docs/src/views/i18n/context.js Outdated Show resolved Hide resolved
@@ -26,6 +26,7 @@ export interface I18nShape {
[key: string]: Renderable<object>;
};
mappingFunc?: (value: string) => string;
render?: (children: any[]) => FunctionComponent<any>;
Copy link
Contributor

@cee-chen cee-chen Oct 5, 2021

Choose a reason for hiding this comment

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

I think we should document this fn here is a props docblock at the very minimum (or we could add an entire section to the src-docs view, but I tend to bias towards props docs myself).

Suggested change
render?: (children: any[]) => FunctionComponent<any>;
/**
* Some i18n frameworks don't work with a rendered `<Fragment>`.
* The `render` function allows you to pass in another wrapping node instead, e.g. `<div>`
*/
render?: (children: any[]) => FunctionComponent<any>;

The above is based on my understanding of this feature/PR, feel free to correct me if I'm wrong!

Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
render?: (children: any[]) => FunctionComponent<any>;
render?: (children: any) => FunctionComponent;

Copy link
Contributor

@cee-chen cee-chen Oct 7, 2021

Choose a reason for hiding this comment

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

@ym Heads up, it looks like most of Greg's Typescript suggestions need to be addressed still

Copy link
Contributor

@thompsongl thompsongl left a comment

Choose a reason for hiding this comment

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

I didn't fully understand the problem yesterday, so apologies for the double review.

See inline comments, but we'll need to make some changes to get this working and understandable. I think adding a new docs section is the right approach.

CHANGELOG.md Outdated
@@ -3,6 +3,8 @@
- Added `maxWidth` prop to `EuiTour`, made `subtitle` optional, and fixed heading levels and footer background ([#5225](https://github.com/elastic/eui/pull/5225))
- Updated `tint`, `shade`, `saturate`, `desaturate`, and `makeHighContrastColor` utility functions to maintain color format supplied ([#5230](https://github.com/elastic/eui/pull/5230))
- Converted generated icon files to Typescript, eliminating the last `.js` files in our source files ([#5212](https://github.com/elastic/eui/pull/5212))
- Added `render` prop to `EuiI18n` ([#5236](https://github.com/elastic/eui/pull/5236))
Copy link
Contributor

Choose a reason for hiding this comment

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

We had a release yesterday so this is now in the wrong section. Merge/rebase master and update


const i18n = {
mapping: mappings[language],
formatNumber: (value) => new Intl.NumberFormat(language).format(value),
render: useDiv
? () => (children) => <div style={{ display: 'inline' }}>{children}</div>
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
? () => (children) => <div style={{ display: 'inline' }}>{children}</div>
? (children) => () => <div style={{ display: 'inline' }}>{children}</div>

Based on the types, this is how it'd work

@@ -26,6 +26,7 @@ export interface I18nShape {
[key: string]: Renderable<object>;
};
mappingFunc?: (value: string) => string;
render?: (children: any[]) => FunctionComponent<any>;
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
render?: (children: any[]) => FunctionComponent<any>;
render?: (children: any) => FunctionComponent;

valueDefault: DEFAULT;
i18nMappingFunc?: (token: string) => string;
values?: I18nTokenShape<T, DEFAULT>['values'];
render?: (children: any[]) => FunctionComponent<any>;
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
render?: (children: any[]) => FunctionComponent<any>;
render?: I18nShape['render'];

src-docs/src/views/i18n/context.js Outdated Show resolved Hide resolved
@thompsongl
Copy link
Contributor

jenkins test this

1 similar comment
@thompsongl
Copy link
Contributor

jenkins test this

@kibanamachine
Copy link

Preview documentation changes for this PR: https://eui.elastic.co/pr_5236/

Copy link
Contributor

@cee-chen cee-chen left a comment

Choose a reason for hiding this comment

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

A few more small comments from me, I think we're really close! Thanks for your patience and the many iterations. As a heads up also we'll be OOO tomorrow, but I think this can get merged next week once remaining feedback is addressed :)

} from '../../../../src/components';

const mappings = {
fr: {
'euiContext.english': 'Anglais',
'euiContext.french': 'Française',
'euiContext.greeting': 'Salutations!',
'euiContext.greeting': 'Salutations, {name}!',
Copy link
Contributor

Choose a reason for hiding this comment

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

It looks like this isn't quite working as expected:

vXHyPxt1Q4

Should we just leave this as-is without the {name}?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

render prop will be only called in component interpolation so I guess we have to keep {name} part.

src-docs/src/views/i18n/context.js Outdated Show resolved Hide resolved
@@ -26,6 +26,7 @@ export interface I18nShape {
[key: string]: Renderable<object>;
};
mappingFunc?: (value: string) => string;
render?: (children: any[]) => FunctionComponent<any>;
Copy link
Contributor

@cee-chen cee-chen Oct 7, 2021

Choose a reason for hiding this comment

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

@ym Heads up, it looks like most of Greg's Typescript suggestions need to be addressed still

@thompsongl
Copy link
Contributor

jenkins test this

@kibanamachine
Copy link

Preview documentation changes for this PR: https://eui.elastic.co/pr_5236/

1Copenut and others added 26 commits October 29, 2021 10:24
…ic#5229)

* Making an explicit check for ID prop in EUI Combobox

* Checking for a user-passed ID prop
* If no user-passed ID, we'll use the `rootId()` class method to set one
* Prepend and append props need an ID to relate label to the input

* Adding example for Combobox with prepended label
* Confirmed the label `for` attribute is referencing input `id`
* Added styles to round the edges of the child `<div>` when we prepend a
  label
* Bumped package.json

* Adding CHANGELOG entry and bumping version

* Update combo_box.tsx

* Updating styles to match other forms with prepend and apppend.

* Finishing Combobox CSS and test updates
* Simplified the Amsterdam overrides for prepended / appended labels
* Added conditional classes to `combo_box.tsx`
* Added unit tests for user passed ID, prepended and appended classes

* Reordering props in child component.

* Final adjustment to ID check in ComboBox

* Final updates to styling and documentation
* Added CSS rules for compressed, prepend and append border radius
* Updated the Display Toggles to include append
* Removed a duplicated instruction paragraph
* Simplified the logic for a unique ID in combobox.ts

* Adding Combobox unique ID to master changelog

* Updated Form Control Layout SCSS
* The borders were still rounded with prepend and append enabled
* Added two more rules to make borders square for full height and compressed

* Move to _combo_box.scss

Co-authored-by: cchaos <caroline.horn@elastic.co>
* Install Cypress code coverage dependencies

* Set up required babel+istanbul config

* Set up Cypress code coverage config

@see https://github.com/cypress-io/code-coverage#instrument-unit-tests

* Add script for combining cypress & jest code coverage
-into a single json & html report

* Misc cleanup/ignores

- Ignore new `.nyc_output` dir generated by cypress/istanbul

- Improve Jest config collectCoverageFrom !ignores:
  - DRY out component+services folder patterns with a {,} glob
  - Ignore new Cypress .spec files and .testenv files for jest coverage

- eslintignore the cypress folder, since they're all .js anyway and it has a decent amount of idiosyncracies
+ cleanup unused eslint-disable
+ cleanup cypress comment boilerplate
+ remove unused paths from webpack config

* Add wiki documentation

* [PR feedback] Move nyc config to own file

* [PR feedback] Switch combine coverage script to .sh
…c#5272)

* Add remark-breaks and line break plugin to MarkdownEditor

* Update changelog
elastic#5283)

* Moved Border tokens to its own page
* Figured out a way to get subsections in the sidenav working
* Added the new `_values` under `customizing/`

* [EuiTableRowCell] Actually support `valign` property manually
* [EuiTable*] Fixing some props and mobile options
* Slightly better responsive table styles
* omit unsupported types

* resolve console errors

* CL
…failures (elastic#5317)

* Add Cypress failed test retries to CI run mode

* Increase cy.wait on flaky context menu tests (just in case)

* More hardening
* use useJsonVars

* use variable
* Added Typography page
* Deleting all old Sass typography
…unt values (elastic#5313)

* Allow the datagrid to expand&contract in response to different row counts, when no pagination is present

* changelog
… theme (elastic#5320)

* Fix large density not increasing in fontSize on Amsterdam theme

* Add changelog entry

* Switch to Amsterdam override
…to` (elastic#5281)

* Remove isHeightSame check

* Remove same height check from shouldComponentUpdate

- if we're not checking for sameHeight in componentDidUpdate, we also likely don't need this anymore, and all dynamic user changes appear to work without this code

* [Proposed refactors]

- Rename `recalculateRowHeight` to `setAutoRowHeight`

- DRY out setAutoRowHeight to be reusable by both the resize observer and during props update (NB: This leads to some repetition with the height being obtained twice, but will not be an issue shortly as I'll be refactoring/removing the cell wrapper observer in a future PR)

- Refactor rowHeightUtils.isAutoHeight to accept an undefined rowHeightsOptions

* Improve unit tests

* Add changelog entry

* [PR feedback] Fix `isAutoHeight` false positive
- occurs if the `defaultHeight` is auto but a specific `rowHeights` line override is not auto

TODO: Write a unit test for this in the future

* [PR feedback/Discover testing] Trigger component update when rowHeightsOptions changes

* [cleanup] Remove now-unused compareHeights util

+ clean up mock rowHeightUtils as well

* [revert] rename setAutoRowHeight back to recalculateRowHeight

- lineCount in elastic#5284 will shortly be using the row height cache in addition to auto, so I'm making the fn name less specific again

* Add enqueue/timeout to recalculateRowHeight updates

- to avoid race conditions with cache being cleared

* Remove clearHeightsCache completely

* Unset row+column height values on unmount (elastic#3)

* Add unit test for new unsetRowHeight

+ add optional isAutoHeight check

* Remove hidden columns from row height cache

* Early return in getRowHeight

Co-authored-by: Chandler Prall <chandler.prall@gmail.com>
* add euiautosizer

* use euiautosizer

* use euiautosizer testenv mock

* CL

* docs

* props table

* simplify wrapper

* add data-eui attr to testenv mock
* Added Sizing page
* Add subsections and use new _values
* Deleting all old Sass typography
* Added callout in Sass page and easier customization of ValuesTable columns
* Cleanup including adding `valign` as a top level configuration
@thompsongl
Copy link
Contributor

My PR idea didn't work. It was my fault so I've opened a new PR with a clean git state: #5337

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.