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

feat(slider): Implement vertical orientation #9953

Closed

Conversation

josercarcamo
Copy link
Contributor

@josercarcamo josercarcamo commented Aug 2, 2024

Related Issue: #5522

Summary

Implemented a vertical orientation for the slider, along with label, precise, ticks.

@josercarcamo josercarcamo changed the title [DRAFT] feat(slider): Implement vertical orientation feat(slider): Implement vertical orientation Aug 2, 2024
@josercarcamo josercarcamo marked this pull request as draft August 2, 2024 19:49
@github-actions github-actions bot added the enhancement Issues tied to a new feature or request. label Aug 6, 2024
Copy link
Contributor

This PR has been automatically marked as stale because it has not had recent activity. Please close your PR if it is no longer relevant. Thank you for your contributions.

@github-actions github-actions bot added Stale Issues or pull requests that have not had recent activity. and removed Stale Issues or pull requests that have not had recent activity. labels Sep 15, 2024
@josercarcamo josercarcamo added the pr ready for visual snapshots Adding this label will run visual snapshot testing. label Sep 18, 2024
@josercarcamo josercarcamo added pr ready for visual snapshots Adding this label will run visual snapshot testing. and removed pr ready for visual snapshots Adding this label will run visual snapshot testing. labels Sep 27, 2024
@josercarcamo josercarcamo added pr ready for visual snapshots Adding this label will run visual snapshot testing. and removed pr ready for visual snapshots Adding this label will run visual snapshot testing. labels Oct 1, 2024
@josercarcamo josercarcamo marked this pull request as ready for review October 2, 2024 19:39
Copy link
Contributor

This PR has been automatically marked as stale because it has not had recent activity. Please close your PR if it is no longer relevant. Thank you for your contributions.

@github-actions github-actions bot added the Stale Issues or pull requests that have not had recent activity. label Oct 12, 2024
@github-actions github-actions bot removed the Stale Issues or pull requests that have not had recent activity. label Oct 22, 2024
expect(button).toEqualAttribute("aria-valuemin", "0");
expect(button).toEqualAttribute("aria-valuemax", "100");
expect(button).toEqualAttribute("aria-orientation", "horizontal");
for (const l of ["horizontal", "vertical"]) {
Copy link
Member

@benelan benelan Oct 22, 2024

Choose a reason for hiding this comment

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

Instead of adding a for loop inside the tests, can you wrap them all in a describe.each block. Something like this:

describe.each(["horizontal", "vertical"])("%s layout", (layout) => {
 // tests here
})

NOTE: I typed that directly into the comment so the syntax may be off.

This will make it easier to determine which layout is causing issues when there are test failures. Also we have a convention not to abbreviate so I changed l to layout.

scale="m"
></calcite-slider>
`;
const simple = {};
Copy link
Member

Choose a reason for hiding this comment

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

We don't need separate "simple" stories for the layout property because it can be changed via the knobs.

};

const rangeLabeledTicksEdgePositioningAtMin = {};
for (const l of ["horizontal", "vertical"]) {
Copy link
Member

Choose a reason for hiding this comment

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

I don't think all of these stories need to be duplicated for vertical vs horizontal.

How about one vertical story that has a couple sliders with different configurations that might be impacted by the change in layout?

Copy link
Member

@jcfranco jcfranco left a comment

Choose a reason for hiding this comment

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

Great progress, @josercarcamo! 💪

I brought up some things that need to be addressed. LMK if you have any questions.

@@ -559,8 +576,9 @@ export class Slider
return;
}

const x = event.clientX || event.pageX;
const position = this.mapToRange(x);
const v =
Copy link
Member

Choose a reason for hiding this comment

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

What does v represent? If it's value, can you rename it to be more expressive?

@@ -938,13 +958,20 @@ export class Slider
/**
* Translate a pixel position to value along the range
*
* @param x
* @param p
Copy link
Member

Choose a reason for hiding this comment

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

Can you rename this to be expressive?

const { left, width } = this.trackEl.getBoundingClientRect();
const percent = (x - left) / width;
let percent: number;
if (this.layout === "horizontal") {
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 a bit of duplication here. Can you DRY it up?

@@ -247,6 +249,9 @@ export class Slider
}

componentDidRender(): void {
if (this.layout === "vertical") {
Copy link
Member

Choose a reason for hiding this comment

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

FIXME: this is bypassing logic that should apply to both layouts (e.g., avoiding label overlap). You can see the difference by comparing edge/overlapping stories in both layouts.

Copy link
Contributor Author

@josercarcamo josercarcamo Oct 24, 2024

Choose a reason for hiding this comment

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

Actually, most of this code translates the handle label in the x direction, which is not needed for vertical.

Copy link
Member

Choose a reason for hiding this comment

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

This needs to handle vertical label overlap for both layouts. You can see this if you compare the edge/overlapping stories:

Range Labeled Ticks Edge Positioning At Max
Screenshot 2024-10-24 at 2 56 58 PM
Screenshot 2024-10-24 at 2 57 08 PM

Range Labeled Ticks Overlapping At Min
Screenshot 2024-10-24 at 2 56 49 PM
Screenshot 2024-10-24 at 2 56 52 PM

@ashetland Do we need hyphenation when vertical?

Choose a reason for hiding this comment

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

Nice catch! Yep, looks like we need this on vertical as well. While we're at it, is it possible to add a space so it would look like 99.5 - 100 instead of 99.5- 100?

Copy link
Contributor Author

@josercarcamo josercarcamo Oct 25, 2024

Choose a reason for hiding this comment

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

Could we please update the design since the numbers are now one on top of the other? Or should it just display "99.5 - 100 |" where "|" is the vertical range bar whenever they overlap each other?

Choose a reason for hiding this comment

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

Yep, when the range handles overlap, it should display "99.5 - 100" like the horizontal layout.

></calcite-slider>
`;
}
export const simpleH = simple["horizontal"];
Copy link
Member

