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(site): Added time component #981

Merged
merged 1 commit into from
Dec 8, 2023
Merged
Show file tree
Hide file tree
Changes from all 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
1 change: 1 addition & 0 deletions libs/domain/site/src/components.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ export * from '../navigation-item/navigation-item.def';
export * from '../notification-center/notification-center.def';
export * from '../price-mode-selector/price-mode-selector.def';
export * from '../price/price.def';
export * from '../time/time.def';
2 changes: 2 additions & 0 deletions libs/domain/site/time/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './time.component';
export * from './time.model';
27 changes: 27 additions & 0 deletions libs/domain/site/time/stories/demo.stories.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { Meta, Story } from '@storybook/web-components';
import { TemplateResult, html } from 'lit';
import { storybookPrefix } from '../../.constants';
import { SiteTimeComponentAttributes } from '../time.model';

export default {
title: `${storybookPrefix}/time`,
args: {
stamp: new Date().toString(),
i18nToken: 'before-<time>-after',
},
argTypes: {
i18nToken: { control: { type: 'text' } },
},
parameters: { chromatic: { disableSnapshot: true } },
} as Meta;

const Template: Story<SiteTimeComponentAttributes> = (
props: SiteTimeComponentAttributes
): TemplateResult => {
return html`<oryx-site-time
.stamp=${props.stamp}
.i18nToken=${props.i18nToken}
></oryx-site-time>`;
};

export const Demo = Template.bind({});
31 changes: 31 additions & 0 deletions libs/domain/site/time/stories/static.stories.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { Meta, Story } from '@storybook/web-components';
import { TemplateResult, html } from 'lit';
import { storybookPrefix } from '../../.constants';
import { SiteTimeComponentAttributes } from '../time.model';

export default {
title: `${storybookPrefix}/time`,
} as Meta;

const Template: Story<SiteTimeComponentAttributes> = (
props: SiteTimeComponentAttributes
): TemplateResult => {
return html`<oryx-site-time
.stamp=${'Fri Dec 08 2023 16:52:54 GMT+0100'}
></oryx-site-time>
<oryx-site-time
.stamp=${'Fri Dec 08 2023 02:52:54 GMT+0100'}
></oryx-site-time>
<oryx-site-time
.stamp=${'Fri Dec 08 2023 08:52:54 GMT+0100'}
.i18nToken=${'before-<time>-after'}
></oryx-site-time>

<style>
oryx-site-time {
display: block;
}
</style> `;
};

export const Static = Template.bind({});
118 changes: 118 additions & 0 deletions libs/domain/site/time/time.component.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
import { fixture } from '@open-wc/testing-helpers';
import { createInjector, destroyInjector } from '@spryker-oryx/di';
import { LocaleService } from '@spryker-oryx/i18n';
import { siteProviders, siteTimeComponent } from '@spryker-oryx/site';
import { useComponent } from '@spryker-oryx/utilities';
import { html } from 'lit';
import { of } from 'rxjs';
import { SiteTimeComponent } from './time.component';

class MockLocaleService implements Partial<LocaleService> {
get = vi.fn().mockReturnValue(of('en'));
formatTime = vi.fn();
}

