Skip to content

Commit

Permalink
feat: Inline-button-create support for HREF (#720)
Browse files Browse the repository at this point in the history
* add href and target

* re position the create-circle

* no blur and better story

---------

Co-authored-by: Jacob Overgaard <[email protected]>
Co-authored-by: Niels Lyngsø <[email protected]>
  • Loading branch information
3 people authored Jan 23, 2024
1 parent 7cd20db commit 7d8affd
Show file tree
Hide file tree
Showing 2 changed files with 131 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { defineElement } from '@umbraco-ui/uui-base/lib/registration';
import { css, html, LitElement } from 'lit';
import { property, state } from 'lit/decorators.js';
import { styleMap } from 'lit/directives/style-map.js';
import { ifDefined } from 'lit/directives/if-defined.js';

import { UUIButtonInlineCreateEvent } from './UUIButtonInlineCreateEvent';

Expand Down Expand Up @@ -37,44 +38,89 @@ export class UUIButtonInlineCreateElement extends LitElement {
@property({ type: Boolean, reflect: true })
vertical = false;

/**
* Set an href, this will turns the button into an anchor tag.
* @type {string}
* @attr
* @default undefined
*/
@property({ type: String })
public href?: string;

/**
* Set an anchor tag target, only used when using href.
* @type {string}
* @attr
* @default undefined
*/
@property({ type: String })
public target?: '_blank' | '_parent' | '_self' | '_top';

private _onMouseMove(e: MouseEvent) {
this._position = this.vertical ? e.offsetY : e.offsetX;
this._position = (this.vertical ? e.offsetY : e.offsetX) - 5;
}

private _handleClick(e: MouseEvent) {
e.preventDefault();
e.stopImmediatePropagation();

// We do not want to focus the button after click.
(e.target as any)?.blur?.();

this.dispatchEvent(
new UUIButtonInlineCreateEvent(UUIButtonInlineCreateEvent.CLICK)
);
}

render() {
#renderContent() {
return html`
<div
id="plus"
style=${styleMap({
left: this.vertical ? '' : this._position + 'px',
top: this.vertical ? this._position + 'px' : '',
})}>
<svg
id="plus-icon"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 512 512">
<path
d="M420.592 214.291H296.104V89.804h-83.102v124.487H88.518v83.104h124.484v124.488h83.102V297.395h124.488z" />
</svg>
</div>
`;
}

#renderLink() {
return html`<a
id="button-wrapper"
@mousemove=${this._onMouseMove}
href=${ifDefined(this.href)}
target=${ifDefined(this.target || undefined)}
rel=${ifDefined(
this.target === '_blank' ? 'noopener noreferrer' : undefined
)}
aria-label=${this.label ? this.label : 'create new element'}>
${this.#renderContent()}
</a>`;
}

#renderButton() {
return html`
<button
id="button-wrapper"
@mousemove=${this._onMouseMove}
@click=${this._handleClick}
aria-label=${this.label ? this.label : 'create new element'}>
<div
id="plus"
style=${styleMap({
left: this.vertical ? '' : this._position + 'px',
top: this.vertical ? this._position + 'px' : '',
})}>
<svg
id="plus-icon"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 512 512">
<path
d="M420.592 214.291H296.104V89.804h-83.102v124.487H88.518v83.104h124.484v124.488h83.102V297.395h124.488z" />
</svg>
</div>
${this.#renderContent()}
</button>
`;
}

render() {
return this.href ? this.#renderLink() : this.#renderButton();
}