Choose a reason for hiding this comment

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

For readability, avoid abbreviations in test names.

export const rangeH = range["horizontal"];
export const rangeV = range["vertical"];

const darkMode = {};
Copy link
Member

Choose a reason for hiding this comment

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

Can you type this, and similar objects? May not be applicable if story functions are parameterized.

></calcite-slider>
`;
}
export const simpleH = simple["horizontal"];
Copy link
Member

Choose a reason for hiding this comment

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

FIXME: can you restore the names for the previous, horizontal stories? Renamed stories will get treated as new ones and won't display a diff.

For improved organization, we could look at having separate stories for each slider layout configuration. I think we can use title for this separation and have Storybook take care of the hierarchy (e.g., title: "Components/Controls/Slider [default], title: "Components/Controls/Slider/Vertical" [new]). I'm open to other ideas too.

Copy link
Member

@benelan benelan Oct 23, 2024

Choose a reason for hiding this comment

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

what if we make it so each story has two sliders - one horizontal and one vertical? That way we don't double slider's chromatic snapshots. Specifically for simple, we only need one slider because it can be changed via knobs like I mentioned above.

Copy link
Member

Choose a reason for hiding this comment

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

I dig this. Besides reducing snapshots, it also makes it easier to add coverage for both compared to handling them separately.

`;
const simple = {};
for (const l of ["horizontal", "vertical"]) {
simple[l] = (args: SliderStoryArgs): string => html`
Copy link
Member

Choose a reason for hiding this comment

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

Storybook allows us to pass arguments to stories, so can you update these to use args:

const SimpleTemplate = {
  render:  (args: SliderStoryArgs): string => html`
<calcite-slider
      min="${args.min}"
      max="${args.max}"
      value="${args.value}"
      step="${args.step}"
      min-label="${args.minLabel}"
      ${boolean("disabled", args.disabled)}
      ${boolean("label-handles", args.labelHandles)}
      ${boolean("label-ticks", args.labelTicks)}
      ticks="${args.ticks}"
      page-step="${args.pageStep}"
      ${boolean("precise", args.precise)}
      ${boolean("mirrored", args.mirrored)}
      ${boolean("snap", args.snap)}
      scale="${args.scale}"
      layout=${args.layout || "horizontal"}
      style="${args.style}"
    ></calcite-slider>
  `;
}

export const simple = {
  ...SimpleTemplate,
  // default "horizontal" specified at [CSF (story metadata) level](https://github.com/Esri/calcite-design-system/pull/9953/files#diff-a4b7803179119e68983d2abf8a806a8e0be7c72550eee9a97a583b289c01ba0aR46)
};

export const simpleVertical = {
  ...SimpleTemplate,
  args: {
    layout: "vertical"
  }
};

See https://storybook.js.org/docs/writing-stories/stories-for-multiple-components#creating-a-template-component

Generalizing the template might help simplify setup for other stories.

@@ -42,6 +43,8 @@ export default {
mirrored: false,
snap: true,
scale: scale.defaultValue,
layout: "horizontal",
style: "padding-top: 200px; padding-left: 100px; height: 200px",
Copy link
Member

Choose a reason for hiding this comment

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

FIXME: it looks like style was added to work around the slider not having the proper box model. In general, we only want to provide defaults for component props.

(this.layout === "horizontal" &&
(minThumbTypes.includes("histogram") || minThumbTypes.includes("precise"))) ||
(this.layout === "vertical" && valueIsRange && this.precise && !this.mirrored) ||
(this.layout === "vertical" && valueIsRange && this.precise && this.mirrored)
Copy link
Member

Choose a reason for hiding this comment

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

mirrored is canceled out in these or statements, so you could simplify this to:

thumbPlacement:
  (this.layout === "horizontal" && (minThumbTypes.includes("histogram") || minThumbTypes.includes("precise"))) ||
  (this.layout === "vertical" && valueIsRange && this.precise);

@josercarcamo josercarcamo added pr ready for visual snapshots Adding this label will run visual snapshot testing. and removed pr ready for visual snapshots Adding this label will run visual snapshot testing. labels Oct 25, 2024
@josercarcamo josercarcamo force-pushed the josercarcamo/5522-slider-vertical-horizontal branch from db157ab to d7c9321 Compare October 28, 2024 18:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Issues tied to a new feature or request. pr ready for visual snapshots Adding this label will run visual snapshot testing.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants