Skip to content

Commit

Permalink
feat(button): add textAlign attribute
Browse files Browse the repository at this point in the history
  • Loading branch information
skhamvon authored and dpellier committed Sep 7, 2023
1 parent 9bc48db commit 23f544d
Show file tree
Hide file tree
Showing 14 changed files with 159 additions and 26 deletions.
36 changes: 22 additions & 14 deletions packages/components/button/documentation/specifications/spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,21 @@
## Interfaces

### OdsButtonAttributes
|name | Type | Required | Default | Description|
|---|---|:---:|---|---|
|**`circle`** | _boolean_ | | | use a circle shape|
|**`color`** | `OdsThemeColorIntent` | | | main color: see component principles|
|**`contrasted`** | _boolean_ | | | contrasted or not: see component principles|
|**`disabled`** | _boolean_ | | | disabled or not: see component principles|
|**`download`** | _string_ | | | Button with href as download source|
|**`flex`** | _boolean_ | | | full width or not: see component principles|
|**`href`** | _string_ | | | use a button as a link with `<a>` element|
|**`rel`** | `OdsHTMLAnchorElementRel` | | | Button with href relationship|
|**`size`** | `OdsButtonSize` | | | size: see component principles|
|**`target`** | `OdsHTMLAnchorElementTarget` | | | link target if we are in a link-mode (using `href` attribute)|
|**`type`** | `OdsButtonType` | | | type of the vanilla button|
|**`variant`** | `OdsButtonVariant` | | | used design aspect|
| name | Type | Required | Default | Description |
|------------------|------------------------------|:---:|---|------------------------------------|
| **`circle`** | _boolean_ | | | use a circle shape |
| **`color`** | `OdsThemeColorIntent` | | | main color: see component principles |
| **`contrasted`** | _boolean_ | | | contrasted or not: see component principles |
| **`disabled`** | _boolean_ | | | disabled or not: see component principles |
| **`download`** | _string_ | | | Button with href as download source |
| **`flex`** | _boolean_ | | | full width or not: see component principles |
| **`href`** | _string_ | | | use a button as a link with `<a>` element |
| **`rel`** | `OdsHTMLAnchorElementRel` | | | Button with href relationship |
| **`size`** | `OdsButtonSize` | | | size: see component principles |
| **`target`** | `OdsHTMLAnchorElementTarget` | | | link target if we are in a link-mode (using `href` attribute) |
| **`textAlign`** | `OdsButtonTextAlign` | | | position of text |
| **`type`** | `OdsButtonType` | | | type of the vanilla button |
| **`variant`** | `OdsButtonVariant` | | | used design aspect |

### OdsButtonBehavior
|name | Type | Required | Default | Description|
Expand Down Expand Up @@ -51,6 +52,13 @@
| `ghost` |
| `stroked` |

### OdsButtonTextAlign
| |
|:--------:|
| `center` |
| `end` |
| `start` |

## Classes

### OdsButtonController
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
enum ODS_BUTTON_TEXTALIGN {
center = 'center',
start = 'start',
end = 'end',
}

const ODS_BUTTON_TEXTALIGNS = Object.freeze(Object.values(ODS_BUTTON_TEXTALIGN));

export {
ODS_BUTTON_TEXTALIGN,
ODS_BUTTON_TEXTALIGNS,
};
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { OdsButtonAttribute } from '../interfaces/attributes';
import { ODS_THEME_COLOR_INTENT } from '@ovhcloud/ods-common-theming';
import { ODS_BUTTON_SIZE } from './button-size';
import { ODS_BUTTON_TEXTALIGN } from './button-textalign';
import { ODS_BUTTON_TYPE } from './button-type';
import { ODS_BUTTON_VARIANT } from './button-variant';