describe('SiteTimeComponent', () => {
let element: SiteTimeComponent;
let localeService: MockLocaleService;

beforeAll(async () => {
await useComponent([siteTimeComponent]);
});

beforeEach(async () => {
const injector = createInjector({
providers: [
...siteProviders,
{
provide: LocaleService,
useClass: MockLocaleService,
},
],
});

localeService = injector.inject(
LocaleService
) as unknown as MockLocaleService;
});

afterEach(() => {
destroyInjector();
vi.clearAllMocks();
});

describe('when the component is initialised', () => {
beforeEach(async () => {
element = await fixture(html`<oryx-site-time></oryx-site-time>`);
});

it('should be an instance of SiteDayComponent', () => {
expect(element).toBeInstanceOf(SiteTimeComponent);
});
});

describe('when the current locale is "en"', () => {
beforeEach(async () => {
localeService.get.mockReturnValue(of('en'));
});

describe('and the day is monday', () => {
beforeEach(async () => {
localeService.formatTime.mockReturnValue('formatted-time');
element = await fixture(
html`<oryx-site-time
.stamp=${'Fri Dec 08 2023 16:57:07'}
></oryx-site-time>`
);
});

it('should call the locale service to format the date', () => {
expect(localeService.formatTime).toHaveBeenCalledWith(
'Fri Dec 08 2023 16:57:07'
);
});

it('should render the formatted date', () => {
expect(element.shadowRoot?.textContent?.trim()).toBe('formatted-time');
});
});
});

describe('when an i18n token is provided', () => {
beforeEach(async () => {
localeService.get.mockReturnValue(of('en'));
localeService.formatTime.mockReturnValue('formatted-time');
});

describe('and there is a day available', () => {
beforeEach(async () => {
element = await fixture(
html`<oryx-site-time
.stamp=${'Fri Dec 08 2023 16:57:07'}
i18nToken="my.custom-<time>-time"
></oryx-site-time>`
);
});

it('should render the token', () => {
expect(element.shadowRoot?.textContent?.trim()).toBe(
'Custom formatted-time time'
);
});
});

describe('and there is no day available', () => {
beforeEach(async () => {
element = await fixture(
html`<oryx-site-time
i18nToken="my.custom-<time>-time"
></oryx-site-time>`
);
});

it('should not render the token', () => {
expect(element.shadowRoot?.textContent?.trim()).toBe('');
});
});
});
});
36 changes: 36 additions & 0 deletions libs/domain/site/time/time.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { resolve } from '@spryker-oryx/di';
import { ContentMixin } from '@spryker-oryx/experience';
import { LocaleService } from '@spryker-oryx/i18n';
import {
computed,
hydrate,
signalAware,
signalProperty,
} from '@spryker-oryx/utilities';
import { LitElement, TemplateResult, html } from 'lit';
import { SiteTimeComponentAttributes } from './time.model';

@hydrate()
@signalAware()
export class SiteTimeComponent
extends ContentMixin(LitElement)
implements SiteTimeComponentAttributes
{
protected localeService = resolve(LocaleService);

@signalProperty() stamp?: string | number | Date;
@signalProperty() i18nToken?: string;

protected $time = computed(() =>
this.stamp ? this.localeService.formatTime(this.stamp) : undefined
);

protected override render(): TemplateResult | void {
if (!this.$time()) return;
if (this.i18nToken) {
return html`${this.i18n(this.i18nToken, { time: this.$time() })}`;
} else {
return html`${this.$time()}`;
}
}
}
6 changes: 6 additions & 0 deletions libs/domain/site/time/time.def.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { componentDef } from '@spryker-oryx/utilities';

export const siteTimeComponent = componentDef({
name: 'oryx-site-time',
impl: () => import('./time.component').then((m) => m.SiteTimeComponent),
});
17 changes: 17 additions & 0 deletions libs/domain/site/time/time.model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
export interface SiteTimeComponentAttributes {
/**
* The value property represents the time in milliseconds.
*/
stamp?: number | string | Date;

/**
* The i18n token can be used to generate a time inside a text. The i18n token
* comes with a default token context parameter ("time"), which will generate the following
* i18n syntax:
*
* ```
* i18n('my.token-<time>', {date: '26-04-2023'})
* ```
*/
i18nToken?: string;
}
1 change: 1 addition & 0 deletions tsconfig.base.json
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,7 @@
"@spryker-oryx/site/price-mode-selector": [
"libs/domain/site/price-mode-selector/index.ts"
],
"@spryker-oryx/site/time": ["libs/domain/site/time/index.ts"],
"@spryker-oryx/themes": ["libs/template/themes/src/index.ts"],
"@spryker-oryx/themes/breakpoints": [
"libs/template/themes/breakpoints/index.ts"
Expand Down
Loading