From 2fcbac574bf3b3cf476e05b632eb7fc708eee5a5 Mon Sep 17 00:00:00 2001
From: Angelo Reale <12191809+angeloreale@users.noreply.github.com>
Date: Sun, 4 Aug 2024 18:41:14 +0100
Subject: [PATCH 01/18] ar(feat) DPCP-31: Audio Player
---
src/atoms/05_SystemIcon/SystemIcon.tsx | 2 +-
src/molecules/02_AudioPlayer/AudioPlayer.tsx | 106 ++++++++++++
.../__docs__/02-AudioPlayer.stories.tsx | 28 ++++
.../02_AudioPlayer/__docs__/AudioPlayer.mdx | 153 ++++++++++++++++++
.../02_AudioPlayer/__docs__/Example.tsx | 9 ++
.../__test__/02-AudioPlayer.test.tsx | 13 ++
src/molecules/02_AudioPlayer/index.ts | 3 +
7 files changed, 313 insertions(+), 1 deletion(-)
create mode 100644 src/molecules/02_AudioPlayer/AudioPlayer.tsx
create mode 100644 src/molecules/02_AudioPlayer/__docs__/02-AudioPlayer.stories.tsx
create mode 100644 src/molecules/02_AudioPlayer/__docs__/AudioPlayer.mdx
create mode 100644 src/molecules/02_AudioPlayer/__docs__/Example.tsx
create mode 100644 src/molecules/02_AudioPlayer/__test__/02-AudioPlayer.test.tsx
create mode 100644 src/molecules/02_AudioPlayer/index.ts
diff --git a/src/atoms/05_SystemIcon/SystemIcon.tsx b/src/atoms/05_SystemIcon/SystemIcon.tsx
index ae74c39..5d68dcb 100644
--- a/src/atoms/05_SystemIcon/SystemIcon.tsx
+++ b/src/atoms/05_SystemIcon/SystemIcon.tsx
@@ -2,7 +2,7 @@
// @atoms/SystemIcon.tsx
import { useMemo } from 'react';
import clsx from 'clsx';
-import { DreamPipColors } from '../../../tailwind.config.ts';
+import { DreamPipColors } from '../../../dist/tailwind.config.ts';
import * as Icons from './assets';
type Theme = 'light' | 'dark';
diff --git a/src/molecules/02_AudioPlayer/AudioPlayer.tsx b/src/molecules/02_AudioPlayer/AudioPlayer.tsx
new file mode 100644
index 0000000..5cc9260
--- /dev/null
+++ b/src/molecules/02_AudioPlayer/AudioPlayer.tsx
@@ -0,0 +1,106 @@
+/* eslint jsx-a11y/media-has-caption:0, no-nested-ternary:0, no-unused-vars:0, max-len:0, no-shadow:0, @typescript-eslint/no-explicit-any:0, object-curly-newline:0 */
+// @atoms/AudioPlayer.tsx
+import clsx from 'clsx';
+import { Fragment } from 'react';
+import Grid, {
+ EBleedVariant,
+ EGridVariant,
+} from '../../atoms/10_Grid/Grid.tsx';
+
+export const DEFAULT_TRACKS = [
+ {
+ id: 'dreampip__chan_0000',
+ className: '',
+ onPlay: () => {},
+ title: 'This is the track playing',
+ url: 'https://www.dreampip.com/api/nexus/audio',
+ isPlaying: false,
+ },
+ {
+ id: 'dreampip__chan_0001',
+ className: '',
+ onPlay: () => {},
+ title: 'This is the track playing',
+ url: 'https://www.dreampip.com/api/nexus/audio/1',
+ isPlaying: false,
+ },
+];
+
+export enum EAudioPlayerVariant {
+ DEFAULT = 'default',
+}
+
+export interface IBackgroundImage {
+ mobile?: string;
+ desktop?: string;
+}
+
+export interface IAudioTrack {
+ id?: string;
+ className?: string;
+ onPlay?: () => void;
+ title?: string;
+ url?: string;
+ isPlaying?: boolean;
+}
+
+export interface IAudioPlayer {
+ id?: string;
+ className?: string;
+ tracks?: IAudioTrack[];
+ onPlayTrack?: () => void;
+ theme?: 'light' | 'dark';
+}
+
+export const HAudioPlayer = function ({
+ id = 'atom__AudioPlayer',
+ className = '',
+ tracks = DEFAULT_TRACKS,
+ onPlayTrack = () => {},
+ theme = 'light',
+}: IAudioPlayer) {
+ const gridSx = [
+ {
+ [`class02
+ grid
+ sm:grid-cols-12
+ sm:!gap-a0
+ md:!gap-a4
+ `]: true,
+ },
+ ];
+
+ const gridStyles = `${clsx(gridSx)} ${className}`;
+
+ onPlayTrack();
+
+ return (
+
+
+
+ );
+};
+
+export default HAudioPlayer;
diff --git a/src/molecules/02_AudioPlayer/__docs__/02-AudioPlayer.stories.tsx b/src/molecules/02_AudioPlayer/__docs__/02-AudioPlayer.stories.tsx
new file mode 100644
index 0000000..e0fcb97
--- /dev/null
+++ b/src/molecules/02_AudioPlayer/__docs__/02-AudioPlayer.stories.tsx
@@ -0,0 +1,28 @@
+// @atoms/02_AudioPlayer/__test__/02-AudioPlayer.stories.tsx
+import type { Meta, StoryObj } from '@storybook/react';
+import Example from './Example.tsx';
+import { EAudioPlayerVariant } from '../AudioPlayer';
+
+const meta: Meta = {
+ title: 'Molecules/02-AudioPlayer',
+ component: Example,
+ argTypes: {
+ theme: {
+ options: ['light', 'dark'],
+ control: { type: 'radio' },
+ },
+ variant: {
+ options: Object.values(EAudioPlayerVariant),
+ control: { type: 'radio' },
+ },
+ },
+};
+
+export default meta;
+type Story = StoryObj;
+
+export const Default: Story = {
+ args: {
+ variant: EAudioPlayerVariant.DEFAULT,
+ },
+};
diff --git a/src/molecules/02_AudioPlayer/__docs__/AudioPlayer.mdx b/src/molecules/02_AudioPlayer/__docs__/AudioPlayer.mdx
new file mode 100644
index 0000000..d4e4912
--- /dev/null
+++ b/src/molecules/02_AudioPlayer/__docs__/AudioPlayer.mdx
@@ -0,0 +1,153 @@
+import { Canvas, Meta } from "@storybook/blocks";
+import Example from "./Example.tsx";
+import * as AudioPlayer from "./02-AudioPlayer.stories.tsx";
+
+
+
+# AudioPlayer
+
+AudioPlayer component with different props.
+
+#### Example
+
+
+
+## Usage
+
+```ts
+import { AudioPlayer } from "@dreampipcom/oneiros";
+
+export const DEFAULT_CARDS = [
+ {
+ id: 'molecule__AudioPlayer__card--02',
+ className: '',
+ onLike: () => {},
+ title: 'This is a card example #02',
+ where: 'Barcelona (Catalonia)',
+ when: 'February',
+ price: '299€',
+ link: 'https://dreampip.com',
+ badgeLink: 'https://dreampip.com',
+ rating: '3/5',
+ selected: false,
+ },
+ {
+ id: 'molecule__AudioPlayer__card--02',
+ className: '',
+ onLike: () => {},
+ title: 'This is a card example #02',
+ where: 'Barcelona (Catalonia)',
+ when: 'February',
+ price: '299€',
+ link: 'https://dreampip.com',
+ badgeLink: 'https://dreampip.com',
+ rating: '4.5/5',
+ selected: true,
+ },
+ {
+ id: 'molecule__AudioPlayer__card--03',
+ className: '',
+ onLike: () => {},
+ title: 'This is a card example #03',
+ where: 'Barcelona (Catalonia)',
+ when: 'February',
+ price: '299€',
+ link: 'https://dreampip.com',
+ badgeLink: 'https://dreampip.com',
+ rating: '3/5',
+ selected: false,
+ },
+ {
+ id: 'molecule__AudioPlayer__card--04',
+ className: '',
+ onLike: () => {},
+ title: 'This is a card example #04',
+ where: 'Barcelona (Catalonia)',
+ when: 'February',
+ price: '299€',
+ link: 'https://dreampip.com',
+ badgeLink: 'https://dreampip.com',
+ rating: '2/5',
+ selected: false,
+ },
+ {
+ id: 'molecule__AudioPlayer__card--05',
+ className: '',
+ onLike: () => {},
+ title: 'This is a card example #05',
+ where: 'Barcelona (Catalonia)',
+ when: 'February',
+ price: '299€',
+ link: 'https://dreampip.com',
+ badgeLink: 'https://dreampip.com',
+ rating: '3.5/5',
+ selected: false,
+ },
+ {
+ id: 'molecule__AudioPlayer__card--06',
+ className: '',
+ onLike: () => {},
+ title: 'This is a card example #06',
+ where: 'Barcelona (Catalonia)',
+ when: 'February',
+ price: '299€',
+ link: 'https://dreampip.com',
+ badgeLink: 'https://dreampip.com',
+ rating: '3.6/5',
+ selected: false,
+ },
+ {
+ id: 'molecule__AudioPlayer__card--07',
+ className: '',
+ onLike: () => {},
+ title: 'This is a card example #07',
+ where: 'Barcelona (Catalonia)',
+ when: 'February',
+ price: '299€',
+ link: 'https://dreampip.com',
+ badgeLink: 'https://dreampip.com',
+ rating: '5/5',
+ selected: false,
+ },
+ {
+ id: 'molecule__AudioPlayer__card--08',
+ className: '',
+ onLike: () => {},
+ title: 'This is a card example #08',
+ where: 'Barcelona (Catalonia)',
+ when: 'February',
+ price: '299€',
+ link: 'https://dreampip.com',
+ badgeLink: 'https://dreampip.com',
+ rating: '4.8/5',
+ selected: false,
+ },
+ {
+ id: 'molecule__AudioPlayer__card--09',
+ className: '',
+ onLike: () => {},
+ title: 'This is a card example #08',
+ where: 'Barcelona (Catalonia)',
+ when: 'February',
+ price: '299€',
+ link: 'https://dreampip.com',
+ badgeLink: 'https://dreampip.com',
+ rating: '3/5',
+ selected: false,
+ },
+];
+
+const App = () => {
+ return (
+
+ );
+};
+
+export default Example;
+```
+
+#### Arguments
+
+- **cards** — An array of Cards props, where each index represents a Card in the grid.
diff --git a/src/molecules/02_AudioPlayer/__docs__/Example.tsx b/src/molecules/02_AudioPlayer/__docs__/Example.tsx
new file mode 100644
index 0000000..cc59d21
--- /dev/null
+++ b/src/molecules/02_AudioPlayer/__docs__/Example.tsx
@@ -0,0 +1,9 @@
+// @atoms/02_AudioPlayer/__test__/Example.tsx
+import React, { FC } from 'react';
+import AudioPlayer, { ICard } from '../AudioPlayer.tsx';
+
+const Example: FC = function ({ theme = 'light', cards }) {
+ return ;
+};
+
+export default Example;
diff --git a/src/molecules/02_AudioPlayer/__test__/02-AudioPlayer.test.tsx b/src/molecules/02_AudioPlayer/__test__/02-AudioPlayer.test.tsx
new file mode 100644
index 0000000..feaec0a
--- /dev/null
+++ b/src/molecules/02_AudioPlayer/__test__/02-AudioPlayer.test.tsx
@@ -0,0 +1,13 @@
+// @atoms/02_Card/__test__/02-AudioPlayer.test.tsx
+import React from 'react';
+import { describe, expect, it } from 'vitest';
+import { render } from '@testing-library/react';
+import AudioPlayer from '../AudioPlayer';
+
+describe('AudioPlayer component', () => {
+ it('AudioPlayer should render correctly', () => {
+ const result = render();
+ const component = result.container.querySelector('#grid-atom--test');
+ expect(component).toBeInTheDocument();
+ });
+});
diff --git a/src/molecules/02_AudioPlayer/index.ts b/src/molecules/02_AudioPlayer/index.ts
new file mode 100644
index 0000000..91d7b32
--- /dev/null
+++ b/src/molecules/02_AudioPlayer/index.ts
@@ -0,0 +1,3 @@
+// @atoms/AudioPlayer/index.ts
+export { default as AudioPlayer, EAudioPlayerVariant } from './AudioPlayer';
+export const AudioPlayerName = 'AudioPlayer';
From a3e793f54b50c589dac5182a7815271d4ef183b4 Mon Sep 17 00:00:00 2001
From: Angelo Reale <12191809+angeloreale@users.noreply.github.com>
Date: Sun, 4 Aug 2024 19:34:32 +0100
Subject: [PATCH 02/18] ar(feat) DPCP-31: Audio Player
---
src/molecules/02_AudioPlayer/AudioPlayer.tsx | 102 +++++++++++++++----
1 file changed, 84 insertions(+), 18 deletions(-)
diff --git a/src/molecules/02_AudioPlayer/AudioPlayer.tsx b/src/molecules/02_AudioPlayer/AudioPlayer.tsx
index 5cc9260..e065232 100644
--- a/src/molecules/02_AudioPlayer/AudioPlayer.tsx
+++ b/src/molecules/02_AudioPlayer/AudioPlayer.tsx
@@ -1,12 +1,16 @@
/* eslint jsx-a11y/media-has-caption:0, no-nested-ternary:0, no-unused-vars:0, max-len:0, no-shadow:0, @typescript-eslint/no-explicit-any:0, object-curly-newline:0 */
// @atoms/AudioPlayer.tsx
import clsx from 'clsx';
-import { Fragment } from 'react';
+import { Fragment, useRef, useState, useEffect } from 'react';
import Grid, {
EBleedVariant,
EGridVariant,
} from '../../atoms/10_Grid/Grid.tsx';
+import { Button, ButtonVariant, EButtonTheme } from '../../atoms/01_Button';
+import { Typography } from '../../atoms/02_Typography';
+import { ESystemIcon } from '../../atoms/05_SystemIcon';
+
export const DEFAULT_TRACKS = [
{
id: 'dreampip__chan_0000',
@@ -49,6 +53,8 @@ export interface IAudioPlayer {
className?: string;
tracks?: IAudioTrack[];
onPlayTrack?: () => void;
+ nativeControls?: boolean;
+ prompt?: string;
theme?: 'light' | 'dark';
}
@@ -57,22 +63,62 @@ export const HAudioPlayer = function ({
className = '',
tracks = DEFAULT_TRACKS,
onPlayTrack = () => {},
+ nativeControls = false,
+ prompt = 'Rotation portals',
theme = 'light',
}: IAudioPlayer) {
+ const audioElement = useRef();
+ const [status, setStatus] = useState('stopped');
+ const [title, setTitle] = useState(prompt);
const gridSx = [
{
[`class02
grid
sm:grid-cols-12
sm:!gap-a0
- md:!gap-a4
+ md:!gap-a1
+ content-center
+ items-center
+ align-center
+ justify-center
`]: true,
},
];
const gridStyles = `${clsx(gridSx)} ${className}`;
- onPlayTrack();
+ const handlePlay = () => {
+ onPlayTrack();
+ audioElement.current.isPlaying = status === 'playing';
+
+ if (audioElement?.current?.isPlaying) {
+ audioElement.current.pause();
+ audioElement.current.currentTime = 0;
+ setStatus('stopped');
+ } else {
+ audioElement.current.play();
+ setStatus('playing');
+ }
+ };
+
+ const handleStatus = (status: string, options: { title?: string }) => () => {
+ setStatus(status);
+ setTitle(options?.title || prompt);
+ };
+
+ useEffect(() => {
+ const handlePlay = handleStatus('playing', {
+ title: audioElement.current.getAttribute('data-title'),
+ });
+ const handleStop = handleStatus('stopped');
+ audioElement.current.addEventListener('play', handlePlay);
+ audioElement.current.addEventListener('ended', handleStop);
+
+ return () => {
+ audioElement.current.removeEventListener('play', handlePlay);
+ audioElement.current.removeEventListener('ended', handleStop);
+ };
+ }, [status]);
return (
-
+ {title}
+
);
};
From e98418565be578f5b13c8bfa014b85c29fe9d51e Mon Sep 17 00:00:00 2001
From: Angelo Reale <12191809+angeloreale@users.noreply.github.com>
Date: Sun, 4 Aug 2024 19:37:01 +0100
Subject: [PATCH 03/18] ar(feat) DPCP-31: Audio Player
---
src/atoms/05_SystemIcon/SystemIcon.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/atoms/05_SystemIcon/SystemIcon.tsx b/src/atoms/05_SystemIcon/SystemIcon.tsx
index 5d68dcb..ae74c39 100644
--- a/src/atoms/05_SystemIcon/SystemIcon.tsx
+++ b/src/atoms/05_SystemIcon/SystemIcon.tsx
@@ -2,7 +2,7 @@
// @atoms/SystemIcon.tsx
import { useMemo } from 'react';
import clsx from 'clsx';
-import { DreamPipColors } from '../../../dist/tailwind.config.ts';
+import { DreamPipColors } from '../../../tailwind.config.ts';
import * as Icons from './assets';
type Theme = 'light' | 'dark';
From 7bf92c7cbe2c81486de2ce8ce1fee045b88ed0f1 Mon Sep 17 00:00:00 2001
From: Angelo Reale <12191809+angeloreale@users.noreply.github.com>
Date: Sun, 4 Aug 2024 19:41:17 +0100
Subject: [PATCH 04/18] ar(feat) DPCP-31: Audio Player
---
src/molecules/02_AudioPlayer/AudioPlayer.tsx | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/src/molecules/02_AudioPlayer/AudioPlayer.tsx b/src/molecules/02_AudioPlayer/AudioPlayer.tsx
index e065232..c40bcb9 100644
--- a/src/molecules/02_AudioPlayer/AudioPlayer.tsx
+++ b/src/molecules/02_AudioPlayer/AudioPlayer.tsx
@@ -67,7 +67,7 @@ export const HAudioPlayer = function ({
prompt = 'Rotation portals',
theme = 'light',
}: IAudioPlayer) {
- const audioElement = useRef();
+ const audioElement = useRef();
const [status, setStatus] = useState('stopped');
const [title, setTitle] = useState(prompt);
const gridSx = [
@@ -89,14 +89,14 @@ export const HAudioPlayer = function ({
const handlePlay = () => {
onPlayTrack();
- audioElement.current.isPlaying = status === 'playing';
+ audioElement?.current?.isPlaying = status === 'playing';
if (audioElement?.current?.isPlaying) {
audioElement.current.pause();
audioElement.current.currentTime = 0;
setStatus('stopped');
} else {
- audioElement.current.play();
+ audioElement?.current?.play();
setStatus('playing');
}
};
@@ -111,12 +111,12 @@ export const HAudioPlayer = function ({
title: audioElement.current.getAttribute('data-title'),
});
const handleStop = handleStatus('stopped');
- audioElement.current.addEventListener('play', handlePlay);
- audioElement.current.addEventListener('ended', handleStop);
+ audioElement?.current?.addEventListener('play', handlePlay);
+ audioElement?.current?.addEventListener('ended', handleStop);
return () => {
- audioElement.current.removeEventListener('play', handlePlay);
- audioElement.current.removeEventListener('ended', handleStop);
+ audioElement?.current?.removeEventListener('play', handlePlay);
+ audioElement?.current?.removeEventListener('ended', handleStop);
};
}, [status]);
From 3f032c2382920a87b9f7d4938366ddbcf9edc028 Mon Sep 17 00:00:00 2001
From: Angelo Reale <12191809+angeloreale@users.noreply.github.com>
Date: Sun, 4 Aug 2024 19:41:39 +0100
Subject: [PATCH 05/18] ar(feat) DPCP-31: Audio Player
---
src/molecules/02_AudioPlayer/AudioPlayer.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/molecules/02_AudioPlayer/AudioPlayer.tsx b/src/molecules/02_AudioPlayer/AudioPlayer.tsx
index c40bcb9..ee0461b 100644
--- a/src/molecules/02_AudioPlayer/AudioPlayer.tsx
+++ b/src/molecules/02_AudioPlayer/AudioPlayer.tsx
@@ -149,7 +149,7 @@ export const HAudioPlayer = function ({