Expand All @@ -15,6 +16,7 @@ const DEFAULT_ATTRIBUTE: OdsButtonAttribute = Object.freeze({
rel: undefined,
size: ODS_BUTTON_SIZE.md,
target: undefined,
textAlign: ODS_BUTTON_TEXTALIGN.center,
type: ODS_BUTTON_TYPE.button,
variant: ODS_BUTTON_VARIANT.flat,
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { OdsLogger, OdsWarnComponentAttribute } from '@ovhcloud/ods-common-core'
import { ODS_THEME_COLOR_INTENT } from '@ovhcloud/ods-common-theming';
import { ODS_BUTTON_SIZE } from '../constants/button-size';
import { ODS_BUTTON_VARIANT } from '../constants/button-variant';
import { ODS_BUTTON_TEXTALIGN } from '../constants/button-textalign';

/**
* common controller logic for button component used by the different implementations.
Expand Down Expand Up @@ -40,6 +41,12 @@ class OdsButtonController {
attributeName: 'variant',
attribute: this.component.variant
});
OdsWarnComponentAttribute<ODS_BUTTON_TEXTALIGN, OsdsButton>({
logger,
attributeValues: ODS_BUTTON_TEXTALIGN as Record<string, unknown>,
attributeName: 'textAlign',
attribute: this.component.textAlign
});
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import type { ODS_THEME_COLOR_INTENT } from '@ovhcloud/ods-common-theming';
import type { ODS_BUTTON_SIZE } from '../constants/button-size';
import type { ODS_BUTTON_TYPE } from '../constants/button-type';
import type { ODS_BUTTON_VARIANT } from '../constants/button-variant';
import type { ODS_BUTTON_TEXTALIGN } from '../constants/button-textalign';

interface OdsButtonAttribute {
/** use a circle shape */
Expand All @@ -26,6 +27,8 @@ interface OdsButtonAttribute {
/** link target if we are in a link-mode (using `href` attribute) */
target?: OdsHTMLAnchorElementTarget;
/** type of the vanilla button */

textAlign?: ODS_BUTTON_TEXTALIGN;
type?: ODS_BUTTON_TYPE;
/** used design aspect */
variant?: ODS_BUTTON_VARIANT;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { odsComponentAttributes2StringAttributes, odsStringAttributes2Str } from
import { ODS_THEME_COLOR_INTENTS } from '@ovhcloud/ods-common-theming';
import { ODS_BUTTON_SIZES } from './constants/button-size';
import { ODS_BUTTON_VARIANTS } from './constants/button-variant';
import { ODS_BUTTON_TEXTALIGNS } from './constants/button-textalign';
import { DEFAULT_ATTRIBUTE } from './constants/default-attributes';

describe('e2e:osds-button', () => {
Expand All @@ -31,12 +32,14 @@ describe('e2e:osds-button', () => {
ODS_THEME_COLOR_INTENTS.forEach((color) => {
ODS_BUTTON_SIZES.forEach((size) => {
ODS_BUTTON_VARIANTS.forEach((variant) => {
it([color, variant, size, action, behaviour].join(', '), async () => {
ODS_BUTTON_TEXTALIGNS.forEach((textAlign) => {
it([color, variant, size, action, behaviour, textAlign].join(', '), async () => {
await setup({
attributes: {
color,
size,
variant,
textAlign,
},
html: `Button`
});
Expand All @@ -51,7 +54,8 @@ describe('e2e:osds-button', () => {
await page.setViewport({ width: 600, height: 600 });
const results = await page.compareScreenshot('button', { fullPage: false, omitBackground: true });
expect(results).toMatchScreenshot({ allowableMismatchedRatio: 0 })
});
});
})
});

it(`${[color, size, action, behaviour].join(', ')} link`, async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { newE2EPage } from '@stencil/core/testing';
import { odsComponentAttributes2StringAttributes, odsStringAttributes2Str } from '@ovhcloud/ods-common-testing';
import { ODS_THEME_COLOR_INTENT } from '@ovhcloud/ods-common-theming';
import { ODS_BUTTON_SIZE } from './constants/button-size';
import { ODS_BUTTON_TEXTALIGN } from './constants/button-textalign';
import { ODS_BUTTON_TYPE } from './constants/button-type';
import { ODS_BUTTON_VARIANT } from './constants/button-variant';
import { DEFAULT_ATTRIBUTE } from './constants/default-attributes';
Expand Down Expand Up @@ -75,6 +76,10 @@ describe('e2e:osds-button', () => {
expect(await el.getProperty('variant')).toBe(DEFAULT_ATTRIBUTE.variant);
});

it('should have a default textAlign', async () => {
expect(await el.getProperty('textAlign')).toBe(DEFAULT_ATTRIBUTE.textAlign);
});

it('should have a default color', async () => {
expect(await el.getProperty('color')).toBe(DEFAULT_ATTRIBUTE.color);
});
Expand Down Expand Up @@ -190,6 +195,23 @@ describe('e2e:osds-button', () => {
});
});

describe('textAlign', () => {
it('should have a textAlign to center', async () => {
await setup({ attributes: { textAlign: ODS_BUTTON_TEXTALIGN.center } });
expect(await el.getProperty('textAlign')).toBe(ODS_BUTTON_TEXTALIGN.center);
});

it('should have a textAlign to start', async () => {
await setup({ attributes: { textAlign: ODS_BUTTON_TEXTALIGN.start } });
expect(await el.getProperty('textAlign')).toBe(ODS_BUTTON_TEXTALIGN.start);
});

it('should have a textAlign to end', async () => {
await setup({ attributes: { textAlign: ODS_BUTTON_TEXTALIGN.end } });
expect(await el.getProperty('textAlign')).toBe(ODS_BUTTON_TEXTALIGN.end);
});
});

describe('sizes', () => {
it('should have a small size', async () => {
await setup({ attributes: { size: ODS_BUTTON_SIZE.sm } });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,43 @@
@include osds-button-on-text-container {
width: inherit;
}
}

.button__centered-text {
grid-area: center;
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
word-break: break-all;
--ods-icon-vertical-align: bottom;
:host([text-align]) {
@include osds-button-on-text-container {
& span:not([slot]) {
grid-area: center;
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
word-break: break-all;
--ods-icon-vertical-align: bottom;
}
}
}

:host([text-align="center"]) {
@include osds-button-on-text-container {
& span:not([slot]) {
text-align: center;
}
}
}

:host([text-align="start"]) {
@include osds-button-on-text-container {
& span:not([slot]) {
text-align: start;
}
}
}

:host([text-align="end"]) {
@include osds-button-on-text-container {
& span:not([slot]) {
text-align: end;
}
}
}

Expand Down Expand Up @@ -90,11 +118,13 @@ slot {
&[name="start"] {
grid-area: start;
justify-self: start;
white-space: nowrap
}

&[name="end"] {
grid-area: end;
justify-self: end;
white-space: nowrap
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { ODS_THEME_COLOR_INTENT, ODS_THEME_COLOR_INTENTS } from '@ovhcloud/ods-c
import { newSpecPage } from '@stencil/core/testing';
import { ODS_BUTTON_SIZE, ODS_BUTTON_SIZES } from './constants/button-size';
import { ODS_BUTTON_VARIANT, ODS_BUTTON_VARIANTS } from './constants/button-variant';
import { ODS_BUTTON_TEXTALIGN, ODS_BUTTON_TEXTALIGNS } from './constants/button-textalign';
import { DEFAULT_ATTRIBUTE } from './constants/default-attributes';
import { OdsButtonController } from './core/controller';
import { OsdsButton } from './osds-button';
Expand Down Expand Up @@ -220,6 +221,23 @@ describe('spec:osds-button', () => {
expect(page.root?.variant).toBe(randomVariant);
});
});

describe('textAlign', () => {
odsUnitTestAttribute<OdsButtonAttribute, 'textAlign'>({
name: 'textAlign',
defaultValue: DEFAULT_ATTRIBUTE.textAlign,
newValue: ODS_BUTTON_TEXTALIGN.center,
value: ODS_BUTTON_TEXTALIGN.start,
setup: (value) => setup({ attributes: { ['textAlign']: value } }),
...config,
});

it('should set a textAlign if attribute is added', async () => {
const randomTextAlign = ODS_BUTTON_TEXTALIGNS[Math.floor(Math.random() * ODS_BUTTON_TEXTALIGNS.length)];
await setup({ attributes: { textAlign: randomTextAlign } });
expect(page.root?.textAlign).toBe(randomTextAlign);
});
});
});

describe('controller', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import type { HTMLStencilElement } from '@stencil/core/internal';
import type { ODS_BUTTON_SIZE } from './constants/button-size';
import type { ODS_BUTTON_TYPE } from './constants/button-type';
import type { ODS_BUTTON_VARIANT } from './constants/button-variant';
import type { ODS_BUTTON_TEXTALIGN } from './constants/button-textalign';
import type { OdsButtonAttribute } from './interfaces/attributes';
import { Component, Element, Host, Prop, h, Listen } from '@stencil/core';
import { DEFAULT_ATTRIBUTE } from './constants/default-attributes';
Expand Down Expand Up @@ -56,6 +57,9 @@ export class OsdsButton implements OdsButtonAttribute {
/** @see OdsButtonAttributes.variant */
@Prop({ reflect: true, mutable: true }) public variant?: ODS_BUTTON_VARIANT = DEFAULT_ATTRIBUTE.variant;

/** @see OdsButtonAttributes.textAlign */
@Prop({ reflect: true, mutable: true }) public textAlign?: ODS_BUTTON_TEXTALIGN = DEFAULT_ATTRIBUTE.textAlign;

/** @see OdsButtonAttributes.circle */
@Prop({ reflect: true }) public circle? = DEFAULT_ATTRIBUTE.circle;

Expand Down Expand Up @@ -83,7 +87,7 @@ export class OsdsButton implements OdsButtonAttribute {
const content = (
<span class={'button__text-container'}>
<slot name={'start'}></slot>
<span class={'button__centered-text'}>
<span>
<slot></slot>
</span>
<slot name={'end'}></slot>
Expand All @@ -102,6 +106,7 @@ export class OsdsButton implements OdsButtonAttribute {
target: this.target,
rel: this.rel,
download: this.download,
textAlign: this.textAlign,
}}>
{content}
</a>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ export type { OdsButtonAttribute } from './interfaces/attributes';
export { ODS_BUTTON_SIZE, ODS_BUTTON_SIZES } from './constants/button-size';
export { ODS_BUTTON_TYPE, ODS_BUTTON_TYPES } from './constants/button-type';
export { ODS_BUTTON_VARIANT, ODS_BUTTON_VARIANTS } from './constants/button-variant';
export { ODS_BUTTON_TEXTALIGN, ODS_BUTTON_TEXTALIGNS } from './constants/button-textalign';
export { OsdsButton } from './osds-button';
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<div class="container">
<osds-button text-align='center'>Center</osds-button>
<osds-button text-align='Start'>Start</osds-button>
<osds-button text-align='End'>End</osds-button>
</div>

```html
<osds-button text-align='center'>Center</osds-button>
<osds-button text-align='stroked'>Start</osds-button>
<osds-button text-align='ghost'>End</osds-button>
```
4 changes: 4 additions & 0 deletions packages/components/button/src/docs/osds-button/usage.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import ColorProperty from './properties/usage.color.mdx';
import DisabledProperty from './properties/usage.disabled.mdx';
import SizeProperty from './properties/usage.size.mdx';
import VariantProperty from './properties/usage.variant.mdx';
import TextAlignProperty from './properties/usage.textalign.mdx';

<GenericStyle />

Expand All @@ -22,6 +23,9 @@ import VariantProperty from './properties/usage.variant.mdx';
### Variants
<VariantProperty />

### TextAligns
<TextAlignProperty />

### Disabled
<DisabledProperty />

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { html } from 'lit-html';
import { unsafeHTML } from 'lit-html/directives/unsafe-html';
import { OdsHTMLAnchorElementRelList, OdsHTMLAnchorElementTargetList } from '@ovhcloud/ods-common-core';
import { ODS_BUTTON_SIZE, ODS_BUTTON_SIZES, ODS_BUTTON_VARIANT, ODS_BUTTON_VARIANTS } from '@ovhcloud/ods-components/button';
import { ODS_BUTTON_SIZE, ODS_BUTTON_SIZES, ODS_BUTTON_VARIANT, ODS_BUTTON_VARIANTS, ODS_BUTTON_TEXTALIGN, ODS_BUTTON_TEXTALIGNS } from '@ovhcloud/ods-components/button';
import { defineCustomElements } from '@ovhcloud/ods-components/button/loader';
import { ODS_THEME_COLOR_INTENT, ODS_THEME_COLOR_INTENTS } from '@ovhcloud/ods-common-theming';
import { createComponentTable, getTagAttributes, extractArgTypes, extractStoryParams } from '../../../core/componentHTMLUtils';
Expand All @@ -26,6 +26,12 @@ const storyParams = {
options: ODS_BUTTON_SIZES,
control: { type: 'select' },
},
textAlign: {
category: 'General',
defaultValue: ODS_BUTTON_TEXTALIGN.center,
options: ODS_BUTTON_TEXTALIGNS,
control: { type: 'select' },
},
variant: {
category: 'General',
defaultValue: ODS_BUTTON_VARIANT.flat,
Expand Down

0 comments on commit 23f544d

Please sign in to comment.