Skip to content

Commit

Permalink
feat(timeline-element): create component
Browse files Browse the repository at this point in the history
  • Loading branch information
WilliamTraoreee committed Sep 10, 2022
1 parent 3d02ac8 commit 70f50a0
Show file tree
Hide file tree
Showing 17 changed files with 285 additions and 0 deletions.
3 changes: 3 additions & 0 deletions libs/shared/types/.babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"presets": [["@nrwl/web/babel", { "useBuiltIns": "usage" }]]
}
18 changes: 18 additions & 0 deletions libs/shared/types/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"extends": ["../../../.eslintrc.json"],
"ignorePatterns": ["!**/*"],
"overrides": [
{
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
"rules": {}
},
{
"files": ["*.ts", "*.tsx"],
"rules": {}
},
{
"files": ["*.js", "*.jsx"],
"rules": {}
}
]
}
11 changes: 11 additions & 0 deletions libs/shared/types/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# shared-types

This library was generated with [Nx](https://nx.dev).

## Running unit tests

Run `nx test shared-types` to execute the unit tests via [Jest](https://jestjs.io).

## Running lint

Run `nx lint shared-types` to execute the lint via [ESLint](https://eslint.org/).
15 changes: 15 additions & 0 deletions libs/shared/types/jest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/* eslint-disable */
export default {
displayName: 'shared-types',
preset: '../../../jest.preset.js',
globals: {
'ts-jest': {
tsconfig: '<rootDir>/tsconfig.spec.json',
},
},
transform: {
'^.+\\.[tj]sx?$': 'ts-jest',
},
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'],
coverageDirectory: '../../../coverage/libs/shared/types',
};
23 changes: 23 additions & 0 deletions libs/shared/types/project.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"$schema": "../../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "libs/shared/types/src",
"projectType": "library",
"targets": {
"lint": {
"executor": "@nrwl/linter:eslint",
"outputs": ["{options.outputFile}"],
"options": {
"lintFilePatterns": ["libs/shared/types/**/*.ts"]
}
},
"test": {
"executor": "@nrwl/jest:jest",
"outputs": ["coverage/libs/shared/types"],
"options": {
"jestConfig": "libs/shared/types/jest.config.ts",
"passWithNoTests": true
}
}
},
"tags": []
}
4 changes: 4 additions & 0 deletions libs/shared/types/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export type NominalType<T extends string> = { __type: T };
export type Seconds = number & NominalType<'Seconds'>;
export type Milliseconds = number & NominalType<'Milliseconds'>;
export type Pixels = number & NominalType<'Pixels'>;
19 changes: 19 additions & 0 deletions libs/shared/types/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"extends": "../../../tsconfig.base.json",
"files": [],
"include": [],
"references": [
{
"path": "./tsconfig.lib.json"
},
{
"path": "./tsconfig.spec.json"
}
],
"compilerOptions": {
"forceConsistentCasingInFileNames": true,
"strict": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true
}
}
10 changes: 10 additions & 0 deletions libs/shared/types/tsconfig.lib.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../../../dist/out-tsc",
"declaration": true,
"types": []
},
"include": ["**/*.ts"],
"exclude": ["jest.config.ts", "**/*.spec.ts"]
}
20 changes: 20 additions & 0 deletions libs/shared/types/tsconfig.spec.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../../../dist/out-tsc",
"module": "commonjs",
"types": ["jest", "node"]
},
"include": [
"jest.config.ts",
"**/*.test.ts",
"**/*.spec.ts",
"**/*.test.tsx",
"**/*.spec.tsx",
"**/*.test.js",
"**/*.spec.js",
"**/*.test.jsx",
"**/*.spec.jsx",
"**/*.d.ts"
]
}
1 change: 1 addition & 0 deletions libs/shared/ui/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from './lib/components/timeline/timeline-element/timeline-element';
export * from './lib/components/chat-card/chat-card';
export * from './lib/components/confirmation/confirmation';
export * from './lib/components/code-editor/code-editor';
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { render } from '@testing-library/react';

import TimelineElement from './timeline-element';

