Skip to content

Conversation

thetaPC
Copy link
Contributor

@thetaPC thetaPC commented Aug 17, 2023

Issue number: resolves #27229


What is the current behavior?

Checkbox, radio, toggle, and range do not allow labels to be stacked.

What is the new behavior?

  • Checkbox can stack the label on top of the control and adjust the alignment.
    • New prop align was added with center as the default1
    • New label-placement value was added
    • Snapshots were added
  • Radio can stack the label on top of the control and adjust the alignment.
    • New prop align was added with center as the default1
    • New label-placement value was added
    • Snapshots were added
  • Toggle can stack the label on top of the control and adjust the alignment.
    • New prop align was added with center as the default1
    • New label-placement value was added
    • Snapshots were added
  • Range can stack the label on top of the control and adjust the alignment.
    • New label-placement value was added
    • Alignment cannot be changed. The label will be on the left side when LTR and right when RTL.
    • Snapshots were added, padding was added to the container to prevent the knob from being cut off

Does this introduce a breaking change?

  • Yes
  • No

Other information

  • Recommendation: Use the file filter during the PR review to filter out images. It'll make it easier to review code.
  • Associated PR to update ion-docs

Footnotes

  1. center is being used because align-items="center" was the original style prior to the implementation. Otherwise, the label will not line up correctly on default. For example, the checkbox for iOS will shift the label to the top left corner when align defaulted to start.2 This shift happens because the input is larger than the label, making the alignment obvious. But this is not correct, the label must be centered vertically as the default to prevent breaking changes to the current visualizations. 2 3

  2. Screenshot 2023-08-17 at 4 51 36 PM

@bolt-new-by-stackblitz
Copy link

Review PR in StackBlitz Codeflow Run & review this pull request in StackBlitz Codeflow.

@github-actions github-actions bot added the package: core @ionic/core package label Aug 17, 2023
@thetaPC thetaPC changed the title refactor(many): stacked labels for form controls feat(many): stacked labels for form controls Aug 22, 2023
@thetaPC thetaPC changed the title feat(many): stacked labels for form controls feat(checkbox, radio, toggle, range): stacked labels for form controls Aug 22, 2023
@github-actions github-actions bot added package: angular @ionic/angular package package: vue @ionic/vue package labels Aug 22, 2023
@@ -138,5 +138,31 @@ configs().forEach(({ title, screenshot, config }) => {
expect(await checkbox.screenshot()).toMatchSnapshot(screenshot(`checkbox-label-fixed-justify-space-between`));
});
});

test.describe('checkbox: stacked placement', () => {
test('should render a start alignment with label in the stacked position', async ({ page }) => {
Copy link
Contributor

Choose a reason for hiding this comment

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

~ The test descriptions are a bit hard to decipher/read.

Thoughts on rewording to:

should align the label to the start of the container in the stacked position

This would apply to the center align test as well.

@@ -137,5 +137,35 @@ configs().forEach(({ title, screenshot, config }) => {
expect(await radio.screenshot()).toMatchSnapshot(screenshot(`radio-label-fixed-justify-space-between`));
});
});

test.describe('radio: stacked placement', () => {
test('should render a start alignment with label in the stacked position', async ({ page }) => {
Copy link
Contributor

Choose a reason for hiding this comment

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

~ Similar feedback here as checkbox for test descriptions.

@@ -124,6 +140,22 @@ configs().forEach(({ title, screenshot, config }) => {

expect(await range.screenshot()).toMatchSnapshot(screenshot(`range-items-fixed`));
});
test('should render label in the stacked placement', async ({ page }) => {
Copy link
Contributor

Choose a reason for hiding this comment

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

~ Thoughts on rewording to:

should render label above the range slider

Copy link
Contributor

@liamdebeasi liamdebeasi 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 really good! I found two edge cases we'll want to account for.

@@ -81,8 +81,9 @@ export class Checkbox implements ComponentInterface {
* `"start"`: The label will appear to the left of the checkbox in LTR and to the right in RTL.
* `"end"`: The label will appear to the right of the checkbox in LTR and to the left in RTL.
* `"fixed"`: The label has the same behavior as `"start"` except it also has a fixed width. Long text will be truncated with ellipses ("...").
* `"stacked"`: The label will appear above the checkbox regardless of the direction.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
* `"stacked"`: The label will appear above the checkbox regardless of the direction.
* `"stacked"`: The label will appear above the checkbox regardless of the direction. The alignment of the label can be controlled with the `align` property.

Copy link
Contributor

Choose a reason for hiding this comment

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

Ditto for the instances of "stacked" for the other components

align-items: normal;
}

:host(.range-label-placement-stacked) .label-text-wrapper {
Copy link
Contributor

Choose a reason for hiding this comment

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

The pin on a range with a stacked label currently overlaps the text. We add padding to the host .range-has-pin is present, but we should probably add that as bottom margin to the label so the pin never obscures the label.

At the very least, you'll need to add bottom margin to the .label-text-wrapper element in each mode stylesheet. You can use the existing padding values that we set on the host when the .range-has-pin class is present in each mode stylesheet.

We then need to remove the host padding since we are setting it as margin on the label wrapper instead. There are a couple ways you can do this:

  1. Set @include padding(0px) in the base stylesheet when .range-label-placement-stacked is present.
  2. Update the existing .range-has-pin selectors to exclude .range-label-placement-stacked using :not.

We'll also want to capture a screenshot for this.

/**
* Label is on top of the checkbox.
*/
:host(.checkbox-label-placement-stacked) .checkbox-wrapper {
Copy link
Contributor

Choose a reason for hiding this comment

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

The following applies to checkbox, radio, and toggle (range is not impacted).

When used in an item, there is not enough bottom margin. It looks like we used to account for this on .label-text-wrapper which works fine when the label and control are on the same line, but it looks a little smushed when using stacked layout:

image

You'll want to apply margin on the top of .label-text-wrapper as well as margin on the bottom of .native-wrapper. So something like this:

:host(.in-item.toggle-label-placement-stacked) .label-text-wrapper {
  @include margin($toggle-item-label-margin-top, null, $form-control-label-margin, null);
}

:host(.in-item.toggle-label-placement-stacked) .native-wrapper {
  @include margin(null, null, $toggle-item-label-margin-bottom, null);
}

We'll want screenshot tests for this too.

@thetaPC
Copy link
Contributor Author

thetaPC commented Aug 29, 2023

Closing this PR in favor of another PR

@thetaPC thetaPC closed this Aug 29, 2023
@thetaPC thetaPC deleted the FW-4090 branch August 30, 2023 15:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
package: angular @ionic/angular package package: core @ionic/core package package: react @ionic/react package package: vue @ionic/vue package
Projects
None yet
Development

Successfully merging this pull request may close these issues.

feat: stacked labels for form controls
4 participants