static styles = [
UUIBlinkKeyframes,
css`
Expand Down Expand Up @@ -205,12 +251,12 @@ export class UUIButtonInlineCreateElement extends LitElement {
}
:host(:not([vertical])) #plus {
margin-left: -21px;
margin-left: -18px;
}
:host([vertical]) #plus {
left: -4px;
margin-top: -21px;
margin-top: -18px;
}
#button-wrapper:focus #plus {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export default {

const insertBox = (e: any) => {
const div = document.createElement('div');
const labelDiv = document.createElement('div');
const label = document.createElement('div');
const buttonInline = document.createElement('uui-button-inline-create');
buttonInline.addEventListener('click', insertBox);
Expand All @@ -33,18 +34,31 @@ const insertBox = (e: any) => {

if (e.target.vertical) {
buttonInline.setAttribute('vertical', 'true');
div.style.display = 'grid';
div.style.gridTemplateColumns = '1fr auto';
labelDiv.style.display = 'grid';
labelDiv.style.gridTemplateColumns = '1fr auto';
buttonInline.style.position = 'absolute';
buttonInline.style.right = '0';
buttonInline.style.top = '0';
} else {
labelDiv.style.display = 'block';
}

div.appendChild(label);
div.appendChild(buttonInline);
labelDiv.appendChild(label);
div.appendChild(labelDiv);

e.target.parentElement.insertAdjacentElement('afterend', div);
e.target.parentElement.parentElement.insertBefore(
div,
e.target.parentElement
);
};

const createBox = (vertical: boolean) =>
html` <div style="position:relative;">
<uui-button-inline-create
style="${vertical ? 'position: absolute; right: 0; top:0;' : ''}"
?vertical=${vertical}
@click=${insertBox}></uui-button-inline-create>
<div
style="
${vertical
Expand All @@ -55,17 +69,21 @@ const createBox = (vertical: boolean) =>
${GetRandomUmbracoWord()}
</div>
</div>
<uui-button-inline-create
style="${vertical ? 'position: absolute; right: 0; top:0;' : ''}"
?vertical=${vertical}
@click=${insertBox}></uui-button-inline-create>
</div>`;

const createBoxes = (count: number, vertical = false) => {
const boxes: TemplateResult<1>[] = [];
for (let index = 0; index < count; index++) {
boxes.push(createBox(vertical));
}
boxes.push(html`
<div style="position:relative;">
<uui-button-inline-create
style="${vertical ? 'position: absolute; right: 0; top:0;' : ''}"
?vertical=${vertical}
@click=${insertBox}></uui-button-inline-create>
</div>
`);
return boxes;
};

Expand All @@ -80,6 +98,7 @@ AAAOverview.parameters = {
source: {
code: `
<div>
<uui-button-inline-create label="Create Item"></uui-button-inline-create>
<div style="padding: 10px;">Item 1</div>
<uui-button-inline-create label="Create Item"></uui-button-inline-create>
<div style="padding: 10px;">Item 2</div>
Expand All @@ -102,6 +121,7 @@ Vertical.parameters = {
source: {
code: `
<div>
<uui-button-inline-create label="Create Item"></uui-button-inline-create>
<div style="padding: 10px;">Item 1</div>
<uui-button-inline-create label="Create Item"></uui-button-inline-create>
<div style="padding: 10px;">Item 2</div>
Expand All @@ -124,6 +144,7 @@ Horizontal.parameters = {
source: {
code: `
<div style="'display: grid; grid-template-columns: 1fr auto;">
<uui-button-inline-create label="Create Item"></uui-button-inline-create>
<div style="padding: 10px;">Item 1</div>
<uui-button-inline-create label="Create Item"></uui-button-inline-create>
<div style="padding: 10px;">Item 2</div>
Expand All @@ -135,3 +156,41 @@ Horizontal.parameters = {
},
},
};

export const Href: Story = () =>
html` <h3>Using HREF</h3>
<div id="container" style="max-width: 500px; border: 1px solid grey">
<uui-button-inline-create
href="#0"
label="Create Item"></uui-button-inline-create>
<div style="padding: 10px;">Item 1</div>
<uui-button-inline-create
href="#1"
label="Create Item"></uui-button-inline-create>
<div style="padding: 10px;">Item 2</div>
<uui-button-inline-create
href="#2"
label="Create Item"></uui-button-inline-create>
<div style="padding: 10px;">Item 3</div>
<uui-button-inline-create
href="#3"
label="Create Item"></uui-button-inline-create>
</div>`;
AAAOverview.storyName = 'Overview';
AAAOverview.parameters = {
docs: {
source: {
code: `
<div>
<uui-button-inline-create href="#0" label="Create Item"></uui-button-inline-create>
<div style="padding: 10px;">Item 1</div>
<uui-button-inline-create href="#1" label="Create Item"></uui-button-inline-create>
<div style="padding: 10px;">Item 2</div>
<uui-button-inline-create href="#2" label="Create Item"></uui-button-inline-create>
<div style="padding: 10px;">Item 3</div>
<uui-button-inline-create href="#3" label="Create Item"></uui-button-inline-create>
</div>
`,
},
},
};

0 comments on commit 7d8affd

Please sign in to comment.