94 lines
2.0 KiB
TypeScript
94 lines
2.0 KiB
TypeScript
import { Box, Pressable, Text } from 'native-base';
|
|
import { StyleProp, ViewStyle } from 'react-native';
|
|
import { PianoKey, NoteNameBehavior, octaveKeys, keyToStr } from '../../models/Piano';
|
|
|
|
type PianoKeyProps = {
|
|
pianoKey: PianoKey;
|
|
showNoteName: NoteNameBehavior;
|
|
bg: string;
|
|
bgPressed: string;
|
|
bgHovered: string;
|
|
onKeyDown: () => void;
|
|
onKeyUp: () => void;
|
|
text: Parameters<typeof Text>[0];
|
|
style: StyleProp<ViewStyle>;
|
|
};
|
|
|
|
const isNoteVisible = (
|
|
noteNameBehavior: NoteNameBehavior,
|
|
isPressed: boolean,
|
|
isHovered: boolean
|
|
) => {
|
|
if (noteNameBehavior === NoteNameBehavior.always) return true;
|
|
if (noteNameBehavior === NoteNameBehavior.never) return false;
|
|
|
|
if (noteNameBehavior === NoteNameBehavior.onpress) {
|
|
return isPressed;
|
|
} else if (noteNameBehavior === NoteNameBehavior.onhover) {
|
|
return isHovered;
|
|
}
|
|
return false;
|
|
};
|
|
|
|
const PianoKeyComp = ({
|
|
pianoKey,
|
|
showNoteName,
|
|
bg,
|
|
bgPressed,
|
|
bgHovered,
|
|
onKeyDown,
|
|
onKeyUp,
|
|
text,
|
|
style,
|
|
}: PianoKeyProps) => {
|
|
const textDefaultProps = {
|
|
style: {
|
|
userSelect: 'none',
|
|
WebkitUserSelect: 'none',
|
|
MozUserSelect: 'none',
|
|
msUserSelect: 'none',
|
|
},
|
|
fontSize: 'xl',
|
|
color: 'black',
|
|
} as Parameters<typeof Text>[0];
|
|
|
|
const textProps = { ...textDefaultProps, ...text };
|
|
return (
|
|
<Pressable onPressIn={onKeyDown} onPressOut={onKeyUp} style={style}>
|
|
{({ isHovered, isPressed }) => (
|
|
<Box
|
|
bg={(() => {
|
|
if (isPressed) return bgPressed;
|
|
if (isHovered) return bgHovered;
|
|
return bg;
|
|
})()}
|
|
w="100%"
|
|
h="100%"
|
|
borderWidth="1px"
|
|
borderColor="black"
|
|
justifyContent="flex-end"
|
|
alignItems="center"
|
|
>
|
|
{isNoteVisible(showNoteName, isPressed, isHovered) && (
|
|
<Text {...textProps}>{keyToStr(pianoKey, false)}</Text>
|
|
)}
|
|
</Box>
|
|
)}
|
|
</Pressable>
|
|
);
|
|
};
|
|
|
|
PianoKeyComp.defaultProps = {
|
|
key: octaveKeys[0],
|
|
showNoteNames: NoteNameBehavior.onhover,
|
|
keyBg: 'white',
|
|
keyBgPressed: 'gray.200',
|
|
keyBgHovered: 'gray.100',
|
|
onKeyDown: () => {},
|
|
onKeyUp: () => {},
|
|
text: {},
|
|
style: {},
|
|
};
|
|
|
|
export default PianoKeyComp;
|