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

SearchField: Add validation props and refine states #2363

Open
wants to merge 19 commits into
base: main
Choose a base branch
from

Conversation

beaesguerra
Copy link
Member

@beaesguerra beaesguerra commented Nov 18, 2024

Summary:

To make the SearchField component more consistent with other form field components like TextField and TextArea, we add validation related props to the component. See LabeledField Implementation Spec for more details!

The changes include:

  • Add error, instantValidation, validate, onValidate props to SearchField
  • Minor tweaks
    • Hide clear icon button if the field is disabled
    • Refine magnifying glass icon styling to make it match Figma component more (smaller, bold icon, spacing, update disabled state)
  • Storybook:
    • Add error and validation stories for SearchField
    • Add variant stories for SearchField states

Issue: WB-1761

Test plan:

  • Review Storybook docs for Error and Validation stories
    • ?path=/docs/packages-searchfield--docs#error
    • ?path=/docs/packages-searchfield--docs#validation
  • Review prop documentation for SearchField (?path=/docs/packages-searchfield--docs)
  • Review new Search Field All Variants stories (?path=/docs/packages-searchfield-all-variants--docs)
  • Review Chromatic diff for styling updates (left some comments in the UI Tests!)

@beaesguerra beaesguerra self-assigned this Nov 18, 2024
Copy link

changeset-bot bot commented Nov 18, 2024

🦋 Changeset detected

Latest commit: d2a4cd5

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

This PR includes changesets to release 3 packages
Name Type
@khanacademy/wonder-blocks-search-field Minor
@khanacademy/wonder-blocks-dropdown Patch
@khanacademy/wonder-blocks-birthday-picker 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

Copy link
Contributor

github-actions bot commented Nov 18, 2024

Size Change: +85 B (+0.08%)

Total Size: 101 kB

Filename Size Change
packages/wonder-blocks-search-field/dist/es/index.js 1.39 kB +85 B (+6.52%) 🔍
ℹ️ View Unchanged
Filename Size
packages/wonder-blocks-accordion/dist/es/index.js 3.78 kB
packages/wonder-blocks-banner/dist/es/index.js 1.53 kB
packages/wonder-blocks-birthday-picker/dist/es/index.js 1.77 kB
packages/wonder-blocks-breadcrumbs/dist/es/index.js 887 B
packages/wonder-blocks-button/dist/es/index.js 4.04 kB
packages/wonder-blocks-cell/dist/es/index.js 2.01 kB
packages/wonder-blocks-clickable/dist/es/index.js 3.06 kB
packages/wonder-blocks-core/dist/es/index.js 3.44 kB
packages/wonder-blocks-data/dist/es/index.js 6.24 kB
packages/wonder-blocks-dropdown/dist/es/index.js 18.2 kB
packages/wonder-blocks-form/dist/es/index.js 6.28 kB
packages/wonder-blocks-grid/dist/es/index.js 1.36 kB
packages/wonder-blocks-i18n/dist/es/index.js 4.76 kB
packages/wonder-blocks-icon-button/dist/es/index.js 3 kB
packages/wonder-blocks-icon/dist/es/index.js 871 B
packages/wonder-blocks-labeled-field/dist/es/index.js 72 B
packages/wonder-blocks-layout/dist/es/index.js 1.82 kB
packages/wonder-blocks-link/dist/es/index.js 2.28 kB
packages/wonder-blocks-modal/dist/es/index.js 5.36 kB
packages/wonder-blocks-pill/dist/es/index.js 1.65 kB
packages/wonder-blocks-popover/dist/es/index.js 4.87 kB
packages/wonder-blocks-progress-spinner/dist/es/index.js 1.52 kB
packages/wonder-blocks-switch/dist/es/index.js 1.94 kB
packages/wonder-blocks-testing-core/dist/es/index.js 3.74 kB
packages/wonder-blocks-testing/dist/es/index.js 1.07 kB
packages/wonder-blocks-theming/dist/es/index.js 693 B
packages/wonder-blocks-timing/dist/es/index.js 1.8 kB
packages/wonder-blocks-tokens/dist/es/index.js 2.36 kB
packages/wonder-blocks-toolbar/dist/es/index.js 905 B
packages/wonder-blocks-tooltip/dist/es/index.js 7.08 kB
packages/wonder-blocks-typography/dist/es/index.js 1.23 kB

