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

feat(Button): add border property to support border-radius changes #709

Merged
merged 7 commits into from
Dec 19, 2023
Merged
Show file tree
Hide file tree
Changes from 6 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
2,449 changes: 1,445 additions & 1,004 deletions package-lock.json

Large diffs are not rendered by default.

26 changes: 13 additions & 13 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -92,26 +92,26 @@
"@storybook/web-components-vite": "7.6.3",
"@swc-node/register": "1.6.8",
"@swc/cli": "0.1.63",
"@swc/core": "1.3.100",
"@swc/core": "1.3.101",
"@swc/helpers": "0.5.3",
"@testing-library/react": "14.1.2",
"@types/jest": "29.5.11",
"@types/mdx": "2.0.10",
"@types/node": "20.10.5",
"@types/react": "18.2.45",
"@types/react-dom": "18.2.18",
"@typescript-eslint/eslint-plugin": "6.11.0",
"@typescript-eslint/parser": "6.11.0",
"@typescript-eslint/eslint-plugin": "6.15.0",
"@typescript-eslint/parser": "6.15.0",
"autoprefixer": "10.4.16",
"babel-jest": "29.7.0",
"chromatic": "10.0.0",
"chromatic": "10.1.0",
"copy-webpack-plugin": "11.0.0",
"core-js": "3.33.3",
"core-js": "3.34.0",
"decompress": "4.2.1",
"eslint": "8.55.0",
"eslint": "8.56.0",
"eslint-config-prettier": "9.1.0",
"eslint-import-resolver-typescript": "3.6.1",
"eslint-plugin-import": "2.29.0",
"eslint-plugin-import": "2.29.1",
"eslint-plugin-jsx-a11y": "6.8.0",
"eslint-plugin-prettier": "5.0.1",
"eslint-plugin-react": "7.33.2",
Expand All @@ -122,30 +122,30 @@
"jest": "29.7.0",
"jest-environment-jsdom": "29.7.0",
"jsonc-eslint-parser": "2.4.0",
"lint-staged": "15.1.0",
"lint-staged": "15.2.0",
"lit-html": "3.1.0",
"nanospinner": "1.1.0",
"ng-packagr": "17.0.2",
"ng-packagr": "17.0.3",
"ngx-deploy-npm": "7.1.0",
"npm-run-all": "4.1.5",
"nx": "17.1.3",
"nx-stylelint": "17.0.1",
"nx-stylelint": "17.1.0",
"plop": "4.0.0",
"postcss": "8.4.32",
"postcss-import": "15.1.0",
"postcss-preset-env": "9.3.0",
"postcss-url": "10.1.3",
"prettier": "3.1.1",
"prettier-plugin-tailwindcss": "0.5.9",
"puppeteer": "21.5.2",
"puppeteer": "21.6.1",
"rimraf": "5.0.5",
"stencil-tailwind-plugin": "1.8.0",
"storybook": "7.6.3",
"stylelint": "15.11.0",
"stylelint-config-sass-guidelines": "10.0.0",
"stylelint-config-standard": "34.0.0",
"tailwindcss": "3.3.6",
"tailwindcss-theme-swapper": "0.8.0",
"tailwindcss": "3.3.7",
"tailwindcss-theme-swapper": "0.10.0",
"ts-jest": "29.1.1",
"ts-node": "10.9.2",
"typescript": "5.2.2",
Expand Down
4 changes: 2 additions & 2 deletions packages/beeq-tailwindcss/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
"module": "./index.esm.js",
"types": "./src/index.d.ts",
"peerDependencies": {
"tailwindcss": "^3.3.2",
"tailwindcss-theme-swapper": "^0.8.0"
"tailwindcss": "^3.3.7",
"tailwindcss-theme-swapper": "^0.10.0"
},
"repository": {
"type": "git",
Expand Down
12 changes: 10 additions & 2 deletions packages/beeq/src/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { TAccordionAppearance, TAccordionSize } from "./components/accordion/bq-
import { TAlertType } from "./components/alert/bq-alert.types";
import { TAvatarShape, TAvatarSize } from "./components/avatar/bq-avatar.types";
import { TBadgeSize } from "./components/badge/bq-badge.types";
import { TButtonAppearance, TButtonSize, TButtonType, TButtonVariant } from "./components/button/bq-button.types";
import { TButtonAppearance, TButtonBorderRadius, TButtonSize, TButtonType, TButtonVariant } from "./components/button/bq-button.types";
import { TDialogFooterAppearance, TDialogSize } from "./components/dialog/bq-dialog.types";
import { TDividerOrientation, TDividerStrokeLinecap, TDividerTitleAlignment } from "./components/divider/bq-divider.types";
import { FloatingUIPlacement } from "./services/interfaces";
Expand All @@ -32,7 +32,7 @@ export { TAccordionAppearance, TAccordionSize } from "./components/accordion/bq-
export { TAlertType } from "./components/alert/bq-alert.types";
export { TAvatarShape, TAvatarSize } from "./components/avatar/bq-avatar.types";
export { TBadgeSize } from "./components/badge/bq-badge.types";
export { TButtonAppearance, TButtonSize, TButtonType, TButtonVariant } from "./components/button/bq-button.types";
export { TButtonAppearance, TButtonBorderRadius, TButtonSize, TButtonType, TButtonVariant } from "./components/button/bq-button.types";
export { TDialogFooterAppearance, TDialogSize } from "./components/dialog/bq-dialog.types";
export { TDividerOrientation, TDividerStrokeLinecap, TDividerTitleAlignment } from "./components/divider/bq-divider.types";
export { FloatingUIPlacement } from "./services/interfaces";
Expand Down Expand Up @@ -202,6 +202,10 @@ export namespace Components {
* If `true`, it will make the button fit to its parent width.
*/
"block": boolean;
/**
* The corner radius of the button
*/
"border": TButtonBorderRadius;
/**
* If true, the button will be disabled (no interaction allowed)
*/
Expand Down Expand Up @@ -2017,6 +2021,10 @@ declare namespace LocalJSX {
* If `true`, it will make the button fit to its parent width.
*/
"block"?: boolean;
/**
* The corner radius of the button
*/
"border"?: TButtonBorderRadius;
/**
* If true, the button will be disabled (no interaction allowed)
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { Args, Meta, StoryObj } from '@storybook/web-components';
import { html } from 'lit-html';

import mdx from './bq-button.mdx';
import { BUTTON_APPEARANCE, BUTTON_SIZE, BUTTON_TYPE, BUTTON_VARIANT } from '../bq-button.types';
import { BUTTON_APPEARANCE, BUTTON_BORDER_RADIUS, BUTTON_SIZE, BUTTON_TYPE, BUTTON_VARIANT } from '../bq-button.types';

const meta: Meta = {
title: 'Components/Button',
Expand All @@ -15,6 +15,7 @@ const meta: Meta = {
argTypes: {
appearance: { control: 'select', options: [...BUTTON_APPEARANCE] },
block: { control: 'boolean' },
border: { control: 'select', options: [...BUTTON_BORDER_RADIUS] },
disabled: { control: 'boolean' },
href: { control: 'text' },
'justify-content': { control: 'select', options: ['left', 'center', 'right'] },
Expand All @@ -32,6 +33,7 @@ const meta: Meta = {
},
args: {
appearance: 'primary',
border: 'm',
block: false,
disabled: false,
href: undefined,
Expand All @@ -51,6 +53,7 @@ const Template = (args: Args) => html`
<bq-button
appearance=${args.appearance}
?block=${args.block}
border=${args.border}
?disabled=${args.disabled}
href=${args.href}
justify-content=${args['justify-content']}
Expand Down Expand Up @@ -122,6 +125,7 @@ export const IconLeft: Story = {
<bq-button
appearance=${args.appearance}
?block=${args.block}
border=${args.border}
?disabled=${args.disabled}
href=${args.href}
justify-content=${args['justify-content']}
Expand All @@ -144,6 +148,7 @@ export const IconRight: Story = {
render: (args) => html`
<bq-button
appearance=${args.appearance}
border=${args.border}
?block=${args.block}
?disabled=${args.disabled}
href=${args.href}
Expand All @@ -167,6 +172,7 @@ export const OnlyIcon: Story = {
render: (args) => html`
<bq-button
appearance=${args.appearance}
border=${args.border}
?block=${args.block}
?disabled=${args.disabled}
href=${args.href}
Expand Down
98 changes: 56 additions & 42 deletions packages/beeq/src/components/button/bq-button.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { Component, Element, Event, EventEmitter, h, Prop, State, Watch } from '@stencil/core';
import { Component, Element, Event, EventEmitter, h, Host, Prop, State, Watch } from '@stencil/core';

import {
BUTTON_APPEARANCE,
BUTTON_SIZE,
BUTTON_TYPE,
BUTTON_VARIANT,
TButtonAppearance,
TButtonBorderRadius,
TButtonSize,
TButtonType,
TButtonVariant,
Expand All @@ -15,9 +16,9 @@ import { hasSlotContent, isDefined, isNil, validatePropValue } from '../../share
/**
* Buttons are designed for users to take action on a page or a screen.
*
* @part button - The HTML button used under the hood.
* @part button - The `<a>` or `<button>` HTML element used under the hood.
* @part prefix - The `<span>` tag element that acts as prefix container.
* @part label - The `<span>` tag element that renderd the text of the button.
* @part label - The `<span>` tag element that renders the text of the button.
* @part suffix - The `<span>` tag element that acts as suffix container.
*/
@Component({
Expand Down Expand Up @@ -53,6 +54,9 @@ export class BqButton {
/** If `true`, it will make the button fit to its parent width. */
@Prop({ reflect: true }) block: boolean = false;

/** The corner radius of the button */
@Prop({ reflect: true }) border: TButtonBorderRadius = 'm';

/** If true, the button will be disabled (no interaction allowed) */
@Prop() disabled = false;

Expand Down Expand Up @@ -179,47 +183,57 @@ export class BqButton {
render() {
const isLink = isDefined(this.href);
const TagElem = isLink ? 'a' : 'button';
const style = {
...(this.border && { '--bq-button--border-radius': `var(--bq-radius--${this.border})` }),
};

return (
<TagElem
class={{
'bq-button': true,
[`bq-button--${this.appearance}`]: true,
[`content-${this.justifyContent}`]: true,
[`${this.variant}`]: true,
[`${this.size}`]: true,
block: this.block,
disabled: this.disabled,
'has-prefix': this.hasPrefix,
'has-suffix': this.hasSuffix,
loading: this.loading,
}}
aria-disabled={this.disabled ? 'true' : 'false'}
disabled={this.disabled}
download={isLink ? this.download : undefined}
href={isLink ? this.href : undefined}
part="button"
rel={isLink && this.target ? 'noreferrer noopener' : undefined}
target={isLink ? this.target : undefined}
type={this.type}
tabIndex={this.disabled ? -1 : 0}
onBlur={this.handleBlur}
onFocus={this.handleFocus}
onClick={this.handleClick}
>
<span class="bq-button__prefix" ref={(spanElem) => (this.prefixElem = spanElem)} part="prefix">
<slot name="prefix" onSlotchange={this.handleSlotChange} />
</span>
<span class="bq-button__label" part="label">
<slot />
</span>
<span class="bq-button__suffix" ref={(spanElem) => (this.suffixElem = spanElem)} part="suffix">
<slot name="suffix" onSlotchange={this.handleSlotChange} />
</span>
{this.loading && (
<bq-icon class="bq-button__loader" name="spinner-gap" role="img" title={`${this.appearance} button loader`} />
)}
</TagElem>
<Host style={style}>
<TagElem
class={{
'bq-button': true,
[`bq-button--${this.appearance}`]: true,
[`content-${this.justifyContent}`]: true,
[`${this.variant}`]: true,
[`${this.size}`]: true,
block: this.block,
disabled: this.disabled,
'has-prefix': this.hasPrefix,
'has-suffix': this.hasSuffix,
loading: this.loading,
}}
aria-disabled={this.disabled ? 'true' : 'false'}
disabled={this.disabled}
download={isLink ? this.download : undefined}
href={isLink ? this.href : undefined}
part="button"
rel={isLink && this.target ? 'noreferrer noopener' : undefined}
target={isLink ? this.target : undefined}
type={this.type}
tabIndex={this.disabled ? -1 : 0}
onBlur={this.handleBlur}
onFocus={this.handleFocus}
onClick={this.handleClick}
>
<span class="bq-button__prefix" ref={(spanElem) => (this.prefixElem = spanElem)} part="prefix">
<slot name="prefix" onSlotchange={this.handleSlotChange} />
</span>
<span class="bq-button__label" part="label">
<slot />
</span>
<span class="bq-button__suffix" ref={(spanElem) => (this.suffixElem = spanElem)} part="suffix">
<slot name="suffix" onSlotchange={this.handleSlotChange} />
</span>
{this.loading && (
<bq-icon
class="bq-button__loader"
name="spinner-gap"
role="img"
title={`${this.appearance} button loader`}
/>
)}
</TagElem>
</Host>
);
}
}
3 changes: 3 additions & 0 deletions packages/beeq/src/components/button/bq-button.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,6 @@ export type TButtonAppearance = (typeof BUTTON_APPEARANCE)[number];

export const BUTTON_VARIANT = ['standard', 'ghost', 'danger'] as const;
export type TButtonVariant = (typeof BUTTON_VARIANT)[number];

export const BUTTON_BORDER_RADIUS = ['none', 'xs2', 'xs', 's', 'm', 'l', 'full'] as const;
export type TButtonBorderRadius = (typeof BUTTON_BORDER_RADIUS)[number];
Loading