Skip to content

Commit

Permalink
feat(divider): implement coponent
Browse files Browse the repository at this point in the history
  • Loading branch information
skhamvon authored and dpellier committed Jul 29, 2024
1 parent b5633db commit 896df6e
Show file tree
Hide file tree
Showing 25 changed files with 668 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 @@ -24,6 +24,7 @@ const componentNames = [
'breadcrumb',
'toggle',
'clipboard',
'divider',
//--generator-anchor--
];

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

const Divider = () => {
return (
<OdsDivider />
);
};

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

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

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

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

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

expect(boundingBox?.height).toBeGreaterThan(0);
expect(boundingBox?.width).toBeGreaterThan(0);
});
});
5 changes: 5 additions & 0 deletions packages/ods/src/components/divider/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Local Stencil command generates external ods component build at the root of the project
# Excluding them is a temporary solution to avoid pushing generated files
# But the issue may cause main build (ods-component package) to fails, as it detects multiples occurences
# of the same component and thus you have to delete all those generated dir manually
*/src/
19 changes: 19 additions & 0 deletions packages/ods/src/components/divider/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"name": "@ovhcloud/ods-component-divider",
"version": "17.1.0",
"private": true,
"description": "ODS Divider 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 '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,23 @@
$spacings: 0, 2, 4, 8, 12, 16, 24, 32, 40, 48, 64;

