Skip to content

Commit

Permalink
feat(medium): implement component
Browse files Browse the repository at this point in the history
  • Loading branch information
dpellier committed Jul 29, 2024
1 parent 1c662f1 commit f226ff9
Show file tree
Hide file tree
Showing 22 changed files with 427 additions and 1 deletion.
1 change: 1 addition & 0 deletions packages/ods/react/tests/_app/src/components.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ const componentNames = [
'tag',
'badge',
'table',
'medium',
//--generator-anchor--
];

Expand Down
11 changes: 11 additions & 0 deletions packages/ods/react/tests/_app/src/components/ods-medium.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import React from 'react-dom/client';
import { OdsMedium } from 'ods-components-react';

const Medium = () => {
return (
<OdsMedium alt="Placeholder image"
src="https://placehold.co/600x400" />
);
};

export default Medium;
24 changes: 24 additions & 0 deletions packages/ods/react/tests/e2e/ods-medium.e2e.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import type { Page } from 'puppeteer';
import { goToComponentPage, setupBrowser } from '../setup';

describe('ods-medium react', () => {
const setup = setupBrowser();
let page: Page;

beforeAll(async () => {
page = setup().page;
});

beforeEach(async () => {
await goToComponentPage(page, 'ods-medium');
await page.waitForNetworkIdle();
});

it('render the component correctly', async () => {
const elem = await page.$('ods-medium');
const boundingBox = await elem?.boundingBox();

expect(boundingBox?.height).toBeGreaterThan(0);
expect(boundingBox?.width).toBeGreaterThan(0);
});
});
3 changes: 2 additions & 1 deletion packages/ods/src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@ export * from './button/src';
export * from './tag/src';
export * from './badge/src';

