Skip to content

Commit

Permalink
Merge branch 'main' into VIV-2031-add-action-items-slot
Browse files Browse the repository at this point in the history
  • Loading branch information
RichardHelm authored Oct 23, 2024
2 parents 1a8b348 + 3940e85 commit 3ee5c60
Show file tree
Hide file tree
Showing 16 changed files with 164 additions and 95 deletions.
4 changes: 2 additions & 2 deletions .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"libs/components": "4.9.0",
"libs/vue-wrappers": "4.9.0",
"libs/components": "4.10.0",
"libs/vue-wrappers": "4.10.0",
"libs/eslint-plugin": "1.3.0"
}
19 changes: 19 additions & 0 deletions libs/components/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,25 @@ This log was last generated on Thu, 26 Jan 2023 14:40:25 GMT and should not be m

<!-- Start content -->

## [4.10.0](https://github.com/Vonage/vivid-3/compare/vivid-v4.9.0...vivid-v4.10.0) (2024-10-23)


### Features

* **button:** content align to start when drop-down indicator is set (VIV-2200) ([#1962](https://github.com/Vonage/vivid-3/issues/1962)) ([b1c3a11](https://github.com/Vonage/vivid-3/commit/b1c3a11ffc4d95651601cabfde61e680e14b3d36))
* **dialog:** add `no-dismiss-on-esc`, `no-dismiss-button` and `non-dismissible` members (VIV-1907) ([#1871](https://github.com/Vonage/vivid-3/issues/1871)) ([af258af](https://github.com/Vonage/vivid-3/commit/af258af36f7ed8bff5112d3f462da6386024ddf5))


### Bug Fixes

* **audio-player:** change menu position-strategy to absolute (VIV-2192) ([#1945](https://github.com/Vonage/vivid-3/issues/1945)) ([3a6f054](https://github.com/Vonage/vivid-3/commit/3a6f0543795ef30ccf70287e098bb55b25b71c81))
* **checkbox:** aria-checked now properly conveys and controls checkbox state (VIV-1598) ([#1956](https://github.com/Vonage/vivid-3/issues/1956)) ([79a13b1](https://github.com/Vonage/vivid-3/commit/79a13b1bf3778a54edd983f4c156b5444d78708d))
* **dial-pad:** prevent focus loss after removal of delete button (VIV-2126) ([#1912](https://github.com/Vonage/vivid-3/issues/1912)) ([fbc115e](https://github.com/Vonage/vivid-3/commit/fbc115e8f28c1c2da37d039593459a33301214f2))
* **icon:** cancel outstanding fetch when changing icon name (VIV-2186) ([#1959](https://github.com/Vonage/vivid-3/issues/1959)) ([3d2900c](https://github.com/Vonage/vivid-3/commit/3d2900cfd0fe9ceec2323608645e8ec9627f09ef))
* **icon:** fix missing announcement in connotation type (VIV-000) ([#1951](https://github.com/Vonage/vivid-3/issues/1951)) ([436e606](https://github.com/Vonage/vivid-3/commit/436e6069fa1a2c984abd0bebbcff3c23164d3b2c))
* **menu-item:** remove border-radius from focus state (VIV-2160) ([#1957](https://github.com/Vonage/vivid-3/issues/1957)) ([570f635](https://github.com/Vonage/vivid-3/commit/570f635f73a4ba5beed8f3218bf42d13eac2696f))
* **text-field:** reflects inputmode onto input element (VIV-000) ([#1947](https://github.com/Vonage/vivid-3/issues/1947)) ([99e360e](https://github.com/Vonage/vivid-3/commit/99e360eea165d7253b224525ec7f064e5f2404fd))

## [4.9.0](https://github.com/Vonage/vivid-3/compare/vivid-v4.8.0...vivid-v4.9.0) (2024-10-10)


Expand Down
2 changes: 1 addition & 1 deletion libs/components/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@vonage/vivid",
"version": "4.9.0",
"version": "4.10.0",
"type": "module",
"module": "./index.js",
"main": "./index.cjs",
Expand Down
31 changes: 31 additions & 0 deletions libs/components/src/lib/button/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,37 @@ Use the `icon` slot to customise icons. If set, the icon attribute is ignored.
</style>
```

## CSS Variables

### Button Content Alignment

When `dropdown-indicator` is set button, the content alignment is set to start.
If center is needed, set `--button-content-alignment: center;`.

```html preview
<vwc-button
class="vwc-button"
dropdown-indicator
appearance="outlined-light"
label="aligned to start content"
></vwc-button>
<vwc-button
class="vwc-button vwc-button-center"
dropdown-indicator
appearance="outlined-light"
label="centered content"
></vwc-button>

<style>
.vwc-button {
inline-size: 300px;
}
.vwc-button-center {
--button-content-alignment: center;
}
</style>
```

## API Reference

### Properties
Expand Down
4 changes: 4 additions & 0 deletions libs/components/src/lib/button/VARIATIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -378,3 +378,7 @@ When the button is used to trigger a menu / dropdown, you can set `dropdown-indi
<vwc-menu-item icon="delete-line" text="Archive"></vwc-menu-item>
</vwc-menu>
```

<vwc-note connotation="information" icon="info-line">
<p>When setting <code>dropdown-indicator</code> the Button's content alignment changes from center to start. You can change it back to center using <code>--button-content-alignment</code> CSS variable </p>
</vwc-note>
8 changes: 8 additions & 0 deletions libs/components/src/lib/button/button.scss
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,14 @@ slot[name='icon'] {
.control.stacked & {
flex-direction: column;
}

:host([dropdown-indicator]) & {
justify-content: var(#{variables.$button-content-alignment}, flex-start);
}
:host([dropdown-indicator][stacked]) & {
align-items: var(#{variables.$button-content-alignment}, flex-start);
justify-content: center;
}
}

:host(:not([icon])) .pending {
Expand Down
1 change: 1 addition & 0 deletions libs/components/src/lib/button/partials/variables.scss
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ $block-size: --_button-block-size;
$button-line-clamp: --button-line-clamp;
$button-border-radius: --_button-border-radius;
$chevron-size: --_button-chevron-size;
$button-content-alignment: --button-content-alignment;
6 changes: 5 additions & 1 deletion libs/components/src/lib/button/ui.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -221,11 +221,15 @@ test('should show the component', async ({ page }: { page: Page }) => {
<vwc-button dropdown-indicator icon="user-line" stacked appearance="filled" label="condensed" size="condensed"></vwc-button>
<vwc-button dropdown-indicator icon="user-line" stacked appearance="filled" label="normal" size="normal"></vwc-button>
<vwc-button dropdown-indicator icon="user-line" stacked appearance="filled" label="expanded" size="expanded"></vwc-button>
</div>
<div style="margin: 5px;">
<vwc-button dropdown-indicator icon="user-line" appearance="filled" label="align-start" size="normal" style="width: 280px;"></vwc-button>
<vwc-button dropdown-indicator icon="user-line" appearance="filled" label="keep align-center" size="normal" style="width: 280px; --button-content-alignment: center;"></vwc-button>
</div>
</div>
`;

await page.setViewportSize({ width: 500, height: 1200 });
await page.setViewportSize({ width: 600, height: 1500 });

await loadComponents({
page,
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`icon resolver should set the icon as loading after 500ms 1`] = `
exports[`icon name should set the icon as loading after 500ms 1`] = `
"<svg width=\\"80%\\" height=\\"80%\\" viewBox=\\"0 0 64 64\\">
<g>
<g stroke-width=\\"6\\" stroke-linecap=\\"round\\" fill=\\"none\\">
Expand Down
148 changes: 67 additions & 81 deletions libs/components/src/lib/icon/icon.spec.ts
Original file line number Diff line number Diff line change
@@ -1,70 +1,64 @@
import {
axe,
elementUpdated,
fixture,
getControlElement,
} from '@vivid-nx/shared';
import { axe, fixture, getControlElement } from '@vivid-nx/shared';
import { ICONS_VERSION as ICON_SET_VERSION } from '@vonage/vwc-consts';
import type { Icon } from './icon';
import '.';

const COMPONENT_TAG = 'vwc-icon';

describe('icon', function () {
function fakeFetch(requestTime = 4000) {
(global.fetch as any) = jest.fn((_, { signal }) => {
currentFetchSignal = signal;
return new Promise((res) => {
setTimeout(() => res(response), requestTime);
});
});
}

function setIconNameAndTriggerFirstTimer() {
element.name = 'none';
jest.advanceTimersToNextTimer();
}

function setIconNameAndAdvanceTime(timeInMs: number, name = 'none') {
element.name = name;
jest.advanceTimersByTime(timeInMs);
}

function setIconNameAndRunAllTimers(iconName: string | undefined) {
element.name = iconName;
jest.runAllTimers();
}

const svg = 'svg';
const response = {
ok: true,
headers: {
get: () => {
return 'image/svg+xml';
},
},
text: () => svg,
};
const originalFetch = global.fetch;
const originalPromise = global.Promise;

let currentFetchSignal: AbortSignal;
let element: Icon;

beforeEach(async () => {
element = (await fixture(`<${COMPONENT_TAG}></${COMPONENT_TAG}>`)) as Icon;
global.Promise = require('promise'); // needed in order for promises to work with jest fake timers
jest.useFakeTimers({ legacyFakeTimers: true });
});

describe('resolver', function () {
function fakeFetch(requestTime = 4000) {
(global.fetch as any) = jest.fn(() => {
return new Promise((res) => {
setTimeout(() => res(response), requestTime);
});
});
}

const svg = 'svg';
const response = {
ok: true,
headers: {
get: () => {
return 'image/svg+xml';
},
},
text: () => svg,
};
const originalFetch = global.fetch;
const originalPromise = global.Promise;

beforeEach(function () {
global.Promise = require('promise'); // needed in order for promises to work with jest fake timers
jest.useFakeTimers({ legacyFakeTimers: true });
});

afterEach(function () {
jest.useRealTimers();
global.fetch = originalFetch;
global.Promise = originalPromise;
});

function setIconNameAndTriggerFirstTimer() {
element.name = 'none';
jest.advanceTimersToNextTimer();
}

function setIconNameAndAdvanceTime(timeInMs: number) {
element.name = 'none';
jest.advanceTimersByTime(timeInMs);
}

function setIconNameAndRunAllTimers(iconName: string | undefined) {
element.name = iconName;
jest.runAllTimers();
}
afterEach(function () {
jest.useRealTimers();
global.fetch = originalFetch;
global.Promise = originalPromise;
});

describe('name', function () {
it('should show nothing when first changing the icon', async function () {
fakeFetch(4000);
setIconNameAndTriggerFirstTimer();
Expand Down Expand Up @@ -96,6 +90,16 @@ describe('icon', function () {
setIconNameAndRunAllTimers(undefined);
expect(element._svg).toEqual('');
});

it('should abort additional fetch requests', function () {
fakeFetch(100);
setIconNameAndAdvanceTime(50, 'home');
const homeSignal = currentFetchSignal;

setIconNameAndAdvanceTime(10, 'user');

expect(homeSignal.aborted).toBe(true);
});
});

describe('iconLoaded', function () {
Expand All @@ -104,74 +108,56 @@ describe('icon', function () {
});

it('should set to true when icon is loaded', async function () {
element.name = 'home';
await elementUpdated(element);
setIconNameAndRunAllTimers('home');
expect(element.iconLoaded).toEqual(true);
});

it('should set an image with src when iconLoaded is false', async function () {
element.name = 'home';
await elementUpdated(element);
setIconNameAndRunAllTimers('home');
element.iconLoaded = false;
await elementUpdated(element);
jest.runAllTimers();
const imgElement = getControlElement(element).querySelector('img');
expect(imgElement?.src).toEqual(
`https://icon.resources.vonage.com/v${ICON_SET_VERSION}/home.svg`
);
});

it('should set aria-busy on the figure element when iconLoaded is false', async function () {
element.name = 'home';
await elementUpdated(element);
setIconNameAndRunAllTimers('home');
element.iconLoaded = false;
await elementUpdated(element);
jest.runAllTimers();
const figureElement = getControlElement(element);
expect(figureElement.hasAttribute('aria-busy')).toBe(true);
});

it('should set iconLoaded to false when name changes', async function () {
function fakeFetch() {
const originalFetch = global.fetch;
let timeout: any;
(global.fetch as any) = jest.fn(() => {
return new Promise((res) => {
timeout = setTimeout(() => res(false), 1000);
});
});
return () => {
global.fetch = originalFetch;
clearTimeout(timeout);
};
}

const restoreFetch = fakeFetch();
element.iconLoaded = true;

element.name = 'no-home';
await elementUpdated(element);
setIconNameAndAdvanceTime(100);

expect(element.iconLoaded).toEqual(false);
restoreFetch();
});
});

describe('size', function () {
it('should not have size class if not set', async function () {
it('should default to no size class', async function () {
expect(getControlElement(element).className).not.toContain('size-');
});

it.each([0, 2] as const)(
'should set size class accordingly when size is %s',
async function (size) {
element.size = size;
await elementUpdated(element);
jest.runAllTimers();
expect(getControlElement(element).classList).toContain(`size-${size}`);
}
);
});

describe('a11y', () => {
it('should pass html a11y test', async () => {
jest.clearAllTimers();
jest.useRealTimers();
element = (await fixture(
`<${COMPONENT_TAG} name="home"></${COMPONENT_TAG}>`
)) as Icon;
Expand Down
Loading

0 comments on commit 3ee5c60

Please sign in to comment.