Skip to content
This repository has been archived by the owner on Jul 12, 2020. It is now read-only.

Enable seamless Panel's caret to stay inline #74

Merged
merged 1 commit into from
Jul 19, 2018

Conversation

Chng-Zhi-Xuan
Copy link

@Chng-Zhi-Xuan Chng-Zhi-Xuan commented Jul 17, 2018

What is the purpose of this pull request? (put "X" next to an item, remove the rest)

• [x] Enhancement to an existing feature

Fixes MarkBind/markbind#337

What is the rationale for this request?
Seamless Panels have its caret pushed to the previous line when the Panel width is too small. The expected behaviour is having the header text wrap around while having the caret inline.

What changes did you make? (Give an overview)

  • Added a new toggle-able inline caret to default header slot rendered via v-html="headerContent".
  • Cleaned up some logic for existing caret.
  • Change popup button to only appear on mouse over for seamless Panels.
Before After
337-before 337-after
Note
When using slot="header" , the problem will re-emerge as there is no way to insert the caret inside the slotted element without using Cheerio / JQuery.

Is there anything you'd like reviewers to focus on?

  • Logic in methods and template

Testing instructions:

  • Run npm run build and paste the updated vue-strap.min.js into MarkBind's asset folder.
  • Run markbind init, author a seamless panel with a long header.
  • Run markbind serve and reduce window width.
  • Check that the caret stays inline and is toggle-able.

@Chng-Zhi-Xuan Chng-Zhi-Xuan changed the title Panel: Enable seamless caret to stay inline Enable seamless Panel's caret to stay inline Jul 17, 2018
@yamgent
Copy link
Member

yamgent commented Jul 17, 2018

The popup button shows even if no popup url is specified.

<panel type="seamless" header="The The The The The The The The The The ">
Hi.
</panel>

src/Panel.vue Outdated
@click.stop="close()">
<span class="glyphicon glyphicon-remove" aria-hidden="true"></span>
</button>
<button type="button" :class="['popup-button', 'btn', isLightBg ? 'btn-outline-secondary' : 'btn-outline-light']"
v-show="this.popupUrl !== null"
v-show="((this.popupUrl !== null) && (isSeamless ? onHeaderHover : (!noCloseBool)))"
Copy link
Member

Choose a reason for hiding this comment

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

As discussed, if no-close is specified, but popup is specified, the popup button still does not show. The user might have reasons to show the popup button even if he wants to hide the close button.

src/Panel.vue Outdated
if (this.isSeamless) {
return this.caretHtml + ' ' + this.inlineRenderedHeader;
}
return this.renderedHeader;
Copy link
Member

Choose a reason for hiding this comment

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

As discussed, maybe everything can just use inline then, since for non-seamless, it seems to not make a difference, there is no reason to do different rendering ways for different type of panels.

Copy link
Member

@yamgent yamgent left a comment

Choose a reason for hiding this comment

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

Some minor nits

src/Panel.vue Outdated
@click.stop="close()">
<span class="glyphicon glyphicon-remove" aria-hidden="true"></span>
</button>
<button type="button" :class="['popup-button', 'btn', isLightBg ? 'btn-outline-secondary' : 'btn-outline-light']"
v-show="this.popupUrl !== null"
v-show="((this.popupUrl !== null) && (isSeamless ? onHeaderHover : true))"
Copy link
Member

Choose a reason for hiding this comment

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

(isSeamless ? onHeaderHover : true)) is a form of p -> q.

Therefore, this can be simplified to:

(this.popupUrl !== null) && (!isSeamless || onHeaderHover)

Copy link

Choose a reason for hiding this comment

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

Nice.

