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

List: Sortable list interactions update #1541

Merged
merged 15 commits into from
Aug 23, 2022

Conversation

philschanely
Copy link
Contributor

Description

This PR updates styling for interactions with sortable List.

Screenshots

Figma spec

Before After
2022-08-01 16 34 24 2022-08-01 16 31 30

Testing in sage-lib

Testing in kajabi-products

  1. (LOW) Updates interactive styling for the List (sortable) component in Rails and React.

Related

SAGE-535

@philschanely philschanely self-assigned this Aug 1, 2022
@philschanely philschanely marked this pull request as ready for review August 3, 2022 12:04
@philschanely philschanely requested review from a team and cameronsimony August 3, 2022 12:05
@philschanely
Copy link
Contributor Author

FFR: Scheduled a design review with @cameronsimony for later today.

@@ -19,7 +19,12 @@ end
>
<% if component.sortable %>
<div class="sage-list__item-sortable-handle">
<%= sage_component SageIcon, { icon: "handle" } %>
<%= sage_component SageButton, {
Copy link
Member

Choose a reason for hiding this comment

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

Curious about the icon vs. button here? Are there any benefits? I see we do get the focus state, but would love to understand further.

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'm going to check on this with Cam during design review. IconButton was used in the Figma specs and think there is some interest in revising it so that it can only be reordered by dragging on this affordance. Def need Cam to look at it in the browser and ensure he's happy with it.

Copy link
Member

Choose a reason for hiding this comment

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

@philschanely would love to hear how the design review goes. I am also curious about the grab vs. move cursor, but my thoughts may become mute depending on what Cam comes back with.

Copy link
Member

@teenwolfblitzer teenwolfblitzer Aug 8, 2022

Choose a reason for hiding this comment

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

Actually clicking and dragging on the drag icon doesn't work for me in FF

Does work in Chrome

As Chris noted, the button in Firefox (and to a lesser extent, Safari when "holding" the button for a second or so) does not propagate the parent list item's event.

Whether or not the icon ends up being the drag "trigger" rather than the list item, we should consider changing it back to an icon rather than a true button element. This would at least restore the draggable behavior in FF/Safari and also be somewhat less confusing to AT users, since the label indicates that the button allows sorting, but it's only possible with a mouse.

Copy link
Member

@pixelflips pixelflips left a comment

Choose a reason for hiding this comment

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

Looks and works great! LGTM! Nice work! 👍🏼

@pixelflips pixelflips requested a review from a team August 3, 2022 16:30
@goodwinchris
Copy link
Contributor

goodwinchris commented Aug 4, 2022

Actually clicking and dragging on the drag icon doesn't work for me in FF

Does work in Chrome

Copy link
Member

@teenwolfblitzer teenwolfblitzer left a comment

Choose a reason for hiding this comment

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

👍🏼 As it currently stands, the functionality is not keyboard accessible, but this is part of the existing behavior, and not necessarily a blocker.

On a related note, the accessible capabilities of Sortable JS appear to be lacking. I'm wondering if we can replace it with a custom solution using the draggable API for a future follow-up. Or maybe leverage something like this as a shortcut.

Last thing… the sortable_update_url config in the Rails preview throws an error when onEnd fires. If we're not storing that state, should we remove it from the preview?

@@ -19,7 +19,12 @@ end
>
<% if component.sortable %>
<div class="sage-list__item-sortable-handle">
<%= sage_component SageIcon, { icon: "handle" } %>
<%= sage_component SageButton, {
Copy link
Member

@teenwolfblitzer teenwolfblitzer Aug 8, 2022

Choose a reason for hiding this comment

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

Actually clicking and dragging on the drag icon doesn't work for me in FF

Does work in Chrome

As Chris noted, the button in Firefox (and to a lesser extent, Safari when "holding" the button for a second or so) does not propagate the parent list item's event.

Whether or not the icon ends up being the drag "trigger" rather than the list item, we should consider changing it back to an icon rather than a true button element. This would at least restore the draggable behavior in FF/Safari and also be somewhat less confusing to AT users, since the label indicates that the button allows sorting, but it's only possible with a mouse.

@philschanely philschanely force-pushed the SAGE-535/pjs-sortable-list-interactions-update branch from ad7cc03 to 8981b7a Compare August 17, 2022 14:39
Copy link

@cameronsimony cameronsimony left a comment

Choose a reason for hiding this comment

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

paired with @philschanely for design QA on this & it looks great! a big 👍 from me!

@philschanely
Copy link
Contributor Author

@goodwinchris does this work better/consistently for you now?

@monkeypox8 are the changes here to your liking as well?

@philschanely philschanely requested a review from a team August 18, 2022 02:37
@philschanely philschanely force-pushed the SAGE-535/pjs-sortable-list-interactions-update branch from 8981b7a to ca7a647 Compare August 18, 2022 14:08
@philschanely
Copy link
Contributor Author

@monkeypox8 @pixelflips requesting a fresh review after having updated this PR.

Copy link
Member

@pixelflips pixelflips left a comment

Choose a reason for hiding this comment

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

A couple of minor non-blocking comments. In Safari, when dragging an item in the top section, items in the bottom section get highlighted/a background color applied.

list-highlight.mov

@@ -89,7 +131,7 @@ If you need more native content formatting you can instead opt to render items u
css_classes: SageClassnames::REVEAL_CONTAINER,
} do %>
<%= sage_component SageCardRow, { grid_template: "ete" } do %>
<img src="//source.unsplash.com/random/240x160?v=<%= item[:id] %>" width="100" alt="" />
<img src="//source.unsplash.com/random/240x160?v=<%= item[:id] %>" width="64" alt="" />
Copy link
Member

Choose a reason for hiding this comment

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

Def not a blocker, but could we add the protocol to the image src here? Protocol-relative URLs have become somewhat of an antipattern now that SSL is highly encouraged and HTTPS no longer has performance issues.

@@ -64,7 +102,6 @@ List.Item = ListItem;
List.defaultProps = {
children: null,
className: null,
hideFirstBorder: false,
Copy link
Member

Choose a reason for hiding this comment

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

If hideFirstBorder is no longer needed, would be worth removing it from the Rails side and the related styles as well? Could definitely be handled in a follow-up

sortableConfigs = { ...DEFAULT_CONFIGS };
}

console.log('final configs', resourceName, sortableConfigs);
Copy link
Member

@pixelflips pixelflips Aug 18, 2022

Choose a reason for hiding this comment

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

Should the console.log be removed?

Copy link
Member

@pixelflips pixelflips left a comment

Choose a reason for hiding this comment

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

Rechecked and am no longer seeing the ID issue as we discussed. LGTM! 👍🏼

@philschanely philschanely force-pushed the SAGE-535/pjs-sortable-list-interactions-update branch from abf1c7e to d06dec6 Compare August 18, 2022 19:12
Copy link
Member

@teenwolfblitzer teenwolfblitzer left a comment

Choose a reason for hiding this comment

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

👍 LGTM, nice work! Thanks for getting this… sorted out 😝

@philschanely philschanely requested a review from a team August 19, 2022 02:32
@@ -5,16 +5,16 @@ tag = component.tag.present? ? component.tag : "ul"
class="
sage-list
<%= component.generated_css_classes %>
<%= "sage-list--hide-first-border" if component.hide_first_border %>
<%= "sage-list--all-draggable" if component.sortable_configs && component.sortable_configs[:handle] == false %>
Copy link
Collaborator

Choose a reason for hiding this comment

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

ruby tip you can change this to component.dig(:sortable_configs, :handle).blank?. This will account for it either being nil or false'. Handle being set to true will pass the blank? check.

[7] pry(main)> component = {sortable_configs: {handle: false}}
=> {:sortable_configs=>{:handle=>false}}
[8] pry(main)> component.dig(:sortable_configs, :handle).blank?
=> true
[9] pry(main)> component.dig(:sortable_configs, :handle)
=> false
[10] pry(main)> component = {sortable_configs: {handle: true}}
=> {:sortable_configs=>{:handle=>true}}
[11] pry(main)> component.dig(:sortable_configs, :handle).blank?
=> false
[12] pry(main)>

@ju-Skinner
Copy link
Collaborator

Lint failure

packages/sage-assets/lib/stylesheets/components/_table.scss
 35:5  ⚠  Expected indentation of 2 spaces   indentation

@philschanely philschanely force-pushed the SAGE-535/pjs-sortable-list-interactions-update branch from d06dec6 to 608e608 Compare August 19, 2022 18:02
@philschanely
Copy link
Contributor Author

@monkeypox8 @pixelflips and @ju-Skinner since last review I made the following updates to further hone how this component works:

  • I abandoned the sortableConfigs/sortable_configs prop that was initially meant to allow the user to pass configs down to the SortableJS inside the component. On React, I instead surfaced only the props we intend to expose at this time: setList, onStart, and onEnd. On Rails this is not practical at this time (and not attempted in previous Sortable component either).
  • I added a dragHandleType/drag_handle_type prop that allows user to choose between "default" and "row". The default is to only allow the end user to sort/drag by the drag handle, but "row" makes the whole row draggable.
  • I moved sortable<boolean> as a prop up from the children Items to the parent List.

Copy link
Member

@pixelflips pixelflips left a comment

Choose a reason for hiding this comment

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

Rechecked all main browsers and all still LGTM! 👍🏼

Copy link
Member

@teenwolfblitzer teenwolfblitzer left a comment

Choose a reason for hiding this comment

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

👍🏼 LGTM! Two final items to consider; both are documentation-related so not considered as blockers for the merge.

Noting here also that I'm not able to get the bridge running due to a bundler issue.

", use_sage_type: true) %>

<%= sage_component SageList, {
sortable: true,
Copy link
Member

Choose a reason for hiding this comment

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

For the sortable examples, thoughts on adding tag: "ol" to drive home the ordinal values?

I suppose we could also be more heavy-handed and change the default to an ol when setting sortable: true in the component, but that's beyond the scope of this work.

...selectArgs({
dragHandleType: List.DRAG_HANDLE_TYPES,
}),
},
args: {
items: [],
Copy link
Member

Choose a reason for hiding this comment

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

I'm getting an error when attempting to toggle the base list to "sortable" in Storybook. Seems it's because we're not defining setList for the default config?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That's right. The setList needs to be set as well so it's not as straightforward to switch props in storybook.

Copy link
Member

@pixelflips pixelflips left a comment

Choose a reason for hiding this comment

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

On drag-n-drop I am seeing the following error in the console. I only point it out as I am seeing this popping up in DataDog UX Monitor Errors on the KP side as well.

Screen Shot 2022-08-22 at 4 15 01 PM

Definitely not a blocker, since it looks like it's been hanging around for a while.

Copy link
Member

@pixelflips pixelflips left a comment

Choose a reason for hiding this comment

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

It may or may not be related to these updates, but I seem to be getting some odd behavior when clicking the dropdown in the fully draggable section. After opening the dropdown, clicking out of it kinda blinks and doesn't close smoothly if at all.

Screen.Recording.2022-08-22.at.4.56.46.PM.mov

Copy link
Collaborator

@ju-Skinner ju-Skinner left a comment

Choose a reason for hiding this comment

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

see comments. the request changes is for documentation purposes in docs/app/views/examples/components/list/_preview.html.erb. There are a couple of other callouts as well.

<h3 class="<%= SageClassnames::TYPE::HEADING_6 %>">Fully draggable row</h3>
<%= md("
By default only the drag handle is active for dragging/sorting a row.
However, `draggable_anywhere` can be set to `true` in order to allow the whole row to be draggable instead.
Copy link
Collaborator

Choose a reason for hiding this comment

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

I believe you need to change draggable_anywhere to "drag_handle_type can be set to row" here.

@@ -1,11 +1,13 @@
<%
tag = component.tag.present? ? component.tag : "ul"
drag_handle_type = component.tag.present? ? component.tag : "default"
Copy link
Collaborator

Choose a reason for hiding this comment

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

This may have been an oversight or a misunderstanding from me. drag_handle_type accepts two options based on the code above default and row. So if component.tag is anything other than those two values, what would be the expectation here?

Is this tag: [:optional, NilClass, Set.new(["ul", "ol"])], the same component.tag values?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh wow good catch. I'll touch this up for sure!

items: [],
itemRenderer: null,
sortableConfigs: null,
dragHandleType: List.DRAG_HANDLE_TYPES.DEFAULT,
onEnd: null,
Copy link
Collaborator

Choose a reason for hiding this comment

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

for functions it is recommended to use noop vs null

Copy link
Contributor Author

Choose a reason for hiding this comment

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

TIL!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hmm... validation does not like that... is it an accepted keyword in js?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I set these up as () => null but lmk if that's not what you were looking for.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Sorry, I made a bad assumption. So noop is a lodash function, that essentially returns undefined which is completely different than the value of null.

Examples taken from console....created a noop function to mimic lodash to show difference.

null === undefined
false
function noop() { return undefined }
undefined
null === noop()
false
undefined === noop()
true

onEnd: null,
onStart: null,
setList: null,
onEnd: () => null,
Copy link
Collaborator

Choose a reason for hiding this comment

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

this is the equivalent to what you had before...you can do one of two things

  1. () => {} // returns undefined <- this is common
  2. () => ( undefined ) // explicitly returns undefined

Copy link
Collaborator

@ju-Skinner ju-Skinner left a comment

Choose a reason for hiding this comment

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

Great job. :shipit:

@philschanely philschanely merged commit 71a5a82 into develop Aug 23, 2022
@philschanely philschanely deleted the SAGE-535/pjs-sortable-list-interactions-update branch August 23, 2022 15:15
@philschanely philschanely mentioned this pull request Aug 23, 2022
4 tasks
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.

6 participants