describe('TimelineElement', () => {
it('should render successfully', () => {
const { baseElement } = render(<TimelineElement />);
expect(baseElement).toBeTruthy();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { ComponentStory, ComponentMeta } from '@storybook/react';
import { Milliseconds } from '@streali/shared/types';
import { TimelineElement } from './timeline-element';

export default {
component: TimelineElement,
title: 'Timeline/Timeline Element',
} as ComponentMeta<typeof TimelineElement>;

const Template: ComponentStory<typeof TimelineElement> = (args) => (
<TimelineElement {...args} />
);

export const Primary = Template.bind({});
Primary.args = {
type: 'text',
title: 'Text 1',
duration: 743 as Milliseconds,
startTime: 1500 as Milliseconds,
totalTime: 5000 as Milliseconds,
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
import { Milliseconds, Pixels } from '@streali/shared/types';
import { pixelToTime, timeToPixel } from '@streali/shared/utils';
import interact from 'interactjs';
import { useEffect, useRef } from 'react';
import Icon from '../../icon/icon';

export interface TimelineElementProps {
onElementMove?: (startTime: Milliseconds) => void;
onElementResize?: (duration: Milliseconds) => void;
type: 'image' | 'video' | 'text' | 'sound' | 'lottie';
title: string;
duration?: Milliseconds;
startTime?: Milliseconds;
totalTime: Milliseconds;
onClick?: () => void;
}

export function TimelineElement(props: TimelineElementProps) {
const {
onElementMove,
onElementResize,
type,
title,
duration,
startTime,
totalTime,
onClick,
} = props;
const containerDrag = useRef<HTMLDivElement>(null);

const elementColor = {
image: 'bg-blue-500',
video: 'bg-red-500',
text: 'bg-green-500',
sound: 'bg-yellow-500',
lottie: 'bg-purple-500',
};

const elementIcon = {
image: 'image-line',
video: 'film-line',
text: 'text',
sound: 'music-fill',
lottie: 'pencil-ruler-2-line',
};

const initInteract = () => {
const container = interact('.draggable');

container
.draggable({
listeners: {
move: moveElement,
},
modifiers: [
interact.modifiers.restrictRect({
restriction: 'parent',
}),
],
})
.resizable({
edges: {
left: false,
right: true,
bottom: false,
top: false,
},
listeners: {
move: resizeElement,
},
});
};

const resizeElement = (event: any) => {
Object.assign(event.target.style, {
width: `${event.rect.width}px`,
});
onElementResize && onElementResize(pixelToTime(event.rect.width as Pixels));
};

const moveElement = (event: any) => {
const target = event.target;
const x = (parseFloat(target.getAttribute('data-x')) || 0) + event.dx;
target.style.left = `${x}px`;
target.setAttribute('data-x', x);
onElementMove && onElementMove(pixelToTime(x as Pixels));
};

useEffect(() => {
initInteract();
}, []);

return (
<div
className="w-full h-16 bg-black py-3"
style={{
width: `${timeToPixel(totalTime)}px`,
}}
ref={containerDrag}
>
<div
className={`h-full w-20 rounded draggable relative flex items-center px-1.5 overflow-hidden gap-2 ${elementColor[type]}`}
style={{
transform: `translateX(${timeToPixel(startTime as Milliseconds)}px)`,
width: `${timeToPixel(duration as Milliseconds)}px`,
}}
onClick={onClick}
>
<div className="w-7 h-7 rounded-sm flex items-center justify-center bg-white shrink-0">
<Icon name={elementIcon[type]} className="text-black" />
</div>
<p className="whitespace-nowrap font-bold text-sm">{title}</p>
</div>
</div>
);
}

export default TimelineElement;
1 change: 1 addition & 0 deletions libs/shared/utils/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from './axios/axios';
export * from './toast/toast';
export * from './timeline/time-converter';
9 changes: 9 additions & 0 deletions libs/shared/utils/src/timeline/time-converter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import type { Milliseconds, Pixels } from '@streali/shared/types';

export const timeToPixel = (time: Milliseconds) => {
return ((time / 10) * 2) as Pixels;
};

export const pixelToTime = (pixel: Pixels) => {
return ((pixel / 2) * 10) as Milliseconds;
};
1 change: 1 addition & 0 deletions tsconfig.base.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"@streali/shared/hooks": ["libs/shared/hooks/src/index.ts"],
"@streali/shared/mocks": ["libs/shared/mocks/src/index.ts"],
"@streali/shared/schema": ["libs/shared/schema/src/index.ts"],
"@streali/shared/types": ["libs/shared/types/src/index.ts"],
"@streali/shared/ui": ["libs/shared/ui/src/index.ts"],
"@streali/shared/utils": ["libs/shared/utils/src/index.ts"]
}
Expand Down
1 change: 1 addition & 0 deletions workspace.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"shared-hooks": "libs/shared/hooks",
"shared-mocks": "libs/shared/mocks",
"shared-schema": "libs/shared/schema",
"shared-types": "libs/shared/types",
"shared-ui": "libs/shared/ui",
"shared-ui-e2e": "apps/shared-ui-e2e",
"shared-utils": "libs/shared/utils"
Expand Down

0 comments on commit 70f50a0

Please sign in to comment.