.ods-divider {
&__divider {
border: none;
height: 1px;

&--light {
background-color: var(--ods-color-neutral-100);
}

&--dark {
background-color: var(--ods-color-neutral-700);
}

@each $spacing in $spacings {
&--#{$spacing} {
margin-top: calc(#{$spacing}px / 2);
margin-bottom: calc(#{$spacing}px / 2);
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import type { OdsDividerColor } from '../../constants/divider-color';
import type { OdsDividerSpacing } from '../../constants/divider-spacing';
import type { FunctionalComponent } from '@stencil/core';
import { Component, Host, Prop, h } from '@stencil/core';
import { ODS_DIVIDER_COLOR } from '../../constants/divider-color';
import { ODS_DIVIDER_SPACING } from '../../constants/divider-spacing';

@Component({
shadow: true,
styleUrl: 'ods-divider.scss',
tag: 'ods-divider',
})
export class OdsDivider {
@Prop({ reflect: true }) color: OdsDividerColor = ODS_DIVIDER_COLOR.light;
@Prop({ reflect: true }) spacing: OdsDividerSpacing = ODS_DIVIDER_SPACING._2;

render(): FunctionalComponent {
return (
<Host>
<hr class={ `ods-divider__divider ods-divider__divider--${this.color} ods-divider__divider--${this.spacing}` }
part="divider" />
</Host>
);
}
}
14 changes: 14 additions & 0 deletions packages/ods/src/components/divider/src/constants/divider-color.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
enum ODS_DIVIDER_COLOR {
dark = 'dark',
light = 'light',
}

type OdsDividerColor = `${ODS_DIVIDER_COLOR}`;

const ODS_DIVIDER_COLORS = Object.freeze(Object.values(ODS_DIVIDER_COLOR));

export {
ODS_DIVIDER_COLOR,
ODS_DIVIDER_COLORS,
type OdsDividerColor,
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
enum ODS_DIVIDER_SPACING {
_0 = '0',
_2 = '2',
_4 = '4',
_6 = '6',
_8 = '8',
_12 = '12',
_16 = '16',
_24 = '24',
_32 = '32',
_40 = '40',
_48 = '48',
_64 = '64',
}

type OdsDividerSpacing = `${ODS_DIVIDER_SPACING}`;

const ODS_DIVIDER_SPACINGS = Object.freeze(Object.values(ODS_DIVIDER_SPACING));

export {
ODS_DIVIDER_SPACING,
ODS_DIVIDER_SPACINGS,
type OdsDividerSpacing,
};
7 changes: 7 additions & 0 deletions packages/ods/src/components/divider/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';
*/
48 changes: 48 additions & 0 deletions packages/ods/src/components/divider/src/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<!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-divider</title>

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

<body>
<div>
<h3>Colors</h3>
<span>Lorem Ipsum</span>
<ods-divider color="light"></ods-divider>
<span>Lorem Ipsum</span>
<ods-divider color="dark"></ods-divider>
<span>Lorem Ipsum</span>

<h3>Spacing</h3>
<span>Lorem Ipsum</span>
<ods-divider spacing="0"></ods-divider>
<span>Lorem Ipsum</span>
<ods-divider spacing="2"></ods-divider>
<span>Lorem Ipsum</span>
<ods-divider spacing="4"></ods-divider>
<span>Lorem Ipsum</span>
<ods-divider spacing="8"></ods-divider>
<span>Lorem Ipsum</span>
<ods-divider spacing="12"></ods-divider>
<span>Lorem Ipsum</span>
<ods-divider spacing="16"></ods-divider>
<span>Lorem Ipsum</span>
<ods-divider spacing="24"></ods-divider>
<span>Lorem Ipsum</span>
<ods-divider spacing="32"></ods-divider>
<span>Lorem Ipsum</span>
<ods-divider spacing="40"></ods-divider>
<span>Lorem Ipsum</span>
<ods-divider spacing="48"></ods-divider>
<span>Lorem Ipsum</span>
<ods-divider spacing="64"></ods-divider>
<span>Lorem Ipsum</span>
</div>
</body>
</html>
5 changes: 5 additions & 0 deletions packages/ods/src/components/divider/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export type { OdsDividerColor } from './constants/divider-color';
export type { OdsDividerSpacing } from './constants/divider-spacing';
export { ODS_DIVIDER_COLOR, ODS_DIVIDER_COLORS } from './constants/divider-color';
export { ODS_DIVIDER_SPACING, ODS_DIVIDER_SPACINGS } from './constants/divider-spacing';
export { OdsDivider } from './components/ods-divider/ods-divider';
7 changes: 7 additions & 0 deletions packages/ods/src/components/divider/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-divider',
namespace: 'ods-divider',
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import type { E2EElement, E2EPage } from '@stencil/core/testing';
import { newE2EPage } from '@stencil/core/testing';
import { ODS_DIVIDER_COLOR, ODS_DIVIDER_SPACING } from '../../src';

describe('ods-divider rendering', () => {
let hr: E2EElement;
let el: 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-divider');
hr = await page.find('ods-divider >>> .ods-divider__divider');
}

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

expect(el.shadowRoot).not.toBeNull();
expect(hr).not.toBeNull();
});

describe('part', () => {
it('should render with custom style applied', async() => {
const customColor = 'rgba(255, 0, 0, 0)';

await setup('<ods-divider></ods-divider>', `ods-divider::part(divider) { background-color: ${customColor}; }`);

const hrStyle = await hr.getComputedStyle();
expect(hrStyle.getPropertyValue('background-color')).toBe(customColor);
});
});

describe('colors', () => {
it('should have different colors', async() => {
await setup(`
<ods-divider color=${ODS_DIVIDER_COLOR.light}></ods-divider>
<ods-divider color=${ODS_DIVIDER_COLOR.dark}></ods-divider>
`);

const lightDivider = await page.find(`ods-divider[color='${ODS_DIVIDER_COLOR.light}'] >>> .ods-divider__divider`);
const darkDivider = await page.find(`ods-divider[color='${ODS_DIVIDER_COLOR.dark}'] >>> .ods-divider__divider`);

const lightDividerStyle = await lightDivider.getComputedStyle();
const lightDividerBackgroundColor = lightDividerStyle.getPropertyValue('background-color');

const darkDividerStyle = await darkDivider.getComputedStyle();
const darkDividerBackgroundColor = darkDividerStyle.getPropertyValue('background-color');

expect(lightDividerBackgroundColor).not.toBe(darkDividerBackgroundColor);
});
});

describe('spacing', () => {
it('should respect increase order (2 < 12 < 24)', async() => {
await setup(`
<ods-divider spacing=${ODS_DIVIDER_SPACING._2}></ods-divider>
<ods-divider spacing=${ODS_DIVIDER_SPACING._12}></ods-divider>
<ods-divider spacing=${ODS_DIVIDER_SPACING._24}></ods-divider>
`);

const smDivider = await page.find(`ods-divider[spacing='${ODS_DIVIDER_SPACING._2}'] >>> .ods-divider__divider`);
const mdDivider = await page.find(`ods-divider[spacing='${ODS_DIVIDER_SPACING._12}'] >>> .ods-divider__divider`);
const lgDivider = await page.find(`ods-divider[spacing='${ODS_DIVIDER_SPACING._24}'] >>> .ods-divider__divider`);

const smDividerStyle = await smDivider.getComputedStyle();
const smDividerMarginTop = parseInt(smDividerStyle.getPropertyValue('margin-top'), 10);

const mdDividerStyle = await mdDivider.getComputedStyle();
const mdDividerMarginTop = parseInt(mdDividerStyle.getPropertyValue('margin-top'), 10);

const lgDividerStyle = await lgDivider.getComputedStyle();
const lgDividerMarginTop = parseInt(lgDividerStyle.getPropertyValue('margin-top'), 10);

expect(smDividerMarginTop).toBeLessThan(mdDividerMarginTop);
expect(smDividerMarginTop).toBeLessThan(lgDividerMarginTop);
expect(mdDividerMarginTop).toBeLessThan(lgDividerMarginTop);
expect(mdDividerMarginTop).toBeGreaterThan(smDividerMarginTop);
expect(lgDividerMarginTop).toBeGreaterThan(smDividerMarginTop);
expect(lgDividerMarginTop).toBeGreaterThan(mdDividerMarginTop);
});
});
});
Loading

0 comments on commit 896df6e

Please sign in to comment.