Skip to content

Commit

Permalink
[PLAY-1454] Form pills 2 of 5: add icon prop (#3540)
Browse files Browse the repository at this point in the history
**What does this PR do?** A clear and concise description with your
runway ticket url.
[PLAY-1454](https://runway.powerhrg.com/backlog_items/PLAY-1454) is part
2 of 5 in the Form Pill/Typeahead
[handoff](https://www.figma.com/file/79KJo0Jl8HSNOBQPJo5MSp/Typeahead-Dropdowns?type=design&node-id=240%3A7600&mode=design&t=f7VGtBFjzitLydyF-1).
Before altering the form pill size, we needed to allow for the use of
icons within the form pill because so much of the pill anatomy, sizing,
and future plans for usage depended on this ability. Note: icons are the
default text color for now because PLAY-1138 is not merged yet; once
that is in the icon color prop should be used.

The doc examples will look a little funky until the sizing has been
corrected - I do wonder if these should be enabled but not yet displayed
(commented out in `example.yml` until PLAY-1439 Form Pill 3 of 5 sizes +
color prop for icon functional). **Update: these have been commented
out, to be put back in with icon color added once sizing ticket
completed**

I've also done an audit of rails vs react form pill permutations in
terms of what combinations of one/some/all prop use are available. This
PR standardizes the behavior between the Rails and React versions of the
kit to the following (see second set of screenshots to demonstrate this
in rails/react as well):

| Props Used | Works or Not |
| ----------- | -------------- |
| Avatar         | Works              |
| Text             | Works              |
| Icon | No (blank FP only X to close out will be displayed) |
| Avatar and Icon | technically Works but not in handoff so not
documented yet|
| Icon and Text | Works  (see doc example screenshots below) |
| Avatar and Text | No (avatar will override text and be only thing
displayed) |
| Avatar Icon and Text | No (avatar + icon will override text, only
avatar and icon displayed) |

**Screenshots:** Screenshots to visualize your addition/change
2 Screenshots below are Rails/React Form Pill Icon doc example -> will
be commented out so as not to display on PB website yet, see above for
rationale
<img width="481" alt="rails doc example for PR"
src="https://github.com/user-attachments/assets/9868ea05-5394-439d-9ad0-dc2f331ede30">
<img width="494" alt="react doc example for PR"
src="https://github.com/user-attachments/assets/bce80fa5-c6b4-49fc-9164-ce25214c72d2">
2 Screenshots below are Rails/React Form Pill all prop permutations (aka
visual interpretation of table above)
<img width="539" alt="rails all permutations"
src="https://github.com/user-attachments/assets/507bb455-b2ea-436b-9e08-f861cc445e96">
<img width="566" alt="react all permutations"
src="https://github.com/user-attachments/assets/8f4e223d-703b-416c-a051-3f7248e541f2">


**How to test?** Steps to confirm the desired behavior:
1. Go to [playbook review
environment](https://pr3540.playbook.beta.gm.powerapp.cloud/).
2. Go to [form pill kit
page](https://pr3540.playbook.beta.gm.powerapp.cloud/kits/form_pill) in
rails and react - see [form pill icon doc
example](https://pr3540.playbook.beta.gm.powerapp.cloud/kits/form_pill/#form-pill-icon).
3. Go to kit pages for
[typeahead](https://pr3540.playbook.beta.gm.powerapp.cloud/kits/typeahead)
and
[multilevelselect](https://pr3540.playbook.beta.gm.powerapp.cloud/kits/multi_level_select)
and confirm form pill behavior within these kits is unchanged.


#### Checklist:
- [x] **LABELS** Add a label: `enhancement`, `bug`, `improvement`, `new
kit`, `deprecated`, or `breaking`. See [Changelog &
Labels](https://github.com/powerhome/playbook/wiki/Changelog-&-Labels)
for details.
- [x] **DEPLOY** I have added the `milano` label to show I'm ready for a
review.
- [x] **TESTS** I have added test coverage to my code.
  • Loading branch information
ElisaShapiro authored Jul 25, 2024
1 parent 8aaf000 commit 735f1d0
Show file tree
Hide file tree
Showing 10 changed files with 118 additions and 29 deletions.
4 changes: 4 additions & 0 deletions playbook/app/pb_kits/playbook/pb_form_pill/_form_pill.scss
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,10 @@ $form_pill_colors: (
outline: $primary solid 2px;
outline-offset: -1px;
}
.pb_form_pill_icon {
height: 12px !important;
width: 12px !important;
}
&.small {
height: fit-content;
height: -moz-fit-content;
Expand Down
11 changes: 11 additions & 0 deletions playbook/app/pb_kits/playbook/pb_form_pill/_form_pill.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,15 @@ test('displays size variant', () => {
)
const kit = screen.getByTestId('formpill')
expect(kit).toHaveClass(`pb_form_pill_kit_primary small none`)
});

test('displays icon', () => {
render(
<FormPill
data={{ testid: testId }}
icon={"test"}
/>
)
const kit = screen.getByTestId('formpill')
expect(kit).toHaveClass(`pb_form_pill_kit_primary_icon none`)
});
69 changes: 52 additions & 17 deletions playbook/app/pb_kits/playbook/pb_form_pill/_form_pill.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ type FormPillProps = {
color?: "primary" | "neutral",
data?: {[key: string]: string},
tabIndex?: number,
icon?: string,
closeProps?: {
onClick?: React.MouseEventHandler<HTMLSpanElement>,
onMouseDown?: React.MouseEventHandler<HTMLSpanElement>,
Expand All @@ -42,9 +43,12 @@ const FormPill = (props: FormPillProps): React.ReactElement => {
color = "primary",
data = {},
tabIndex,
icon = "",
} = props

const iconClass = icon ? "_icon" : ""
const css = classnames(
`pb_form_pill_kit_${color}`,
`pb_form_pill_kit_${color}${iconClass}`,
globalProps(props),
className,
size === 'small' ? 'small' : null,
Expand All @@ -61,29 +65,60 @@ const FormPill = (props: FormPillProps): React.ReactElement => {
{...dataProps}
{...htmlProps}
>
{name &&
{((name && !icon && !text) || (name && !icon && text)) && (
<>
<Avatar
imageUrl={avatarUrl}
name={name}
size="xs"
status={null}
/>
<Title
className="pb_form_pill_text"
size={4}
text={name}
/>
<Avatar
imageUrl={avatarUrl}
name={name}
size="xs"
status={null}
/>
<Title
className="pb_form_pill_text"
size={4}
text={name}
/>
</>
}

{text &&
)}
{((name && icon && !text) || (name && icon && text)) && (
<>
<Avatar
imageUrl={avatarUrl}
name={name}
size="xs"
status={null}
/>
<Title
className="pb_form_pill_text"
size={4}
text={name}
/>
<Icon
className="pb_form_pill_icon"
icon={icon}
/>
</>
)}
{(!name && icon && text) && (
<>
<Icon
className="pb_form_pill_icon"
icon={icon}
/>
<Title
className="pb_form_pill_tag"
size={4}
text={text}
/>
</>
)}
{(!name && !icon && text) && (
<Title
className="pb_form_pill_tag"
size={4}
text={text}
/>
}
)}
<div
className="pb_form_pill_close"
onClick={onClick}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<%= pb_rails("form_pill", props: {
icon: "badge-check",
text: "icon and tag",
tabindex: 0,
}) %>
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import React from 'react'
import FormPill from '../_form_pill'

const FormPillIcon = (props) => {
return (
<div>
<FormPill
icon="badge-check"
onClick={() => {
alert('Click!')
}}
tabIndex={0}
text="icon and tag"
{...props}
/>
</div>
)
}
export default FormPillIcon
3 changes: 2 additions & 1 deletion playbook/app/pb_kits/playbook/pb_form_pill/docs/example.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@ examples:
- form_pill_size: Form Pill Size
- form_pill_tag: Form Pill Tag
- form_pill_example: Example

# - form_pill_icon: Form Pill Icon

react:
- form_pill_user: Form Pill User
- form_pill_size: Form Pill Size
- form_pill_tag: Form Pill Tag
- form_pill_example: Example
# - form_pill_icon: Form Pill Icon
2 changes: 1 addition & 1 deletion playbook/app/pb_kits/playbook/pb_form_pill/docs/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ export { default as FormPillUser } from './_form_pill_user.jsx'
export { default as FormPillSize } from './_form_pill_size.jsx'
export { default as FormPillTag } from './_form_pill_tag.jsx'
export { default as FormPillExample } from './_form_pill_example.jsx'

export { default as FormPillIcon } from './_form_pill_icon.jsx'
25 changes: 16 additions & 9 deletions playbook/app/pb_kits/playbook/pb_form_pill/form_pill.html.erb
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
<%= content_tag(:div, id: object.id, data: object.data, class: object.classname + object.size_class, tabindex: object.tabindex, **combined_html_options) do %>
<% if object.name.present? %>
<%= pb_rails("avatar", props: { name: object.name, image_url: object.avatar_url, size: "xs" }) %>
<%= pb_rails("title", props: { text: object.name, size: 4, classname: "pb_form_pill_text" }) %>
<% elsif object.text.present? %>
<%= pb_rails("title", props: { text: object.text, size: 4, classname: "pb_form_pill_tag" }) %>
<% end %>

<%= pb_rails("body", props: { classname: "pb_form_pill_close" }) do %>
<%= pb_rails("icon", props: { icon: 'times' , fixed_width: true }) %>
<% end %>
<% end %>
<%= pb_rails("title", props: { text: object.name, size: 4, classname: "pb_form_pill_text" }) %>
<% if object.icon.present? %>
<%= pb_rails("icon", props: { classname: "pb_form_pill_icon", icon: object.icon }) %>
<% end %>
<% elsif object.text.present? %>
<% if object.icon.present? %>
<%= pb_rails("icon", props: { classname: "pb_form_pill_icon", icon: object.icon }) %>
<% end %>
<% if object.text.present? %>
<%= pb_rails("title", props: { text: object.text, size: 4, classname: "pb_form_pill_tag" }) %>
<% end %>
<% end %>
<%= pb_rails("body", props: { classname: "pb_form_pill_close" }) do %>
<%= pb_rails("icon", props: { icon: 'times' , fixed_width: true }) %>
<% end %>
<% end %>
7 changes: 6 additions & 1 deletion playbook/app/pb_kits/playbook/pb_form_pill/form_pill.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@ class FormPill < Playbook::KitBase
values: %w[primary neutral],
default: "primary"
prop :tabindex
prop :icon

def classname
generate_classname("pb_form_pill_kit", color, name, text, text_transform)
generate_classname("pb_form_pill_kit", color, icon_class, name, text, text_transform)
end

def display_text
Expand All @@ -27,6 +28,10 @@ def display_text
def size_class
size == "small" ? " small" : ""
end

def icon_class
icon ? "icon" : nil
end
end
end
end
2 changes: 2 additions & 0 deletions playbook/spec/pb_kits/playbook/kits/form_pill_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,14 @@
it { is_expected.to define_prop(:avatar_url) }
it { is_expected.to define_prop(:size) }
it { is_expected.to define_prop(:color) }
it { is_expected.to define_prop(:icon) }

describe "#classname" do
it "returns namespaced class name", :aggregate_failures do
expect(subject.new({}).classname).to eq "pb_form_pill_kit_primary_none"
expect(subject.new(classname: "additional_class").classname).to eq "pb_form_pill_kit_primary_none additional_class"
expect(subject.new(color: "neutral").classname).to eq "pb_form_pill_kit_neutral_none"
expect(subject.new(icon: "user").classname).to eq "pb_form_pill_kit_primary_icon_none"
end
end
end

0 comments on commit 735f1d0

Please sign in to comment.