0
votes

I've created a Custom Form Field Control for Angular 8 compatible with Reactive Forms and Angular Material. However, it being a simplified Rich-Text Editor, it has a header with various buttons with actions for the user.

How can I move the Placeholder label below the header of my input control to the actual textarea?

Current placeholder label placement

1
Other than on or off, there is no option for the position of the floating placeholder.G. Tranter
@G.Tranter Thanks. Guess I'll have to experiment a bit and see if I can figure something out.ArdentAngel

1 Answers

0
votes

Well, since nobody really responded to my question, I'll post my own solution to this problem, one cruder (Solution 2) and one I deem proper (Solution 2, though to me it appears otherwise).

Edit: Solution 2: Proper approach

Well, I tried to make my code slightly more-configurable, hence I made one little mistake when changing code - I changed one variable to static, a variable used to declare the ID MatFormField uses in a class definition inside itself which we can use to customize the look of our component.

Namely controlType. Using this variable, we can identify when our component is in-use by direct class name following naming convention mat-form-field-type-<controlType>. So, since my controlType = "app-text-editor", I can use it like this:

.mat-form-field-type-app-text-editor:not(.mat-form-field-should-float) .mat-form-field-label-wrapper > .mat-form-field-label {
    margin-top: 2.5rem;
    padding: .5em;
}

Original: Solution 1: Hacky-approach

What I did was change my component to encapsulation: ViewEncapsulation.None, used the selector of my component inside css as my main identifier (in my case: app-text-editor) and then used CSS Sibling selector to select the floating label and placeholder to set offset for my TextEditor header and reset it back to default once the label is floating. The resulting CSS looks like this:

app-text-editor {
  // Styling for actual TextEditor

  &.floating ~ .mat-form-field-label-wrapper > .mat-form-field-label {
    margin-top: initial;
    padding: initial;
  }
  & ~ .mat-form-field-label-wrapper > .mat-form-field-label {
    margin-top: 2.5rem;
    padding: .5em; // Used to properly align the content inside my contenteditable
}

Or as pure CSS would look like:

app-text-editor.floating ~ .mat-form-field-label-wrapper > .mat-form-field-label {
  margin-top: initial;
  padding: initial;
}
app-text-editor ~ .mat-form-field-label-wrapper > .mat-form-field-label {
  margin-top: 2.5rem;
  padding: .5em; /* Used to properly align the content inside my contenteditable */
}

Weirdly enough, even the animation transition looks smooth despite me using such a hacky-approach for repositioning it.

If you don't mind using advanced CSS selector (Can I Use: Advanced CSS3 selectors), the solution can be even cleaner:

SCSS:

app-text-editor {
  // Styling for the actual TextEditor

  &:not(.floating) ~ .mat-form-field-label-wrapper > .mat-form-field-label {
    margin-top: 2.5rem;
    padding: .5em; // Used to properly align the content inside my contenteditable
}

Pure CSS:

app-text-editor:not(.floating) ~ .mat-form-field-label-wrapper > .mat-form-field-label {
  margin-top: 2.5rem;
  padding: .5em; /* Used to properly align the content inside my contenteditable */
}