Skip to content

React Image Integration#3911

Closed
ironman5366 wants to merge 12 commits intomasterfrom
will-js-image-tag
Closed

React Image Integration#3911
ironman5366 wants to merge 12 commits intomasterfrom
will-js-image-tag

Conversation

@ironman5366
Copy link
Contributor

No description provided.

aduth and others added 6 commits July 13, 2020 08:25
**Why**: As a login.gov developer, I want to be able to test React functionality, and for those tests to be integrated with the existing Mocha test framework.
**Why**: As a user, I want pages that I'm viewing to be localized to my language, including those page which use React.
Leftover from earlier iterations
@ironman5366 ironman5366 requested a review from aduth July 13, 2020 16:23
@ironman5366 ironman5366 marked this pull request as ready for review July 13, 2020 16:38
}

<% image_keys.each do |key| %>
window.LoginGov.AssetStrings.images['<%=key %>'] = '<%= ActionController::Base.helpers.image_path(key) %>';
Copy link
Contributor

Choose a reason for hiding this comment

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

As used in i18n-strings.js.erb, the j helper is an alias for escape_javascript, which may be important to help escape potentially unexpected / conflicting characters (e.g. early terminating single quote ' or </script>, etc).

return 'Document Capture';
const t = useI18n();
const imageTag = useImage();
return <img src={imageTag('idv/phone.png')} alt={t('doc_auth.headings.welcome')} />;
Copy link
Contributor

Choose a reason for hiding this comment

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

If the idea is to have this correspond to an equivalent Rails helper method, and since image_tag in Rails would generate the full markup for the image, should we consider to refer to this as imagePath, since it's intended to correspond to image_path (return the src value)?

Copy link
Contributor

Choose a reason for hiding this comment

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

I also wonder if, rather than making separate helpers for each type of asset, it would be possible to create one generic helper which can return the path for any asset, regardless of type.

Considering asset_path as an alternative to image_path, where the usage could be something like:

const getAssetPath = useAssets();
const src = getAssetPath('images/idv/phone.png');


function useI18n() {
const strings = useContext(I18nContext);
const t = (key) => (Object.prototype.hasOwnProperty.call(strings, key) ? strings[key] : key); // eslint-disable-line
Copy link
Contributor

Choose a reason for hiding this comment

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

What was the reason for disabling ESLint for this line?

import AssetContext from '../app/document-capture/context/assets';
import I18nContext from '../app/document-capture/context/i18n';

const { I18n: i18n, AssetStrings } = window.LoginGov;
Copy link
Contributor

Choose a reason for hiding this comment

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

This relates to a review comment at #3909 (review) which I'll need to respond to, but the idea with renaming LoginGov.I18n to i18n was to adhere to camel-case conventions with lowercase first letter. The same could apply to AssetStrings.

But it depends on how we'd want to approach the naming convention, since there is some precedent in the broader ecosystem for naming fixed enumerated sets of values in this way as PascalCase (for example, see Google style guide or TypeScript enum documentation).

//= link application.css

//= link i18n-strings.js
//= link asset-strings.js
Copy link
Contributor

Choose a reason for hiding this comment

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

Did it turn out that this is necessary?

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, I believe it is

Co-authored-by: Andrew Duthie <andrew.duthie@gsa.gov>
Comment on lines +1 to +12
window.LoginGov = window.LoginGov || {}
<% image_keys = [
'idv/phone.png'
] %>

window.LoginGov.AssetStrings = {
images: {}
};

<% image_keys.each do |key| %>
window.LoginGov.AssetStrings.images['<%=key %>'] = '<%= ActionController::Base.helpers.image_path(key) %>';
<% end %>
Copy link
Contributor

Choose a reason for hiding this comment

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

Based on our previous conversation, I think we should be able to make this less opinionated about the particular kinds of assets, instead creating a single object which can contain any of the paths we might want in the client:

Suggested change
window.LoginGov = window.LoginGov || {}
<% image_keys = [
'idv/phone.png'
] %>
window.LoginGov.AssetStrings = {
images: {}
};
<% image_keys.each do |key| %>
window.LoginGov.AssetStrings.images['<%=key %>'] = '<%= ActionController::Base.helpers.image_path(key) %>';
<% end %>
window.LoginGov = window.LoginGov || {};
window.LoginGov.AssetStrings = {};
<% keys = [
'idv/phone.png'
] %>
<% keys.each do |key| %>
window.LoginGov.AssetStrings['<%= ActionController::Base.helpers.j key %>'] = '<%= ActionController::Base.helpers.j ActionController::Base.helpers.asset_path key %>';
<% end %>

In my testing, this creates an object mapping the original path to the one including the digest:

image

return imageTag;
}

export { useImage };
Copy link
Contributor

Choose a reason for hiding this comment

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

In separate work I came across the need to recreate an existing shared view element in React (the accordion), and it occurred to me that it would be a nice abstraction to be able to use an image as a regular <img> HTML tag, in a way that the application would substitute the digest-modified path automatically. I was considering this a new Image component.

Example usage:

<Image
  src="plus.svg"
  alt={ t('image_description.accordian_plus_buttom') }
  width={ 16 }
  className="plus-icon display-none"
/>

Recreating this:

= image_tag asset_url('plus.svg'), alt: t('image_description.accordian_plus_buttom'),
width: 16, class: 'plus-icon display-none'

Repurposing src as a reference to an asset path might be a bit too magical, so naming it something like assetPath could be more appropriate.

As far as it relates here, I still think we'll need the asset context, but I'm not yet sure about these hooks. It seems like if we had an Image component abstraction, it wouldn't be too much a regular bother to reference the context using useContext, without any intermediary useAsset or useImage hooks.

@ironman5366
Copy link
Contributor Author

Duplicated by #3931

@amathews-fs amathews-fs deleted the will-js-image-tag branch January 7, 2021 19:39
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