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

adds icon, icon-before, icon-after properties #786

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 47 additions & 4 deletions packages/uui-button/lib/uui-button.element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,30 @@ export class UUIButtonElement extends UUIFormControlMixin(
@property({ type: String, reflect: true })
type: UUIButtonType = 'button';

/**
* Optionally set an icon to render before the label
* @attr
* @default undefined;
*/
@property({ reflect: true, attribute: 'icon-before' })
iconBefore?: string;

/**
* Optionally set an icon to render after the label
* @attr
* @default undefined;
*/
@property({ reflect: true, attribute: 'icon-after' })
iconAfer?: string;

/**
* Optionally set an icon without positioning. Renders as icon-before.
* @attr
* @default undefined;
*/
@property({ reflect: true })
icon?: string;

/**
* Disables the button, changes the looks of it and prevents if from emitting the click event
* @type {boolean}
Expand Down Expand Up @@ -220,6 +244,13 @@ export class UUIButtonElement extends UUIFormControlMixin(
return html`<div id="state">${element}</div>`;
}

renderIcon(icon?: string) {
if (!icon) return null;

demandCustomElement(this, 'uui-icon');
return html`<uui-icon class="icon" name=${icon}></uui-icon>`;
}

render() {
return this.href
? html`
Expand All @@ -231,7 +262,9 @@ export class UUIButtonElement extends UUIFormControlMixin(
rel=${ifDefined(
this.target === '_blank' ? 'noopener noreferrer' : undefined,
)}>
${this.renderState()} ${this.renderLabel()}
${this.renderState()}
${this.renderIcon(this.icon ?? this.iconBefore)}
${this.renderLabel()} ${this.renderIcon(this.iconAfer)}
<slot name="extra"></slot>
</a>
`
Expand All @@ -240,7 +273,9 @@ export class UUIButtonElement extends UUIFormControlMixin(
id="button"
?disabled=${this.disabled}
aria-label=${ifDefined(this.label)}>
${this.renderState()} ${this.renderLabel()}
${this.renderState()}
${this.renderIcon(this.icon ?? this.iconBefore)}
${this.renderLabel()} ${this.renderIcon(this.iconAfer)}
<slot name="extra"></slot>
</button>
`;
Expand Down Expand Up @@ -271,7 +306,8 @@ export class UUIButtonElement extends UUIFormControlMixin(
color 80ms;
}

:host([compact]) {
:host([compact]),
:host([icon]) {
--uui-button-padding-left-factor: 1;
--uui-button-padding-right-factor: 1;
--uui-button-padding-top-factor: 0;
Expand All @@ -283,7 +319,9 @@ export class UUIButtonElement extends UUIFormControlMixin(
display: block;
transition: opacity 120ms;
}
:host([state]:not([state=''])) .label {

:host([state]:not([state=''])) .label,
:host([state]:not([state=''])) .icon {
opacity: 0;
}

Expand Down Expand Up @@ -349,6 +387,11 @@ export class UUIButtonElement extends UUIFormControlMixin(
animation: ${UUIHorizontalShakeAnimationValue};
}

.label:not(:empty) ~ .icon,
.icon + .label:not(:empty) {
margin-left: var(--uui-size-2);
}

/* ANIMATIONS */
@keyframes fadeIn {
0% {
Expand Down
50 changes: 48 additions & 2 deletions packages/uui-button/lib/uui-button.story.ts
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@ LooksAndColors.parameters = {
},
};

export const WithIcon = () => html`
export const WithSlottedIcon = () => html`
<uui-icon-registry-essential>
<uui-button look="primary" color="danger" label="A11Y proper label">
<uui-icon .name=${'favorite'}></uui-icon>
Expand All @@ -314,7 +314,7 @@ export const WithIcon = () => html`
</uui-button>
</uui-icon-registry-essential>
`;
WithIcon.parameters = {
WithSlottedIcon.parameters = {
docs: {
source: {
code: `
Expand All @@ -323,6 +323,52 @@ WithIcon.parameters = {
},
};

export const WithIconProperty = () => html`
<uui-icon-registry-essential>
<uui-button
look="primary"
color="danger"
icon="favorite"
label="A11Y proper label">
</uui-button>
<br />
<br />
<uui-button
look="primary"
color="default"
icon-before="favorite"
label="Button with icon"></uui-button>
<br />
<br />
<uui-button
look="primary"
color="positive"
icon-after="favorite"
label="Button with icon"></uui-button>
<br />
<br />
<uui-button
look="primary"
color="warning"
icon-before="check"
icon-after="favorite"
label="Button with icon"></uui-button>
<br />
<br />
<p>
The 'compact' attribute is not required when using the 'icon' property.
</p>
</uui-icon-registry-essential>
`;
WithIconProperty.parameters = {
docs: {
source: {
code: `
<uui-button look="primary" icon="alert" label="A11Y proper label">Button Label</uui-button>`,
},
},
};

export const WaitingState = Template.bind({});
WaitingState.args = { state: 'waiting' };
WaitingState.parameters = {
Expand Down
Loading