src/Panel.vue Outdated
}
},
hasCustomHeader () {
if (this.$slots.header) {
Copy link
Member

Choose a reason for hiding this comment

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

Can this be simplified to return this.$slots.header;?

Copy link
Author

Choose a reason for hiding this comment

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

Then it will return either a null object or a v-node object, which is not a Boolean

Copy link
Member

Choose a reason for hiding this comment

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

How about return this.$slots.header !== null; then

Copy link
Author

Choose a reason for hiding this comment

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

I was wrong, it gives undefined instead of null. Will modify accordingly.

@yamgent yamgent added this to the v2.0.1-markbind.15 milestone Jul 18, 2018
@Chng-Zhi-Xuan
Copy link
Author

Update

  • Squashed commits

@yamgent yamgent merged commit d7626b3 into MarkBind:master Jul 19, 2018
@damithc
Copy link

damithc commented Jul 20, 2018

This problem seems to be fixed in most places but traces of it remain in some places. e.g.,
image
The above is a new bit of code I added today, BTW.

@yamgent
Copy link
Member

yamgent commented Jul 23, 2018

This problem seems to be fixed in most places but traces of it remain in some places. e.g.,

That panel header appears that way because it uses a custom header slot.

We did not implement the logic to insert the caret inside the content, because the content here can literally be anything, so we cannot make any good assumptions. Hence, custom headers will always have the caret outside the content, resulting in the breaking. (new discovery, see subsequent post).

See the original post:

When using slot="header" , the problem will re-emerge as there is no way to insert the caret inside the slotted element without using Cheerio / JQuery.

@acjh
Copy link

acjh commented Jul 23, 2018

Try styling the slot as display: inline-block;

@yamgent
Copy link
Member

yamgent commented Jul 23, 2018

Try styling the slot as display: inline-block;

Tried it, didn't work. :S

@damithc
Copy link

damithc commented Jul 23, 2018

I see. Looks like there is no easy way around it. Still, we should not give up entirely. I use slots a lot because my headings often contains span elements (e.g., to add stars of a certain color). Would the introduction of a <header> element help?

May be create a separate issue and explain the exact problem?

@damithc
Copy link

damithc commented Jul 23, 2018

BTW, can we allocate more space for the header (and less space for panel buttons)? That should reduce the incidence of this problem. In this screenshot, there seems to be enough space for the full title.

image

@yamgent
Copy link
Member

yamgent commented Jul 23, 2018

Found the reason why the caret breaks on your website. It is because your custom headers were using the card-title Bootstrap style, but it should not be used when the panels are seamless, because we don't use the Bootstrap's card design when it is seamless.

Solution: If custom header slots are used, and your panels are seamless, don't use card-title style.

This solution will have to be documented in the "Advanced Tips and Tricks" section.

As to why I was able to somehow "replicate" the issue on my side, I realize that this does not happen if the custom slot header is declared with <span>. I was using <p> all along, which explains why the caret and the headers break on my side. My bad. :P

@yamgent
Copy link
Member

yamgent commented Jul 23, 2018

@damithc we found another issue with the implementation of caret with the panel that may be related to this bug, so you can ignore the above solution for now, as we will try to fix it on our side.

yamgent added a commit to yamgent/vue-strap that referenced this pull request Jul 27, 2018
…s-panel"

This reverts commit d7626b3, reversing
changes made to a0bae9e.
yamgent added a commit to yamgent/vue-strap that referenced this pull request Jul 27, 2018
The caret is combined with the header content. It is usually rendered
like this:

> Some heading

However, custom header contents, after markdown rendering, will be
wrapped with block HTML tags such as <p> and <h1>, which will make
browsers render a line break between the caret and header content:

>
Some heading

Let's fix this by moving the caret to a separate div. Then, make
everything inside a panel header be on a single line by using CSS
'display: inline-block' and 'width: ...', such that the width adds up to
100%.

    +--------+-----------------+---------+
    | caret  |  header-content | buttons |
    | (32px) | (100% - 32 - 32)|  (32px) |
    +--------+-----------------+---------+

Thanks to @nusjzx for providing the fix to the button-wrapper in PR
MarkBind#86, in which his use of
'calc(100% - 32px)' provided a source of inspiration for this fix. His
fix in that PR is incorporated into this commit because without it, the
responsive design will not work.

An alternative fix considered was to use md.renderInline(). However,
md.renderInline() does not render markdown headings.

Another alternative fix was to insert the caret directly inside the
header content. However, after PR MarkBind#74, MarkBind#81 and MarkBind#83 were merged, new
problems continue to emerge.

These problems are reported as comments in these pages:
- MarkBind#74
- MarkBind#81
- MarkBind#83
- MarkBind/markbind#373
- MarkBind/markbind#383

As such, the PRs for this alternative fix has been reverted by the
previous commits before this commit. Therefore, this commit shall be
viewed as the canonical fix for issue
MarkBind/markbind#337.
yamgent added a commit to yamgent/vue-strap that referenced this pull request Jul 27, 2018
The caret is combined with the header content. It is usually rendered
like this:

> Some heading

However, custom header contents, after markdown rendering, will be
wrapped with block HTML tags such as <p> and <h1>, which will make
browsers render a line break between the caret and header content:

>
Some heading

Let's fix this by moving the caret to a separate div. Then, make
everything inside a panel header be on a single line by using CSS
'display: inline-block' and 'width: ...', such that the width adds up to
100%.

    +--------+-----------------+---------+
    | caret  |  header-content | buttons |
    | (32px) | (100% - 32 - 32)|  (32px) |
    +--------+-----------------+---------+

Thanks to @nusjzx for providing the fix to the button-wrapper in PR
MarkBind#86, in which his use of
'calc(100% - 32px)' provided a source of inspiration for this fix. His
fix in that PR is incorporated into this commit because without it, the
responsive design will not work.

An alternative fix considered was to use md.renderInline(). However,
md.renderInline() does not render markdown headings.

Another alternative fix was to insert the caret directly inside the
header content. However, after PR MarkBind#74, MarkBind#81 and MarkBind#83 were merged, new
problems continue to emerge.

These problems are reported as comments in these pages:
- MarkBind#74
- MarkBind#81
- MarkBind#83
- MarkBind/markbind#373
- MarkBind/markbind#383

As such, the PRs for this alternative fix has been reverted by the
previous commits before this commit.
yamgent added a commit to yamgent/vue-strap that referenced this pull request Jul 27, 2018
The caret is combined with the header content. It is usually rendered
like this:

> Some heading

However, custom header contents, after markdown rendering, will be
wrapped with block HTML tags such as <p> and <h1>, which will make
browsers render a line break between the caret and header content:

>
Some heading

Let's fix this by moving the caret to a separate div. Then, make
everything inside a panel header be on a single line by using CSS
'display: inline-block' and 'width: ...', such that the width adds up to
100%.

    +--------+-----------------+---------+
    | caret  |  header-content | buttons |
    | (32px) | (100% - 32 - 32)|  (32px) |
    +--------+-----------------+---------+

Thanks to @nusjzx for providing the fix to the button-wrapper in PR
MarkBind#86, in which his use of
'calc(100% - 32px)' provided a source of inspiration for this fix. His
fix in that PR is incorporated into this commit because without it, the
responsive design will not work.

An alternative fix considered was to use md.renderInline(). However,
md.renderInline() does not render markdown headings.

Another alternative fix was to insert the caret directly inside the
header content. However, after PR MarkBind#74, MarkBind#81 and MarkBind#83 were merged, new
problems continue to emerge.

These problems are reported as comments in these pages:
- MarkBind#74
- MarkBind#81
- MarkBind#83
- MarkBind/markbind#373
- MarkBind/markbind#383

As such, the PRs for this alternative fix has been reverted by the
previous commits before this commit.
@yamgent yamgent mentioned this pull request Jul 27, 2018
@Chng-Zhi-Xuan Chng-Zhi-Xuan deleted the 337-seamless-panel branch May 27, 2019 02:32
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Optimize heading layout for narrow-width seamless panels
4 participants