Skip to content

feat(#280): adds icon component with material desing icons #384

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

Merged
merged 12 commits into from
Apr 28, 2025

Conversation

latin-panda
Copy link
Collaborator

@latin-panda latin-panda commented Apr 25, 2025

Closes #280

I have verified this PR works in these browsers (latest versions):

  • Chrome
  • Firefox
  • Safari (macOS)
  • Safari (iOS)
  • Chrome for Android
  • Not applicable

What else has been done to verify that this works as intended?

I verified the bundle, and I confirm that the tree-shaking is working:

  • Including only imported icons
  • Not increasing bundle size - just minimal.

Test evidence:

Web Form Preview Page preview-page-desktop-1 preview-page-desktop-2 preview-page-desktop-3 preview-page-mobile-1 preview-page-mobile-2
Rank rank-1 rank-2
Multiselect (check icon) multiselect
Image upload image-upload-1 image-upload-2 image-upload-3
Geopoint geopoint-1 geopoint-2 geopoint-3 geopoint-4 geopoint-5
Form header form-header-icons-1 form-header-icons-2 form-header-icons-3 form-header-icons-4

Why is this the best possible solution? Were any other approaches considered?

  • Easy to add new icons to the project, just import them and add them to the map.
  • Easy to use. Minimalistic component.
  • It has baked-in tree-shaking
  • Wide variety of icons
  • Well-supported library by opensource community

How does this change affect users? Describe intentional changes to behavior and behavior that could have accidentally been affected by code changes. In other words, what are the regression risks?

User won't notice significant changes

Do we need any specific form for testing your changes? If so, please attach one.

No

What's changed

  • Removes icomoon
  • Adds new dependency with Material Design icons @mdi/js
  • Adds a new icon component that imports Material Design icons, has variants, and sizes.
    • Our lint requires a two-word name for components. That's why the name is IconSVG
  • Replace all icons with the new component

Copy link

changeset-bot bot commented Apr 25, 2025

🦋 Changeset detected

Latest commit: 83df5cd

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@getodk/web-forms Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@@ -25,8 +25,11 @@
--odk-primary-lighter-background-color: var(--p-primary-50);
--odk-primary-border-color: var(--p-primary-500);

--odk-error-text-color: var(--p-message-error-color);
--odk-error-background-color: var(--p-message-error-background);
--odk-error-text-color: var(--p-red-600);
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I realized that --p-message-error-background is not always available if the message component is unused. Better use the base color variable from PrimeVue

@@ -38,8 +41,6 @@

--odk-border-color: var(--p-surface-300);

--odk-icon-size: 1.5rem;
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This is unlikely to be customized in theming. The primary reason for removing it and letting the IconSVG component handle it is that the SVG's path, which contains the image, is resized using CSS transform.

</Button>
<Menu id="overlay_menu" ref="menu" :model="items" :popup="true">
<template #item="{ item }">
<a class="p-menu-item-link" v-if="item.command != null" @click="(event) => item.command?.({ originalEvent: event, item })">
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

TypeScript static check doesn't understand that the item.command is already validated in the v-if="item.command != null" 🤦🏽‍♀️ That's why the optional chaining operator

Copy link
Member

Choose a reason for hiding this comment

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

Looks like vuejs/vetur#1212?

Maybe ! instead of ? is slightly more explicit since you know it isn't null at that point but not a big deal.

Copy link
Member

Choose a reason for hiding this comment

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

There's also a lint warning here.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Interesting, the ! didn't fix the TypeScript static check and requires a bit more to make it work. Ultimately, I'm checking item.command is defined before calling it.

I've fixed the GH's lint warning.

@@ -75,18 +76,7 @@ watchEffect(() => {
:disabled="isDisabled"
@click="triggerInputField(takePictureInput)"
>
<svg
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Red is the new black 😌

Comment on lines +90 to +91
content: '\2713';
font-family: system-ui;
Copy link
Collaborator Author

@latin-panda latin-panda Apr 25, 2025

Choose a reason for hiding this comment

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

This seems close enough to the check mark from Material Icon. It wasn't worth the effort to customize this component to use Material Icons (for now).

It's a safe well supported font, I tested this font in chrome, firefox, safari

} from '@mdi/js';

// Find icons here: https://pictogrammers.com/library/mdi/
const iconMap: Record<string, string> = {
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

We don't have that many icons. If it grows a lot eventually, we will extract it to a file; for now, it's good to have it in one place.

@latin-panda
Copy link
Collaborator Author

@lognaturel @alyblenkin I need to do another pass of testing, but you can start reviewing.

Please find the screenshots in this section from the PR's description:

Screenshot 2025-04-24 at 9 32 11 PM

Copy link
Member

@lognaturel lognaturel left a comment

Choose a reason for hiding this comment

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

Couple of small questions in line!


By following the steps above, you should minimize the diff. However, in the JSON file, you may still see changes for properties like `id`, `iconIdx`, `setId`, and `setIdx`.
- Import the icon from `@mdi/js` in the `Icon` component.
Copy link
Member

Choose a reason for hiding this comment

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

IconSVG?

</Button>
<Menu id="overlay_menu" ref="menu" :model="items" :popup="true">
<template #item="{ item }">
<a class="p-menu-item-link" v-if="item.command != null" @click="(event) => item.command?.({ originalEvent: event, item })">
Copy link
Member

Choose a reason for hiding this comment

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

There's also a lint warning here.

@alyblenkin
Copy link
Collaborator

Looking good! The comments below are small and not a deal breaker.

Screenshot 2025-04-25 at 3 50 27 PM

  • On the WF preview page in file upload section, the file icon looks like a different colour.
  • I also think the file without the lines is a bit less distracting.
  • I'm not sure why the upload and preview icon look so large in comparison to the rest. I know they are 1.5rem/24px, but they look too big on this page. Maybe the preview eye could use the outline?
  • I'm tempted to do 22px for all the icons because I know we tried 20 and it was too small.

Screenshot 2025-04-25 at 3 48 15 PM

  • I also noticed today that there is some inconsistency between the spacing of the icons and the text within the button. I could add another issue for this if that's helpful?

@latin-panda
Copy link
Collaborator Author

@alyblenkin @lognaturel I’ve addressed the feedback:

  • Updated documentation to reference IconSVG instead of Icon.
  • Resolved lint warning.
  • Changed the icon color for the document icon and replaced it with a lineless icon (initially searched for "document" but used "file" to find the lineless version).
  • Resized icons to 20px. Calendar is now bigger, matching 20px.
  • Centered icons within their containers, which may result in varying distances from the text.
Screenshots Screenshot 2025-04-28 at 1 01 19 PM Screenshot 2025-04-28 at 1 01 04 PM Screenshot 2025-04-28 at 1 00 53 PM Screenshot 2025-04-28 at 12 48 28 PM Screenshot 2025-04-28 at 12 47 35 PM Screenshot 2025-04-28 at 12 47 31 PM Screenshot 2025-04-28 at 12 33 02 PM Screenshot 2025-04-28 at 12 32 50 PM Screenshot 2025-04-28 at 12 32 43 PM Screenshot 2025-04-28 at 12 32 36 PM

@latin-panda latin-panda requested a review from lognaturel April 28, 2025 19:22
@latin-panda latin-panda merged commit ea9674c into main Apr 28, 2025
81 of 85 checks passed
@latin-panda latin-panda deleted the material-icons branch April 28, 2025 19:58
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.

Add all material icons
3 participants