compressed-size-action

Copy link
Contributor

github-actions bot commented Nov 18, 2024

A new build was pushed to Chromatic! 🚀

https://5e1bf4b385e3fb0020b7073c-wqaepcqqyj.chromatic.com/

Chromatic results:

Metric Total
Captured snapshots 99
Tests with visual changes 15
Total stories 510
Inherited (not captured) snapshots [TurboSnap] 275
Tests on the build 374

@@ -146,7 +174,7 @@ const SearchField: React.ForwardRefExoticComponent<

// @ts-expect-error [FEI-5019] - TS2322 - Type '() => JSX.Element | null' is not assignable to type '() => ReactElement<any, string | JSXElementConstructor<any>>'.
const maybeRenderClearIconButton: () => React.ReactElement = () => {
if (!value.length) {
if (!value.length || disabled) {
Copy link
Member Author

Choose a reason for hiding this comment

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

Now that we have the Search Field Variants stories, addressed a small bug where we were showing the clear button when the field is disabled!

@@ -223,18 +255,11 @@ const styles = StyleSheet.create({
margin: 0,
position: "absolute",
right: 0,
":hover": {
Copy link
Member Author

Choose a reason for hiding this comment

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

This was causing an issue where the focus outline would not be shown if the clear button was hovered and focused. Also, the hover state of the clear button doesn't have a border so this isn't needed!

},
inputStyleReset: {
display: "flex",
flex: 1,
"::placeholder": {
Copy link
Member Author

Choose a reason for hiding this comment

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

We can rely on the styles from TextField so it is consistent!

@@ -167,8 +195,14 @@ const SearchField: React.ForwardRefExoticComponent<
<View onClick={onClick} style={[styles.inputContainer, style]}>
<PhosphorIcon
icon={magnifyingGlassIcon}
size="medium"
color={color.offBlack64}
size="small"
Copy link
Member Author

Choose a reason for hiding this comment

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

Applying some styling updates to make the search field look more like the Figma component! It also addresses the disabled and light states

Before (left) and After (right):
image

@beaesguerra beaesguerra marked this pull request as ready for review November 18, 2024 21:55
@khan-actions-bot khan-actions-bot requested a review from a team November 18, 2024 21:55
@khan-actions-bot
Copy link
Contributor

Gerald

Required Reviewers
  • @Khan/wonder-blocks for changes to .changeset/breezy-bears-teach.md, __docs__/wonder-blocks-search-field/search-field-variants.stories.tsx, __docs__/wonder-blocks-search-field/search-field.stories.tsx, packages/wonder-blocks-search-field/src/components/search-field.tsx, packages/wonder-blocks-search-field/src/components/__tests__/search-field.test.tsx

Don't want to be involved in this pull request? Comment #removeme and we won't notify you of further changes.

Copy link
Contributor

github-actions bot commented Nov 18, 2024

npm Snapshot: Published

🎉 Good news!! We've packaged up the latest commit from this PR (33b95e2) and published all packages with changesets to npm.

You can install the packages in webapp by running:

./services/static/dev/tools/deploy_wonder_blocks.js --tag="PR2363"

Packages can also be installed manually by running:

yarn add @khanacademy/wonder-blocks-<package-name>@PR2363

Copy link
Member

@jandrade jandrade left a comment

Choose a reason for hiding this comment

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

This is looking great! left a couple of nit/non-blocking suggestions before giving final approval.

padding: spacing.medium_16,
},
scenarios: {
display: "flex",
Copy link
Member

Choose a reason for hiding this comment

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

super-nit: View provides flex by default.

Copy link
Member Author

Choose a reason for hiding this comment

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

Removed! (🦸 super-nit 😄)

/>
{(errorMessage || args.error) && (
<>
<Strut size={spacing.xSmall_8} />
Copy link
Member

Choose a reason for hiding this comment

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

suggestion: I guess you could also set gap: spacing.xSmall_8 in the parent View container. This approach works well too if you want to keep it.

On a side note, I feel that Strut and Spring were created in times where we didn't have so many CSS flex and grid goodies to solve these kind of issues. The more I think, the more I'm convinced that we should recommend using gap instead of these components. What do you think about that? (not that we have to migrate existing uses, but more that we should recommend this approach from now on if it makes sense).

Copy link
Member Author

Choose a reason for hiding this comment

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

That makes sense! I wonder if it would be helpful to add a gap or space prop to View. What do you think?

Also, is it preferred we inline the aphrodite styles or create styles in a stylesheet for things like this?

<View style={{ gap: spacing.xSmall_8 }} />

or

<View style={styles.container} />
...
const styles = StyleSheet.create({
  container: {
    gap: spacing.xSmall_8,
  }
});

Is one more performant? One nice thing about inlining the styles is that if the styling gets removed, it's removed! Unlike the other way, there's a chance we forget to remove the unused style from the stylesheet! This may also change depending on our css approach, curious if anyone has thoughts on this :)

Copy link
Member

Choose a reason for hiding this comment

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

The inline approach sure reminds me of Tailwind! It puts the styles closer to their usage. One downside is the code is less portable, whereas classes can be centralized and reused.

@khan-actions-bot khan-actions-bot requested a review from a team November 20, 2024 17:40
return null;
}

return (
<IconButton
icon={xIcon}
size="xsmall"
Copy link
Member Author

Choose a reason for hiding this comment

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

I also updated the dismiss icon styling (bold icon, smaller, spacing!). Thanks for catching this @jandrade!

Since IconButton is smaller now, this addresses the issue where the focus outline on the dismiss button can be cropped out if an ancestor element has overflow: hidden (see Chromatic comment)
image

The hit area seems too small though for accessibility. I wonder if all sizes of the IconButton component should all have the same minimum hit area?

Copy link
Member

Choose a reason for hiding this comment

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

I think we should probably use size="small" instead, as it keeps the same icon size (16x16) but the hit area is slightly bigger (32 instead of 24), which would improve a11y in that regard. We'd still fail to achieve AAA, but I think it would be a good compromise for the mid-term.

And I like the suggestion about revisiting the hit areas of all IconButton variants. I think this is something worth exploring and documenting in the WB audit that we are doing for the new experience.

Copy link
Member Author

Choose a reason for hiding this comment

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

size="small" for IconButton uses a 24x24 icon, which is different from size="small" for PhosphorIcon! I'll update this to size="small" and have the icon be a bit bigger so it is more usable!

Copy link
Member Author

@beaesguerra beaesguerra Nov 20, 2024

Choose a reason for hiding this comment

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

I'll also update it back to the regular icon weight, I think when it's bold and 24x24, the dismiss icon is too prominent!
image image

Update: I've updated this!

Copy link
Member

Choose a reason for hiding this comment

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

Thanks for trying this out. The last iteration makes sense to me.

For context, I got a big confused as I saw that the designs apparently used an icon of 24x24 but in reality the icon was 16x16

Screenshot 2024-11-20 at 2 48 50 PM

https://www.figma.com/design/VbVu3h2BpBhH80niq101MHHE/%F0%9F%92%A0-Main-Components?node-id=13843-9211&t=nNY8Jl9Ah253UTqj-4

Copy link
Member Author

Choose a reason for hiding this comment

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

Ahh yes that is confusing! I added a note in WB-1792 to document tips for developers around icons once we work with design to make the translation easier!

I also updated the audit spreadsheet to include notes about the IconButton hit area and IconButton/PhosphorIcon size consistency!

…e regular icon again so the bold icon isn't too prominent
Copy link
Member

@jandrade jandrade left a comment

Choose a reason for hiding this comment

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

Looks awesome! thanks for adding these changes and for getting more consistency across our form fields 👏 🚀

Copy link
Member

@marcysutton marcysutton left a comment

Choose a reason for hiding this comment

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

This seems like a really great change, nice work @beaesguerra!

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.

4 participants