export * from './table/src';
export * from './table/src';
export * from './medium/src';
19 changes: 19 additions & 0 deletions packages/ods/src/components/medium/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"name": "@ovhcloud/ods-component-medium",
"version": "17.1.0",
"private": true,
"description": "ODS Medium component",
"main": "dist/index.cjs.js",
"collection": "dist/collection/collection-manifest.json",
"scripts": {
"clean": "rimraf .stencil coverage dist docs-api www",
"doc": "typedoc --pretty --plugin ../../../scripts/typedoc-plugin-decorator.js && node ../../../scripts/generate-typedoc-md.js",
"lint:scss": "stylelint --allow-empty-input 'src/components/**/*.scss'",
"lint:ts": "eslint '{src,tests}/**/*.{js,ts,tsx}'",
"start": "stencil build --dev --watch --serve",
"test:e2e": "stencil test --e2e --config stencil.config.ts",
"test:e2e:ci": "tsc --noEmit && stencil test --e2e --ci --config stencil.config.ts",
"test:spec": "stencil test --spec --config stencil.config.ts --coverage",
"test:spec:ci": "tsc --noEmit && stencil test --config stencil.config.ts --spec --ci --coverage"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { Component, type FunctionalComponent, Host, Prop, h } from '@stencil/core';

@Component({
shadow: true,
tag: 'ods-medium',
})
export class OdsMedium {
@Prop({ reflect: true }) public alt: string = '';
@Prop({ reflect: true }) public height?: number;
@Prop({ reflect: true }) public src!: string;
@Prop({ reflect: true }) public width?: number;

render(): FunctionalComponent {
return (
<Host>
<img
alt={ this.alt }
height={ this.height }
src={ this.src }
width={ this.width }
/>
</Host>
);
}
}
7 changes: 7 additions & 0 deletions packages/ods/src/components/medium/src/globals.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/**
* Import here all the external ODS component that you need to run the current component
* when running dev server (yarn start) or e2e tests
*
* ex:
* import '../../text/src';
*/
31 changes: 31 additions & 0 deletions packages/ods/src/components/medium/src/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<!DOCTYPE html>
<html dir='ltr' lang='en'>
<head>
<meta charset='utf-8' />
<meta name='viewport' content='width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=5.0' />
<title>Dev ods-medium</title>

<script type='module' src='/build/ods-medium.esm.js'></script>
<script nomodule src='/build/ods-medium.js'></script>
<link rel="stylesheet" href="/build/ods-medium.css">
</head>

<body>
<p>Default</p>
<ods-medium alt="OVHcloud logo"
src="https://corporate.ovhcloud.com/sites/default/files/2022-03/ovhcloud-logo2.png">
</ods-medium>

<p>Height</p>
<ods-medium alt="OVHcloud logo"
height="50"
src="https://corporate.ovhcloud.com/sites/default/files/2022-03/ovhcloud-logo2.png">
</ods-medium>

<p>Width</p>
<ods-medium alt="OVHcloud logo"
src="https://corporate.ovhcloud.com/sites/default/files/2022-03/ovhcloud-logo2.png"
width="300">
</ods-medium>
</body>
</html>
1 change: 1 addition & 0 deletions packages/ods/src/components/medium/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { OdsMedium } from './components/ods-medium/ods-medium';
7 changes: 7 additions & 0 deletions packages/ods/src/components/medium/stencil.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { getStencilConfig } from '../../config/stencil';

export const config = getStencilConfig({
args: process.argv.slice(2),
componentCorePackage: '@ovhcloud/ods-component-medium',
namespace: 'ods-medium',
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import type { E2EElement, E2EPage } from '@stencil/core/testing';
import { newE2EPage } from '@stencil/core/testing';

describe('ods-medium rendering', () => {
let el: E2EElement;
let medium: E2EElement;
let page: E2EPage;

async function setup(content: string, customStyle?: string): Promise<void> {
page = await newE2EPage();

await page.setContent(content);
await page.evaluate(() => document.body.style.setProperty('margin', '0px'));

if (customStyle) {
await page.addStyleTag({ content: customStyle });
}

el = await page.find('ods-medium');
medium = await page.find('ods-medium >>> img');
}

it('should render the web component', async() => {
await setup('<ods-medium></ods-medium>');

expect(el.shadowRoot).not.toBeNull();
expect(medium).not.toBeNull();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import type { SpecPage } from '@stencil/core/testing';
import { newSpecPage } from '@stencil/core/testing';
import { OdsMedium } from '../../src';

describe('ods-medium rendering', () => {
let page: SpecPage;
let root: HTMLElement | undefined;

async function setup(html: string): Promise<void> {
page = await newSpecPage({
components: [OdsMedium],
html,
});

root = page.root;
}

describe('alt', () => {
it('should be reflected', async() => {
const dummyValue = 'dummy value';

await setup(`<ods-medium alt="${dummyValue}"></ods-medium>`);

expect(root?.getAttribute('alt')).toBe(dummyValue);
});

it('should render with expected default value', async() => {
await setup('<ods-medium></ods-medium>');

expect(root?.getAttribute('alt')).toBe('');
});
});

describe('height', () => {
it('should be reflected', async() => {
const dummyValue = '42';

await setup(`<ods-medium height="${dummyValue}"></ods-medium>`);

expect(root?.getAttribute('height')).toBe(dummyValue);
});

it('should not be set by default', async() => {
await setup('<ods-medium></ods-medium>');

expect(root?.getAttribute('height')).toBeNull();
});
});

describe('src', () => {
it('should be reflected', async() => {
const dummyValue = 'dummy value';

await setup(`<ods-medium src="${dummyValue}"></ods-medium>`);

expect(root?.getAttribute('src')).toBe(dummyValue);
});

it('should not be set by default', async() => {
await setup('<ods-medium></ods-medium>');

expect(root?.getAttribute('src')).toBeNull();
});
});

describe('width', () => {
it('should be reflected', async() => {
const dummyValue = '33';

await setup(`<ods-medium width="${dummyValue}"></ods-medium>`);

expect(root?.getAttribute('width')).toBe(dummyValue);
});

it('should not be set by default', async() => {
await setup('<ods-medium></ods-medium>');

expect(root?.getAttribute('width')).toBeNull();
});
});
});
7 changes: 7 additions & 0 deletions packages/ods/src/components/medium/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"extends": "../../../tsconfig.json",
"include": [
"src",
"tests"
]
}
10 changes: 10 additions & 0 deletions packages/ods/src/components/medium/typedoc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"entryPoints": ["src/index.ts"],
"excludeInternal": true,
"excludePrivate": true,
"excludeProtected": true,
"hideGenerator": true,
"json": "dist/docs-api/typedoc.json",
"out": "dist/docs-api/",
"tsconfig":"tsconfig.json"
}
1 change: 1 addition & 0 deletions packages/ods/vue/tests/_app/src/components.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ const componentNames = [
'tag',
'badge',
'table',
'medium',
//--generator-anchor--
];

Expand Down
16 changes: 16 additions & 0 deletions packages/ods/vue/tests/_app/src/components/ods-medium.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<template>
<OdsMedium alt="Placeholder image"
src="https://placehold.co/600x400" />
</template>

<script lang="ts">
import { defineComponent } from 'vue';
import { OdsMedium } from '@ovhcloud/ods-components/vue';
export default defineComponent({
name: 'Medium',
components: {
OdsMedium,
},
});
</script>
24 changes: 24 additions & 0 deletions packages/ods/vue/tests/e2e/ods-medium.e2e.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import type { Page } from 'puppeteer';
import { goToComponentPage, setupBrowser } from '../setup';

describe('ods-medium vue', () => {
const setup = setupBrowser();
let page: Page;

beforeAll(async () => {
page = setup().page;
});

beforeEach(async () => {
await goToComponentPage(page, 'ods-medium');
await page.waitForNetworkIdle();
});

it('render the component correctly', async () => {
const elem = await page.$('ods-medium');
const boundingBox = await elem?.boundingBox();

expect(boundingBox?.height).toBeGreaterThan(0);
expect(boundingBox?.width).toBeGreaterThan(0);
});
});
33 changes: 33 additions & 0 deletions packages/storybook/stories/components/medium/documentation.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { Canvas, Meta, Markdown } from '@storybook/blocks';
import SpecificationsMedium from '@ovhcloud/ods-components/src/components/medium/documentation/spec.md?raw';
import { Banner } from '../../banner';
import { DocNavigator } from '../../doc-navigator';
import * as MediumStories from './medium.stories';

<Meta of={ MediumStories } name='Documentation' />

<Banner of={ MediumStories } />

# Overview

Medium is a wrapper for displaying assets such as images:

<Canvas of={ MediumStories.Default } sourceState='none' />

<DocNavigator of={ MediumStories } />

# API

<Markdown>{ SpecificationsMedium }</Markdown>

# Examples

## Default

<Canvas of={ MediumStories.Default } sourceState='shown' />

## Height
<Canvas of={ MediumStories.Height } sourceState='shown' />

## Width
<Canvas of={ MediumStories.Width } sourceState='shown' />
Loading

0 comments on commit f226ff9

Please sign in to comment.