Skip to content

Commit

Permalink
feat: add basic sound components
Browse files Browse the repository at this point in the history
  • Loading branch information
remvze committed Oct 6, 2023
1 parent 8d7e4d2 commit 4adb8bf
Show file tree
Hide file tree
Showing 8 changed files with 197 additions and 1 deletion.
1 change: 1 addition & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
"prettier/prettier": "error",
"sort-keys-fix/sort-keys-fix": ["warn", "asc"],
"sort-destructure-keys/sort-destructure-keys": "warn",
"jsx-a11y/no-static-element-interactions": "off",
"react/jsx-sort-props": [
"warn",
{
Expand Down
5 changes: 4 additions & 1 deletion src/components/category/category.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { useMemo } from 'react';

import { Sounds } from '@/components/sounds';
import { cn } from '@/helpers/styles';

import styles from './category.module.css';
Expand All @@ -12,7 +13,7 @@ interface CategoryProps {
sounds: Array<{ label: string; src: string }>;
}

export function Category({ color, icon, title }: CategoryProps) {
export function Category({ color, icon, sounds, title }: CategoryProps) {
const colorStyle = useMemo(() => {
const colorToStyle: { [color: string]: string } = {
green: styles.green,
Expand All @@ -30,6 +31,8 @@ export function Category({ color, icon, title }: CategoryProps) {
</div>

<h2 className={styles.title}>{title}</h2>

<Sounds color={color} sounds={sounds} />
</div>
);
}
1 change: 1 addition & 0 deletions src/components/sound/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { Sound } from './sound';
119 changes: 119 additions & 0 deletions src/components/sound/sound.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
.sound {
position: relative;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 30px 20px;
border: 1px solid var(--color-neutral-200);
border-radius: 10px;
background: linear-gradient(var(--color-neutral-100), transparent);
text-align: center;

&:not(.selected)::before {
position: absolute;
top: -1px;
left: 0;
width: 100%;
height: 1px;
background: linear-gradient(
90deg,
transparent,
var(--color-neutral-300),
transparent
);
content: '';
}

&.selected {
&.green {
border: 2px solid #4ade80;
box-shadow: 0 10px 20px #4ade8033;
}

&.indigo {
border: 2px solid #818cf8;
box-shadow: 0 10px 20px #818cf833;
}
}

& h3 {
font-family: var(--font-heading);
font-size: 15px;
font-weight: 600;
line-height: 1.6;
}

& input {
width: 100%;
max-width: 120px;
margin-top: 12px;

/********** Range Input Styles **********/

/* Range Reset */
appearance: none;
background: transparent;
cursor: pointer;

/* Removes default focus */
&:focus {
outline: none;
}

&:disabled {
cursor: default;
opacity: 0.5;
pointer-events: none;
}

/***** Chrome, Safari, Opera and Edge Chromium styles *****/

&::-webkit-slider-runnable-track {
height: 0.5rem;
border-radius: 0.5rem;
background-color: #27272a;
}

&::-webkit-slider-thumb {
width: 14px;
height: 14px;
border: 1px solid #52525b;
border-radius: 50%;
margin-top: -3px;
appearance: none;
background-color: #3f3f46;
}

&:not(:disabled):focus::-webkit-slider-thumb {
border: 1px solid #053a5f;
outline: 3px solid #053a5f;
outline-offset: 0.125rem;
}

/******** Firefox styles ********/

&::-moz-range-track {
height: 0.5rem;
border-radius: 0.5rem;
background-color: #27272a;
}

&::-moz-range-thumb {
width: 14px;
height: 14px;
border: none;
border: 1px solid #52525b;
border-radius: 0;
border-radius: 50%;
margin-top: -3px;
background-color: #3f3f46;
}

&:not(:disabled):focus::-moz-range-thumb {
border: 1px solid #053a5f;
outline: 3px solid #053a5f;
outline-offset: 0.125rem;
}
}
}
47 changes: 47 additions & 0 deletions src/components/sound/sound.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { useState, useMemo, useEffect } from 'react';

import { cn } from '@/helpers/styles';

import styles from './sound.module.css';

interface SoundProps {
color: string;
sound: { label: string; src: string };
}

export function Sound({ color, sound }: SoundProps) {
const [isSelected, setIsSelected] = useState(false);
const [volume, setVolume] = useState(0.5);

const colorStyle = useMemo(() => {
const colorToStyle: { [color: string]: string } = {
green: styles.green,
indigo: styles.indigo,
};

return colorToStyle[color];
}, [color]);

useEffect(() => {
if (!isSelected) setVolume(0.5);
}, [isSelected]);

return (
<div
className={cn(styles.sound, isSelected && styles.selected, colorStyle)}
onClick={() => setIsSelected(prev => !prev)}
onKeyDown={() => setIsSelected(prev => !prev)}
>
<h3>{sound.label}</h3>
<input
disabled={!isSelected}
max={100}
min={0}
type="range"
value={volume * 100}
onChange={e => isSelected && setVolume(Number(e.target.value) / 100)}
onClick={e => e.stopPropagation()}
/>
</div>
);
}
1 change: 1 addition & 0 deletions src/components/sounds/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { Sounds } from './sounds';
6 changes: 6 additions & 0 deletions src/components/sounds/sounds.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.sounds {
display: grid;
margin-top: 20px;
gap: 20px;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
}
18 changes: 18 additions & 0 deletions src/components/sounds/sounds.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Sound } from '@/components/sound';

import styles from './sounds.module.css';

interface SoundsProps {
color: string;
sounds: Array<{ label: string; src: string }>;
}

export function Sounds({ color, sounds }: SoundsProps) {
return (
<div className={styles.sounds}>
{sounds.map(sound => (
<Sound color={color} key={sound.label} sound={sound} />
))}
</div>
);
}

0 comments on commit 4adb8bf

Please sign in to comment.