Skip to content

Commit

Permalink
fix(button): remove basebutton (#1277)
Browse files Browse the repository at this point in the history
  • Loading branch information
bennypowers authored Oct 23, 2023
1 parent 6a87885 commit fcf22f0
Show file tree
Hide file tree
Showing 3 changed files with 169 additions and 62 deletions.
4 changes: 4 additions & 0 deletions .changeset/button-remove-base.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
"@rhds/elements": patch
---
`<rh-button>`: remove dependency on `@patternfly/elements`
137 changes: 90 additions & 47 deletions elements/rh-button/rh-button.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,87 @@
:host {
display: inline-block;
height: max-content;
}

:host([hidden]) {
display: none !important;
}

[hidden] {
display: none !important;
}

button {
cursor: pointer;
position: relative;
font-family: inherit;
border-width: 0;
border-style: solid;
border-radius: var(--rh-border-radius-default, 3px);
color: var(--_color);
background-color: var(--_background-color);
font-size: var(--rh-font-size-body-text-md, 1rem);
font-weight: var(--rh-font-weight-body-text-regular, 400);
line-height: var(--rh-line-height-body-text, 1.5);
padding-block: var(--rh-space-sm, 6px);
padding-inline: var(--rh-space-lg, 16px);
outline-offset: var(--rh-length-4xs, 1px);

--_color: var(--_default-color, var(--_primary-color));
--_background-color: var(--_default-background-color, var(--_primary-background-color));
--_border-color: var(--_default-border-color, var(--_primary-border-color));
--_border-width: var(--_default-border-width, var(--_primary-border-width));
}

button:after {
position: absolute;
inset: 0;
content: "";
border-style: solid;
border-color: var(--_border-color);
border-width: var(--_border-width);
border-radius: var(--rh-border-radius-default, 3px);
}

:host(:is(:disabled, [aria-disabled="true"])),
:host(:is(:disabled, [aria-disabled="true"])) #container,
:host(:is(:disabled, [aria-disabled="true"])) button,
:host(:is(:disabled, [aria-disabled="true"])[danger]) button,
:host(:is(:disabled, [aria-disabled="true"])[variant="link"]) button {
pointer-events: none;
cursor: default;
}

[part="icon"] {
display: none;
pointer-events: none;
}

.hasIcon {
position: relative;
display: flex;
align-items: center;
}

.hasIcon [part="icon"] {
display: inline-flex;
align-items: center;
position: absolute;
width: 16px;
}

[part="icon"] ::slotted(*) {
width: 16px;
max-width: 16px;
height: 16px;
max-height: 16px;
}

.hasIcon button {
position: absolute;
inset: 0;
}

.light {
/* PRIMARY */
--_primary-color: var(--rh-color-text-primary-on-dark, #ffffff);
Expand Down Expand Up @@ -198,10 +282,7 @@
display: contents;
}

:host([hidden]) {
display: none !important;
}

:host([hidden]),
[hidden] {
display: none !important;
}
Expand All @@ -210,49 +291,6 @@ rh-icon {
color: currentcolor;
}

button {
cursor: pointer;
position: relative;
color: var(--_color);
background-color: var(--_background-color);
font-family: inherit;
font-size: var(--rh-font-size-body-text-md, 1rem);
font-weight: var(--rh-font-weight-body-text-regular, 400);
line-height: var(--rh-line-height-body-text, 1.5);
padding-block: var(--rh-space-sm, 6px);
padding-inline: var(--rh-space-lg, 16px);
border-width: 0;
border-style: solid;
border-radius: var(--rh-border-radius-default, 3px);
outline-offset: var(--rh-length-4xs, 1px);

--_color: var(--_default-color, var(--_primary-color));
--_background-color: var(--_default-background-color, var(--_primary-background-color));
--_border-color: var(--_default-border-color, var(--_primary-border-color));
--_border-width: var(--_default-border-width, var(--_primary-border-width));
}

button:after {
position: absolute;
inset: 0;
content: "";
border-style: solid;
border-color: var(--_border-color);
border-width: var(--_border-width);
border-radius: var(--rh-border-radius-default, 3px);
}

[part="icon"] {
display: none;
pointer-events: none;
}

.hasIcon {
position: relative;
display: flex;
align-items: center;
}

/******************************
* *
* PRIMARY *
Expand Down Expand Up @@ -505,3 +543,8 @@ button[disabled] {
--_hover-background-color: transparent;
--_hover-border-color: var(--_danger-hover-border-color);
}

:host(:not([disabled])) .hasIcon [part="icon"] {
cursor: pointer;
}

90 changes: 75 additions & 15 deletions elements/rh-button/rh-button.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,51 @@
import { html } from 'lit';
import { LitElement, html, type TemplateResult } from 'lit';
import { customElement } from 'lit/decorators/custom-element.js';
import { property } from 'lit/decorators/property.js';
import { classMap } from 'lit/directives/class-map.js';
import { ifDefined } from 'lit/directives/if-defined.js';

import { colorContextConsumer, type ColorTheme } from '../../lib/context/color/consumer.js';

import { BaseButton } from '@patternfly/elements/pf-button/BaseButton.js';
import { InternalsController } from '@patternfly/pfe-core/controllers/internals-controller.js';

import styles from './rh-button.css';

/**
* A button is clickable text or an icon that triggers an action on the page or in the background. Depending on the action, content, and hierarchy, a button can be used on its own or grouped with other buttons.
*
* @summary Triggers actions on the page or in the background
* @summary Triggers actions on the page or in the background
*
* @csspart button - Internal button element
* @csspart icon - Container for the icon slot
*
* @slot icon - Contains the button's icon or state indicator, e.g. a spinner.
* @slot - Contains button text
*/
@customElement('rh-button')
export class RhButton extends BaseButton {
export class RhButton extends LitElement {
static readonly styles = [styles];

static readonly formAssociated = true;

static readonly shadowRootOptions: ShadowRootInit = { ...LitElement.shadowRootOptions, delegatesFocus: true };

/** Disables the button */
@property({ reflect: true, type: Boolean }) disabled = false;

@property({ reflect: true }) type?: 'button' | 'submit' | 'reset';

/** Accessible name for the button, use when the button does not have slotted text */
@property() label?: string;

/** Form value for the button */
@property() value?: string;

/** Form name for the button */
@property() name?: string;

/** Shorthand for the `icon` slot, the value is icon name */
@property() icon?: string;

/**
* Changes the style of the button.
* - Primary: Used for the most important call to action on a page. Try to
Expand All @@ -34,34 +58,70 @@ export class RhButton extends BaseButton {
*/
@property({ reflect: true }) variant: 'primary' | 'secondary' | 'tertiary' | 'close' | 'play' = 'primary';

/** @deprecated The size property is not currently used */
declare size: string;

/**
* When set, indicates that the button performs a destructive action
* Use danger buttons for actions a user can take that are potentially
* destructive or difficult/impossible to undo, like deleting or removing
* user data.
*/
@property({ type: Boolean, reflect: true }) danger = false;

@colorContextConsumer() private on?: ColorTheme;

get #variant() { return this.variant?.toLowerCase(); }
get #hasIcon() { return !!this.icon; }

#internals = new InternalsController(this);

override willUpdate() {
switch (this.#variant) {
const variant = this.variant.toLowerCase();
switch (variant) {
case 'close':
case 'play':
this.icon = this.#variant;
this.icon = variant;
break;
}
}

override render() {
const { on = 'light' } = this;
return html`<div id="rhds-container" class="${classMap({ [on]: true })}">${super.render()}</div>`;
const hasIcon = this.#hasIcon;
return html`
<button aria-label="${ifDefined(this.label)}"
class="${classMap({ hasIcon, [on]: !!on })}"
part="button"
type="${ifDefined(this.type)}"
value="${ifDefined(this.value)}"
@click="${this.#onClick}"
?disabled="${this.disabled || this.#internals.formDisabled}">
<slot id="icon" part="icon" aria-hidden="true" name="icon">${this.#renderDefaultIcon()}</slot>
<slot id="text" aria-hidden=${String(!!this.label) as 'true' | 'false'}></slot>
</button>
`;
}

protected async formDisabledCallback() {
await this.updateComplete;
this.requestUpdate();
}

#onClick() {
switch (this.type) {
case 'reset':
return this.#internals.reset();
default:
return this.#internals.submit();
}
}

protected renderDefaultIcon() {
switch (this.#variant) {
/**
* Fallback content for the icon slot. When the `icon` attribute is set, it
* should render an icon corresponding to the value.
*
* @example ```html
* <base-icon icon=${this.icon}></base-icon>
* ```
*/
#renderDefaultIcon(): TemplateResult | string {
switch (this.variant.toLowerCase()) {
// TODO: revisit when rh-icon is ready
// return html`<rh-icon icon=${this.variant}></rh-icon>`;
case 'close':
Expand All @@ -77,7 +137,7 @@ export class RhButton extends BaseButton {
</svg>
`;
default:
return '' as ReturnType<this['render']>;
return '';
}
}
}
Expand Down

0 comments on commit fcf22f0

Please sign in to comment.