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

Inline Add Button Component #4270

Merged
merged 20 commits into from
Nov 24, 2023
Merged

Inline Add Button Component #4270

merged 20 commits into from
Nov 24, 2023

Conversation

margaree
Copy link
Contributor

@margaree margaree commented Nov 20, 2023

Rally Story

This is the initial work on the inline add button component. Its original purpose was for list but it now has the requirement of being a standalone component. I'll add comments throughout, but most of this is up for debate especially naming.

This does not include more detailed documentation on the README (followup story) and also doesn't include the ability to hide when not hovering (will do separately, didn't want to clutter this PR too much).

Also note that there will likely be a different icon use, which will also change on hover and focus.

Copy link
Contributor

Thanks for the PR! 🎉

We've deployed an automatic preview for this PR - you can see your changes here:

URL https://live.d2l.dev/prs/BrightspaceUI/core/pr-4270/

Note

The build needs to finish before your changes are deployed.
Changes to the PR will automatically update the instance.

/**
* A component for quickly adding items to a specific locaiton.
*/
class ButtonAdd extends FocusMixin(LocalizeCoreElement(LitElement)) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Currently have this as d2l-button-add. Including inline was thought to not be great because css-wise it's not actually inline. I looked up synonyms for inline but didn't fine anything I thought was great. Thoughts?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Also, I didn't use ButtonMixin. Let me know if there are other pieces of that which are important to a button that I'm missing.

Copy link
Member

Choose a reason for hiding this comment

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

I agree with not using ButtonMixin -- it just includes too many <button> attributes that would be confusing to handle here.

Comment on lines 14 to 30
static get properties() {
return {
/**
* The text to be shown in the tooltip as a hint when visible-text is false
* @type {string}
*/
label: { type: String },
/**
* The text to show in the button when visible-text is true
* @type {string}
*/
text: { type: String },
/**
* When true, show the button with icon and visible text. When false, only show icon.
* @type {boolean}
*/
visibleText: { type: Boolean, attribute: 'visible-text' }
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Most basic component states (demo page is also probably more useful for this):

  1. Default -> visible-text is false, component shows the divider line, an add icon, and a tooltip which contains whatever is in label (design refers to this as "hint") OR "Add Item" as a fallback
  2. Visible Text -> when visible-text is true, the component shows the divider, and in the centre is the plus icon and the text specified in text OR "Add Item" as a fallback.

text and label will not be used at the same time (the tooltip will not be shown if the text is visible and vice versa).

An aria description is potentially going to be used as well, I'll be discussing that more with design.

}

static get styles() {
return [labelStyles, css`
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 didn't use buttonStyles here as it felt like it complicated things more than made them easier. Let me know if I should be using that.

Comment on lines 110 to 119
<button class="d2l-label-text" id="${this._buttonId}">
<div class="line"></div>
<div class="content">
<d2l-icon icon="tier1:plus-default"></d2l-icon>
${this.visibleText
? html`<span>${text}</span>`
: html`<d2l-tooltip class="vdiff-target" offset="18" for="${this._buttonId}" for-type="label">${label}</d2l-tooltip>`}
</div>
</button>
`;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This implements its own button within rather than using subtle and/or icon button because we don't seem to want the focus/hover states that those provide.


_onClick() {
/** Dispatched when click happens */
this.dispatchEvent(new CustomEvent('d2l-button-add-click', {
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 made this a component specific click event rather than just firing up click since list consumers could be listening for this and just having a generic click seemed like it could cause confusion.

Copy link
Contributor

Choose a reason for hiding this comment

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

That makes sense. In that case, we probably want to call e.stopPropagation();. I'm kinda surprised we aren't doing that here.

Copy link
Member

Choose a reason for hiding this comment

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

I'd like to explore this a little bit... there are lots of components that fire click events, including just clicking on a <span> or whatever, so hoping we don't need to worry about this.

Either way, does it need to bubble and cross shadow root boundaries?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It would need to bubble and cross shadow root boundaries. The plan is that to use this consumers of list would have something like:
<d2l-list add-button>...</d2l-list>
and then the button-add component would appear after each list item. We don't want consumers to have to manage adding this component themselves after each item, and behaviour is designed to be consistent (i.e., wouldn't have some list items with button-add and others that don't have it, etc.).

All that to say, for the list case, consumers of list would want to listen for this event and then handle the click of the add button however they wish to.

Copy link
Member

Choose a reason for hiding this comment

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

Gotcha. In that case, another option: since list is going to be the one rendering <d2l-button-add>, it could wire up to its click event and then fire its own d2l-list-add-button-click event.

Copy link
Member

Choose a reason for hiding this comment

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

So consumers would go <d2l-list add-button @d2l-list-add-button-click="{...}">.

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 like that idea - I think that would be more straightforward for consumers.

lang/en.js Show resolved Hide resolved
@margaree
Copy link
Contributor Author

/**
* A component for quickly adding items to a specific locaiton.
*/
class ButtonAdd extends FocusMixin(LocalizeCoreElement(LitElement)) {
Copy link
Member

Choose a reason for hiding this comment

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

I agree with not using ButtonMixin -- it just includes too many <button> attributes that would be confusing to handle here.

components/button/button-add.js Outdated Show resolved Hide resolved
components/button/button-add.js Outdated Show resolved Hide resolved
components/button/button-add.js Outdated Show resolved Hide resolved

_onClick() {
/** Dispatched when click happens */
this.dispatchEvent(new CustomEvent('d2l-button-add-click', {
Copy link
Member

Choose a reason for hiding this comment

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

I'd like to explore this a little bit... there are lots of components that fire click events, including just clicking on a <span> or whatever, so hoping we don't need to worry about this.

Either way, does it need to bubble and cross shadow root boundaries?

components/button/test/button-add.axe.js Outdated Show resolved Hide resolved
components/button/test/button-add.test.js Outdated Show resolved Hide resolved
@margaree margaree marked this pull request as ready for review November 22, 2023 20:18
@margaree margaree requested a review from a team as a code owner November 22, 2023 20:18
label: { type: String },
/**
* The text to show in the button when visible-text is true
* When text-visible is true, the text to show in the button. When text-visible is false, the text to show in the tooltip.
* @type {string}
*/
text: { type: String },
Copy link
Member

Choose a reason for hiding this comment

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

Once the PropertyRequiredMixin stuff merges, this should likely use it.

components/button/test/button-add.vdiff.js Outdated Show resolved Hide resolved
lang/en.js Show resolved Hide resolved
Copy link
Member

@dlockhart dlockhart left a comment

Choose a reason for hiding this comment

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

Cool!

static get properties() {
return {
/**
* When text-visible is true, the text to show in the button. When text-visible is false, the text to show in the tooltip.
* @type {string}
*/
text: { type: String },
text: { type: String, required: true },
Copy link
Member

Choose a reason for hiding this comment

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

Yay!

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
@margaree margaree merged commit 6124689 into main Nov 24, 2023
5 checks passed
@margaree margaree deleted the inline-add-component branch November 24, 2023 15:34
Copy link

🎉 This PR is included in version 2.165.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

const id = !this.textVisible ? this._buttonId : undefined;

return html`
<button class="d2l-label-text" id="${ifDefined(id)}">
Copy link
Member

Choose a reason for hiding this comment

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

Just remembered randomly: make sure you set type="button" on this, otherwise it defaults to submit and will submit forms!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good catch, thanks! Will fix

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants