Browse Source

Add labels, change props

Add function prop for labelling keys. Also changed some props for clearer usage.
master
TheoryOfNekomata 4 years ago
parent
commit
47c729bbc7
13 changed files with 899 additions and 686 deletions
  1. +0
    -1
      docs/example.38168819.js.map
  2. +16
    -16
      docs/example.4d83155a.js
  3. +1
    -0
      docs/example.4d83155a.js.map
  4. +1
    -1
      docs/index.html
  5. +1
    -1
      example/index.tsx
  6. +1
    -1
      package.json
  7. +28
    -1
      src/components/AccidentalKey/AccidentalKey.tsx
  8. +80
    -13
      src/components/Keyboard/Keyboard.stories.tsx
  9. +35
    -20
      src/components/Keyboard/Keyboard.tsx
  10. +29
    -1
      src/components/NaturalKey/NaturalKey.tsx
  11. +364
    -339
      src/components/StyledAccidentalKey/StyledAccidentalKey.tsx
  12. +316
    -292
      src/components/StyledNaturalKey/StyledNaturalKey.tsx
  13. +27
    -0
      src/services/constants.ts

+ 0
- 1
docs/example.38168819.js.map
File diff suppressed because it is too large
View File


docs/example.4d83155a.js
File diff suppressed because it is too large
View File


+ 1
- 0
docs/example.4d83155a.js.map
File diff suppressed because it is too large
View File


+ 1
- 1
docs/index.html View File

@@ -1,2 +1,2 @@
<!DOCTYPE html><html lang="en-PH"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,shrink-to-fit=no"><title>Demo | React Musical Keyboard</title><meta name="description" content="@theoryofnekomata/react-musical-keyboard"><style>:root{--color-channel-0:#f55;--color-channel-1:#ff0;--color-channel-2:#0a0;--color-channel-3:#05a;--color-channel-4:#a0f;--color-channel-5:#a00;--color-channel-6:#a50;--color-channel-7:#fa0;--color-channel-8:#0f0;--color-channel-9:#0aa;--color-channel-10:#0ff;--color-channel-11:#f0a;--color-channel-12:#aa0;--color-channel-13:#550;--color-channel-14:#50a;--color-channel-15:#f5f}html{color:#fff;background-color:#000;font-family:system-ui,sans-serif}body,html{width:100%;height:100%}body{margin:0;display:grid;grid-template-areas:"channel instrument instrument" "background background background" "keyboard keyboard keyboard";grid-template-columns:5rem auto auto;grid-template-rows:3rem auto 15rem}#channel{grid-area:channel}#channel,#instrument{-webkit-appearance:none;border:0;outline:0;background-color:initial;color:inherit;font:inherit;padding:0 1rem}#instrument{grid-area:instrument}#keyboard{grid-area:keyboard;width:100%;position:relative;overflow-x:auto;color:#000;background-color:#fff;cursor:pointer}#keyboard-scroll{width:750%;height:100%;top:0;left:0;position:absolute}@media (min-width:1080px){body{grid-template-rows:5rem auto 5rem}#keyboard-scroll{width:100%}}</style></head><body> <script src="example.38168819.js"></script>
<!DOCTYPE html><html lang="en-PH"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,shrink-to-fit=no"><title>Demo | React Musical Keyboard</title><meta name="description" content="@theoryofnekomata/react-musical-keyboard"><style>:root{--color-channel-0:#f55;--color-channel-1:#ff0;--color-channel-2:#0a0;--color-channel-3:#05a;--color-channel-4:#a0f;--color-channel-5:#a00;--color-channel-6:#a50;--color-channel-7:#fa0;--color-channel-8:#0f0;--color-channel-9:#0aa;--color-channel-10:#0ff;--color-channel-11:#f0a;--color-channel-12:#aa0;--color-channel-13:#550;--color-channel-14:#50a;--color-channel-15:#f5f}html{color:#fff;background-color:#000;font-family:system-ui,sans-serif}body,html{width:100%;height:100%}body{margin:0;display:grid;grid-template-areas:"channel instrument instrument" "background background background" "keyboard keyboard keyboard";grid-template-columns:5rem auto auto;grid-template-rows:3rem auto 15rem}#channel{grid-area:channel}#channel,#instrument{-webkit-appearance:none;border:0;outline:0;background-color:initial;color:inherit;font:inherit;padding:0 1rem}#instrument{grid-area:instrument}#keyboard{grid-area:keyboard;width:100%;position:relative;overflow-x:auto;color:#000;background-color:#fff;cursor:pointer}#keyboard-scroll{width:750%;height:100%;top:0;left:0;position:absolute}@media (min-width:1080px){body{grid-template-rows:5rem auto 5rem}#keyboard-scroll{width:100%}}</style></head><body> <script src="example.4d83155a.js"></script>
</body></html> </body></html>

+ 1
- 1
example/index.tsx View File

@@ -117,7 +117,7 @@ const App = () => {
<Keyboard <Keyboard
startKey={0} startKey={0}
endKey={127} endKey={127}
keyChannels={keyChannels}
keysOn={keyChannels}
height="100%" height="100%"
keyboardVelocity={0.75} keyboardVelocity={0.75}
onChange={Channel.handle({ setKeyChannels, generator: generator.current!, channel, })} onChange={Channel.handle({ setKeyChannels, generator: generator.current!, channel, })}


+ 1
- 1
package.json View File

@@ -1,5 +1,5 @@
{ {
"version": "1.1.3",
"version": "1.1.4",
"license": "MIT", "license": "MIT",
"main": "dist/index.js", "main": "dist/index.js",
"typings": "dist/index.d.ts", "typings": "dist/index.d.ts",


+ 28
- 1
src/components/AccidentalKey/AccidentalKey.tsx View File

@@ -1,6 +1,20 @@
import * as React from 'react' import * as React from 'react'
import * as PropTypes from 'prop-types'
import {
BOTTOM_CSS_ATTRIBUTES,
LEFT_CSS_ATTRIBUTES,
WIDTH_CSS_ATTRIBUTES,
ORIENTATIONS,
} from '../../services/constants'


const AccidentalKey: React.FC = () => (
const propTypes = {
label: PropTypes.string,
orientation: PropTypes.oneOf(ORIENTATIONS),
}

type Props = PropTypes.InferProps<typeof propTypes>

const AccidentalKey: React.FC<Props> = ({ label = '', orientation = 0 }) => (
<div <div
style={{ style={{
width: '100%', width: '100%',
@@ -22,6 +36,19 @@ const AccidentalKey: React.FC = () => (
backgroundColor: `var(--color-active-key, Highlight)`, backgroundColor: `var(--color-active-key, Highlight)`,
}} }}
/> />
<div
style={{
position: 'absolute',
display: 'grid',
placeContent: 'center',
filter: 'invert(100)',
[BOTTOM_CSS_ATTRIBUTES[orientation || 0]]: 0,
[LEFT_CSS_ATTRIBUTES[orientation || 0]]: 0,
[WIDTH_CSS_ATTRIBUTES[orientation || 0]]: '100%',
}}
>
{label}
</div>
</div> </div>
) )




+ 80
- 13
src/components/Keyboard/Keyboard.stories.tsx View File

@@ -1,8 +1,7 @@
import * as React from 'react' import * as React from 'react'
import * as PropTypes from 'prop-types'
import StyledAccidentalKey from '../StyledAccidentalKey/StyledAccidentalKey' import StyledAccidentalKey from '../StyledAccidentalKey/StyledAccidentalKey'
import StyledNaturalKey from '../StyledNaturalKey/StyledNaturalKey' import StyledNaturalKey from '../StyledNaturalKey/StyledNaturalKey'
import Keyboard, { propTypes } from './Keyboard'
import Keyboard, { Props } from './Keyboard'


const Wrapper: React.FC = (props) => ( const Wrapper: React.FC = (props) => (
<div <div
@@ -33,8 +32,6 @@ export default {
title: 'Keyboard', title: 'Keyboard',
} }


type Props = PropTypes.InferProps<typeof propTypes>

// By passing optional props to this story, you can control the props of the component when // By passing optional props to this story, you can control the props of the component when
// you consume the story in a test. // you consume the story in a test.
export const Default = (props?: Partial<Props>) => ( export const Default = (props?: Partial<Props>) => (
@@ -49,13 +46,13 @@ export const WithActiveKeys = (props?: Partial<Props>) => (
{...props} {...props}
startKey={21} startKey={21}
endKey={108} endKey={108}
keyChannels={[
keysOn={[
{ {
key: 60, key: 60,
velocity: 1, velocity: 1,
}, },
{ {
key: 64,
key: 63,
velocity: 1, velocity: 1,
}, },
{ {
@@ -86,7 +83,7 @@ export const Styled = (props?: Partial<Props>) => (
{...props} {...props}
startKey={21} startKey={21}
endKey={108} endKey={108}
keyChannels={[
keysOn={[
{ {
key: 60, key: 60,
velocity: 1, velocity: 1,
@@ -123,7 +120,7 @@ export const AnotherStyled = (props?: Partial<Props>) => (
{...props} {...props}
startKey={21} startKey={21}
endKey={108} endKey={108}
keyChannels={[
keysOn={[
{ {
key: 60, key: 60,
velocity: 1, velocity: 1,
@@ -161,7 +158,7 @@ export const DarkStyled = (props?: Partial<Props>) => (
{...props} {...props}
startKey={21} startKey={21}
endKey={108} endKey={108}
keyChannels={[
keysOn={[
{ {
key: 60, key: 60,
velocity: 1, velocity: 1,
@@ -226,7 +223,7 @@ const HasMapComponent = (props: any) => {
{...props} {...props}
startKey={21} startKey={21}
endKey={108} endKey={108}
keyChannels={keyChannels}
keysOn={keyChannels}
onChange={handleKeyOn} onChange={handleKeyOn}
keyboardMapping={{ keyboardMapping={{
KeyQ: 60, KeyQ: 60,
@@ -279,19 +276,19 @@ export const Mirrored = () => <HasMapComponent mirrored />


export const Checkbox = (props?: Partial<Props>) => ( export const Checkbox = (props?: Partial<Props>) => (
<Wrapper> <Wrapper>
<Keyboard {...props} startKey={21} endKey={108} behavior="checkbox" name="checkbox" />
<Keyboard {...props} startKey={21} endKey={108} fallbackBehavior="checkbox" name="checkbox" />
</Wrapper> </Wrapper>
) )


export const Radio = (props?: Partial<Props>) => ( export const Radio = (props?: Partial<Props>) => (
<Wrapper> <Wrapper>
<Keyboard {...props} startKey={21} endKey={108} behavior="radio" name="radio" />
<Keyboard {...props} startKey={21} endKey={108} fallbackBehavior="radio" name="radio" />
</Wrapper> </Wrapper>
) )


export const Link = (props?: Partial<Props>) => ( export const Link = (props?: Partial<Props>) => (
<Wrapper> <Wrapper>
<Keyboard {...props} startKey={21} endKey={108} behavior="link" href={(key) => `?key=${key}`} />
<Keyboard {...props} startKey={21} endKey={108} fallbackBehavior="link" href={(key) => `?key=${key}`} />
</Wrapper> </Wrapper>
) )


@@ -314,3 +311,73 @@ export const Rotated180Mirrored = (props?: Partial<Props>) => <HasMapComponent {
export const Rotated270Mirrored = (props?: Partial<Props>) => ( export const Rotated270Mirrored = (props?: Partial<Props>) => (
<HasMapComponent {...props} orientation={270} width={80} height={600} mirrored /> <HasMapComponent {...props} orientation={270} width={80} height={600} mirrored />
) )

export const LabelledKeyboard = (props?: Partial<Props>) => (
<HasMapComponent {...props} startKey={21} endKey={108} keyLabels={(key: number) => key} />
)

export const LabelledOctave = (props?: Partial<Props>) => (
<HasMapComponent
{...props}
startKey={21}
endKey={108}
keyLabels={(key: number) => {
if (Math.floor(key / 12) === 5) {
return key.toString()
}
return ''
}}
/>
)

export const LabelledPitch = (props?: Partial<Props>) => (
<HasMapComponent
{...props}
startKey={21}
endKey={108}
keyLabels={(key: number) => {
if (key % 12 === 0) {
return 'C'
}
return ''
}}
/>
)

export const LabelledRotatedKeyboard = (props?: Partial<Props>) => (
<HasMapComponent
{...props}
orientation={90}
width={80}
height={600}
startKey={21}
endKey={108}
keyLabels={(key: number) => key}
/>
)

export const LabelledRotatedMirroredKeyboard = (props?: Partial<Props>) => (
<HasMapComponent
{...props}
orientation={90}
width={80}
height={600}
startKey={21}
endKey={108}
mirrored
keyLabels={(key: number) => key}
/>
)

export const LabelledStyledKeyboard = (props?: Partial<Props>) => (
<HasMapComponent
{...props}
startKey={21}
endKey={108}
keyComponents={{
natural: StyledNaturalKey,
accidental: StyledAccidentalKey,
}}
keyLabels={(key: number) => key}
/>
)

+ 35
- 20
src/components/Keyboard/Keyboard.tsx View File

@@ -8,9 +8,9 @@ import DefaultAccidentalKey from '../AccidentalKey/AccidentalKey'
import DefaultNaturalKey from '../NaturalKey/NaturalKey' import DefaultNaturalKey from '../NaturalKey/NaturalKey'
import KeyboardMap from '../KeyboardMap/KeyboardMap' import KeyboardMap from '../KeyboardMap/KeyboardMap'
import getKeyBounds from '../../services/getKeyBounds' import getKeyBounds from '../../services/getKeyBounds'
import { BEHAVIORS, OCTAVE_DIVISIONS, ORIENTATIONS } from '../../services/constants'
import { BEHAVIORS, OCTAVE_DIVISIONS, ORIENTATIONS, COMPONENTS } from '../../services/constants'


export const propTypes = {
const propTypes = {
/** /**
* MIDI note of the first key. * MIDI note of the first key.
*/ */
@@ -34,7 +34,7 @@ export const propTypes = {
/** /**
* Current active keys and their channel assignments. * Current active keys and their channel assignments.
*/ */
keyChannels: PropTypes.arrayOf(
keysOn: PropTypes.arrayOf(
PropTypes.shape({ PropTypes.shape({
key: PropTypes.number.isRequired, key: PropTypes.number.isRequired,
velocity: PropTypes.number.isRequired, velocity: PropTypes.number.isRequired,
@@ -58,26 +58,32 @@ export const propTypes = {
* Height of the component. * Height of the component.
*/ */
height: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), height: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),

/** /**
* Event handler triggered upon change in activated keys in the component. * Event handler triggered upon change in activated keys in the component.
*/ */
onChange: PropTypes.func, onChange: PropTypes.func,

/** /**
* Map from key code to key number, used to activate the component from the keyboard. * Map from key code to key number, used to activate the component from the keyboard.
*/ */
keyboardMapping: PropTypes.object, keyboardMapping: PropTypes.object,

/** /**
* Behavior of the component when clicking. * Behavior of the component when clicking.
*/ */
behavior: PropTypes.oneOf(BEHAVIORS),
fallbackBehavior: PropTypes.oneOf(BEHAVIORS),

/** /**
* Name of the component used for forms. * Name of the component used for forms.
*/ */
name: PropTypes.string, name: PropTypes.string,

/** /**
* Destination of the component upon clicking a key, if behavior is set to 'link'.
* Destination of the component upon clicking a key, if fallbackBehavior is set to 'link'.
*/ */
href: PropTypes.func, href: PropTypes.func,

/** /**
* MIDI input for sending MIDI messages to the component. * MIDI input for sending MIDI messages to the component.
*/ */
@@ -85,21 +91,29 @@ export const propTypes = {
addEventListener: PropTypes.func.isRequired, addEventListener: PropTypes.func.isRequired,
removeEventListener: PropTypes.func.isRequired, removeEventListener: PropTypes.func.isRequired,
}), }),

/** /**
* Received velocity when activating the component through the keyboard. * Received velocity when activating the component through the keyboard.
*/ */
keyboardVelocity: PropTypes.number, keyboardVelocity: PropTypes.number,

/** /**
* Orientation of the component. * Orientation of the component.
*/ */
orientation: PropTypes.oneOf(ORIENTATIONS), orientation: PropTypes.oneOf(ORIENTATIONS),

/** /**
* Is the component mirrored? * Is the component mirrored?
*/ */
mirrored: PropTypes.bool, mirrored: PropTypes.bool,

/**
* Function returning the label of each key.
*/
keyLabels: PropTypes.func,
} }


type Props = PropTypes.InferProps<typeof propTypes>
export type Props = PropTypes.InferProps<typeof propTypes>


/** /**
* Component for displaying musical notes in the form of a piano keyboard. * Component for displaying musical notes in the form of a piano keyboard.
@@ -109,19 +123,20 @@ const Keyboard: React.FC<Props> = ({
endKey, endKey,
octaveDivision = 12, octaveDivision = 12,
accidentalKeyLengthRatio = 0.65, accidentalKeyLengthRatio = 0.65,
keyChannels = [],
keysOn = [],
width = '100%', width = '100%',
keyComponents = {}, keyComponents = {},
height = 80, height = 80,
onChange, onChange,
keyboardMapping, keyboardMapping,
behavior,
fallbackBehavior,
name, name,
href, href,
midiInput, midiInput,
keyboardVelocity, keyboardVelocity,
orientation = 0, orientation = 0,
mirrored = false, mirrored = false,
keyLabels,
}) => { }) => {
const [clientSide, setClientSide] = React.useState(false) const [clientSide, setClientSide] = React.useState(false)
const [clientSideKeys, setClientSideKeys] = React.useState<number[]>([]) const [clientSideKeys, setClientSideKeys] = React.useState<number[]>([])
@@ -188,7 +203,7 @@ const Keyboard: React.FC<Props> = ({
{keys.map((key) => { {keys.map((key) => {
const isNatural = isNaturalKey(key) const isNatural = isNaturalKey(key)
const Component: any = isNatural ? NaturalKey! : AccidentalKey! const Component: any = isNatural ? NaturalKey! : AccidentalKey!
const [currentKey = null] = Array.isArray(keyChannels!) ? keyChannels.filter((kc) => kc!.key === key) : []
const [currentKey = null] = Array.isArray(keysOn!) ? keysOn.filter((kc) => kc!.key === key) : []
const width = getKeyWidth(key) const width = getKeyWidth(key)
const left = getKeyLeft(key) const left = getKeyLeft(key)
const { left: leftBounds, right: rightBounds } = getKeyBounds( const { left: leftBounds, right: rightBounds } = getKeyBounds(
@@ -198,24 +213,20 @@ const Keyboard: React.FC<Props> = ({
getKeyWidth, getKeyWidth,
)(key, left, width) )(key, left, width)
const octaveStart = Math.floor(key / 12) * 12 const octaveStart = Math.floor(key / 12) * 12
// TODO implement xenharmonic keyboards
const theOctaveDivision = (octaveDivision as number) !== 12 ? 12 : octaveDivision const theOctaveDivision = (octaveDivision as number) !== 12 ? 12 : octaveDivision
const octaveEnd = octaveStart + 12 * (1 - 1 / theOctaveDivision!) const octaveEnd = octaveStart + 12 * (1 - 1 / theOctaveDivision!)
const octaveLeftBounds = getKeyLeft(octaveStart) const octaveLeftBounds = getKeyLeft(octaveStart)
const octaveRightBounds = getKeyLeft(octaveEnd) + getKeyWidth(octaveEnd) const octaveRightBounds = getKeyLeft(octaveEnd) + getKeyWidth(octaveEnd)
const components: Record<string, string> = {
link: 'a',
checkbox: 'label',
radio: 'label',
}


const { [behavior!]: component = 'div' } = components
const { [fallbackBehavior!]: component = 'div' } = COMPONENTS


const KeyComponent = component as React.ElementType const KeyComponent = component as React.ElementType


return ( return (
<KeyComponent <KeyComponent
key={key} key={key}
href={behavior === 'link' ? href!(key) : undefined}
href={fallbackBehavior === 'link' ? href!(key) : undefined}
data-key={key} data-key={key}
data-octave-left-bounds={octaveLeftBounds} data-octave-left-bounds={octaveLeftBounds}
data-octave-right-bounds={octaveRightBounds} data-octave-right-bounds={octaveRightBounds}
@@ -230,14 +241,14 @@ const Keyboard: React.FC<Props> = ({
[leftDirection]: (mirrored ? 100 - width - left : left) + '%', [leftDirection]: (mirrored ? 100 - width - left : left) + '%',
position: 'absolute', position: 'absolute',
[topDirection]: 0, [topDirection]: 0,
cursor: onChange || behavior ? 'pointer' : undefined,
cursor: onChange || fallbackBehavior ? 'pointer' : undefined,
color: 'inherit', color: 'inherit',
'--opacity-highlight': currentKey !== null ? 1 : 0, '--opacity-highlight': currentKey !== null ? 1 : 0,
}} }}
> >
{(behavior! === 'checkbox' || behavior === 'radio') && (
{(fallbackBehavior! === 'checkbox' || fallbackBehavior === 'radio') && (
<input <input
type={behavior}
type={fallbackBehavior}
className="ReactMusicalKeyboard-checkbox" className="ReactMusicalKeyboard-checkbox"
name={name!} name={name!}
value={key} value={key}
@@ -250,7 +261,11 @@ const Keyboard: React.FC<Props> = ({
}} }}
/> />
)} )}
<Component />
<Component
label={typeof keyLabels! === 'function' ? keyLabels(key) : null}
orientation={orientation}
mirrored={mirrored}
/>
</KeyComponent> </KeyComponent>
) )
})} })}


+ 29
- 1
src/components/NaturalKey/NaturalKey.tsx View File

@@ -1,6 +1,20 @@
import * as React from 'react' import * as React from 'react'
import * as PropTypes from 'prop-types'
import {
BOTTOM_CSS_ATTRIBUTES,
LEFT_CSS_ATTRIBUTES,
WIDTH_CSS_ATTRIBUTES,
ORIENTATIONS,
} from '../../services/constants'


const NaturalKey: React.FC = () => (
const propTypes = {
label: PropTypes.string,
orientation: PropTypes.oneOf(ORIENTATIONS),
}

type Props = PropTypes.InferProps<typeof propTypes>

const NaturalKey: React.FC<Props> = ({ label = '', orientation = 0 }) => (
<div <div
style={{ style={{
width: '100%', width: '100%',
@@ -22,7 +36,21 @@ const NaturalKey: React.FC = () => (
backgroundColor: `var(--color-active-key, Highlight)`, backgroundColor: `var(--color-active-key, Highlight)`,
}} }}
/> />
<div
style={{
position: 'absolute',
display: 'grid',
placeContent: 'center',
[BOTTOM_CSS_ATTRIBUTES[orientation || 0]]: 0,
[LEFT_CSS_ATTRIBUTES[orientation || 0]]: 0,
[WIDTH_CSS_ATTRIBUTES[orientation || 0]]: '100%',
}}
>
{label}
</div>
</div> </div>
) )


NaturalKey.propTypes = propTypes

export default NaturalKey export default NaturalKey

+ 364
- 339
src/components/StyledAccidentalKey/StyledAccidentalKey.tsx View File

@@ -1,452 +1,477 @@
import * as React from 'react' import * as React from 'react'
import * as PropTypes from 'prop-types'
import {
BOTTOM_CSS_ATTRIBUTES,
LEFT_CSS_ATTRIBUTES,
WIDTH_CSS_ATTRIBUTES,
ORIENTATIONS,
} from '../../services/constants'


const LIGHT_COLOR = 'white' const LIGHT_COLOR = 'white'


const StyledAccidentalKey: React.FC = () => {
return (
const propTypes = {
label: PropTypes.string,
orientation: PropTypes.oneOf(ORIENTATIONS),
}

type Props = PropTypes.InferProps<typeof propTypes>

const StyledAccidentalKey: React.FC<Props> = ({ label = '', orientation = 0 }) => (
<div
style={{
width: '100%',
height: '100%',
position: 'relative',
}}
>
<div <div
style={{ style={{
position: 'absolute',
top: 0,
left: 0,
width: '100%', width: '100%',
height: '100%', height: '100%',
position: 'relative',
}} }}
> >
<div <div
style={{ style={{
position: 'absolute',
top: 0,
left: 0,
width: '100%', width: '100%',
height: '100%', height: '100%',
position: 'relative',
}} }}
> >
<div <div
style={{ style={{
width: '100%', width: '100%',
height: '100%', height: '100%',
position: 'relative',
position: 'absolute',
top: 0,
left: 0,
borderRadius: 'calc(1px * var(--size-scale-factor, 1))',
boxShadow: '0 0 0 calc(1px * var(--size-scale-factor, 1)) rgba(0, 0, 0, 0.25)',
}}
/>
<div
style={{
width: '100%',
height: '100%',
backgroundColor: 'black',
position: 'absolute',
top: 0,
left: 0,
borderRadius: '0 0 calc(1px * var(--size-scale-factor, 1)) calc(1px * var(--size-scale-factor, 1))',
}}
/>
<div
style={{
width: '100%',
height: 'calc(6 / 50 * 100%)',
padding: '0 calc(1px * var(--size-scale-factor, 1)) calc(1px * var(--size-scale-factor, 1))',
boxSizing: 'border-box',
position: 'absolute',
bottom: 0,
left: 0,
}} }}
> >
<div <div
style={{ style={{
width: '100%', width: '100%',
height: '100%', height: '100%',
position: 'absolute',
top: 0,
left: 0,
borderRadius: 'calc(1px * var(--size-scale-factor, 1))',
boxShadow: '0 0 0 calc(1px * var(--size-scale-factor, 1)) rgba(0, 0, 0, 0.25)',
borderRadius: '0 0 calc(1px * var(--size-scale-factor, 1)) calc(1px * var(--size-scale-factor, 1))',
backgroundColor: `var(--color-accidental-key, #35313b)`,
maskImage: 'linear-gradient(to bottom, white, rgba(0, 0, 0, 0.9))',
WebkitMaskImage: 'linear-gradient(to bottom, white, rgba(0, 0, 0, 0.9))',
}} }}
/> />
</div>
<div
style={{
width: '100%',
height: 'calc(44 / 50 * 100%)',
padding: 'calc(1px * var(--size-scale-factor, 1)) calc(1px * var(--size-scale-factor, 1)) 0',
boxSizing: 'border-box',
position: 'absolute',
top: 0,
left: 0,
}}
>
<div <div
style={{ style={{
width: '100%', width: '100%',
height: '100%', height: '100%',
backgroundColor: 'black',
position: 'absolute',
top: 0,
left: 0,
borderRadius: '0 0 calc(1px * var(--size-scale-factor, 1)) calc(1px * var(--size-scale-factor, 1))',
backgroundColor: `var(--color-accidental-key, #35313b)`,
}} }}
/> />
</div>
<div
style={{
width: '100%',
height: 'calc(4px * var(--size-scale-factor, 1))',
padding: 'calc(1px * var(--size-scale-factor, 1)) 0 0 0',
boxSizing: 'border-box',
position: 'absolute',
top: 0,
left: 0,
}}
>
<div <div
style={{ style={{
width: '100%', width: '100%',
height: 'calc(6 / 50 * 100%)',
padding: '0 calc(1px * var(--size-scale-factor, 1)) calc(1px * var(--size-scale-factor, 1))',
boxSizing: 'border-box',
position: 'absolute',
bottom: 0,
left: 0,
height: '100%',
backgroundColor: 'black',
opacity: '0.12',
}} }}
>
<div
style={{
width: '100%',
height: '100%',
borderRadius: '0 0 calc(1px * var(--size-scale-factor, 1)) calc(1px * var(--size-scale-factor, 1))',
backgroundColor: `var(--color-accidental-key, #35313b)`,
maskImage: 'linear-gradient(to bottom, white, rgba(0, 0, 0, 0.9))',
WebkitMaskImage: 'linear-gradient(to bottom, white, rgba(0, 0, 0, 0.9))',
}}
/>
</div>
/>
</div>
<div
style={{
width: 'calc(2px * var(--size-scale-factor, 1))',
height: 'calc(10 / 52 * 100%)',
padding: '0 calc(1px * var(--size-scale-factor, 1)) 0 0',
boxSizing: 'border-box',
position: 'absolute',
top: 0,
right: 0,
}}
>
<div <div
style={{ style={{
width: '100%', width: '100%',
height: 'calc(44 / 50 * 100%)',
padding: 'calc(1px * var(--size-scale-factor, 1)) calc(1px * var(--size-scale-factor, 1)) 0',
boxSizing: 'border-box',
position: 'absolute',
top: 0,
left: 0,
height: '100%',
backgroundColor: LIGHT_COLOR,
maskImage: 'linear-gradient(to bottom, transparent, white)',
WebkitMaskImage: 'linear-gradient(to bottom, transparent, white)',
opacity: '0.4',
}} }}
>
<div
style={{
width: '100%',
height: '100%',
backgroundColor: `var(--color-accidental-key, #35313b)`,
}}
/>
</div>
/>
</div>
<div
style={{
width: 'calc(2px * var(--size-scale-factor, 1))',
height: 'calc(34 / 52 * 100%)',
boxSizing: 'border-box',
position: 'absolute',
bottom: 'calc(8 / 52 * 100%)',
right: 0,
paddingRight: 'calc(1px * var(--size-scale-factor, 1))',
paddingLeft: 0,
}}
>
<div <div
style={{ style={{
width: '100%', width: '100%',
height: 'calc(4px * var(--size-scale-factor, 1))',
padding: 'calc(1px * var(--size-scale-factor, 1)) 0 0 0',
boxSizing: 'border-box',
position: 'absolute',
top: 0,
left: 0,
}}
>
<div
style={{
width: '100%',
height: '100%',
backgroundColor: 'black',
opacity: '0.12',
}}
/>
</div>
<div
style={{
width: 'calc(2px * var(--size-scale-factor, 1))',
height: 'calc(10 / 52 * 100%)',
padding: '0 calc(1px * var(--size-scale-factor, 1)) 0 0',
boxSizing: 'border-box',
position: 'absolute',
top: 0,
right: 0,
}}
>
<div
style={{
width: '100%',
height: '100%',
backgroundColor: LIGHT_COLOR,
maskImage: 'linear-gradient(to bottom, transparent, white)',
WebkitMaskImage: 'linear-gradient(to bottom, transparent, white)',
opacity: '0.4',
}}
/>
</div>
<div
style={{
width: 'calc(2px * var(--size-scale-factor, 1))',
height: 'calc(34 / 52 * 100%)',
boxSizing: 'border-box',
position: 'absolute',
bottom: 'calc(8 / 52 * 100%)',
right: 0,
paddingRight: 'calc(1px * var(--size-scale-factor, 1))',
paddingLeft: 0,
height: '100%',
backgroundColor: LIGHT_COLOR,
opacity: '0.4',
borderBottomRightRadius: 'calc(1px * var(--size-scale-factor, 1))',
}} }}
>
<div
style={{
width: '100%',
height: '100%',
backgroundColor: LIGHT_COLOR,
opacity: '0.4',
borderBottomRightRadius: 'calc(1px * var(--size-scale-factor, 1))',
}}
/>
</div>
/>
</div>
<div
style={{
width: '100%',
height: 'calc(6 / 52 * 100%)',
padding:
'0 calc(1px * var(--size-scale-factor, 1)) calc(1px * var(--size-scale-factor, 1)) calc(1px * var(--size-scale-factor, 1))',
boxSizing: 'border-box',
position: 'absolute',
bottom: 0,
left: 0,
}}
>
<div <div
style={{ style={{
width: '100%', width: '100%',
height: 'calc(6 / 52 * 100%)',
padding:
'0 calc(1px * var(--size-scale-factor, 1)) calc(1px * var(--size-scale-factor, 1)) calc(1px * var(--size-scale-factor, 1))',
boxSizing: 'border-box',
position: 'absolute',
bottom: 0,
left: 0,
height: '100%',
backgroundColor: LIGHT_COLOR,
borderRadius:
'calc(4px * var(--size-scale-factor, 1)) calc(4px * var(--size-scale-factor, 1)) calc(1px * var(--size-scale-factor, 1)) calc(1px * var(--size-scale-factor, 1))',
opacity: '0.12',
}} }}
>
<div
style={{
width: '100%',
height: '100%',
backgroundColor: LIGHT_COLOR,
borderRadius:
'calc(4px * var(--size-scale-factor, 1)) calc(4px * var(--size-scale-factor, 1)) calc(1px * var(--size-scale-factor, 1)) calc(1px * var(--size-scale-factor, 1))',
opacity: '0.12',
}}
/>
</div>
/>
</div>
<div
style={{
width: '100%',
height: 'calc(38 / 52 * 100%)',
padding: '0 calc(3px * var(--size-scale-factor, 1)) 0 calc(3px * var(--size-scale-factor, 1))',
boxSizing: 'border-box',
position: 'absolute',
top: 'calc(3px * var(--size-scale-factor, 1))',
left: 0,
}}
>
<div <div
style={{ style={{
width: '100%', width: '100%',
height: 'calc(38 / 52 * 100%)',
padding: '0 calc(3px * var(--size-scale-factor, 1)) 0 calc(3px * var(--size-scale-factor, 1))',
boxSizing: 'border-box',
position: 'absolute',
top: 'calc(3px * var(--size-scale-factor, 1))',
left: 0,
height: '100%',
backgroundColor: LIGHT_COLOR,
maskImage: 'linear-gradient(to bottom, transparent, white)',
WebkitMaskImage: 'linear-gradient(to bottom, transparent, white)',
borderRadius: 99999,
opacity: 0.12,
}} }}
>
<div
style={{
width: '100%',
height: '100%',
backgroundColor: LIGHT_COLOR,
maskImage: 'linear-gradient(to bottom, transparent, white)',
WebkitMaskImage: 'linear-gradient(to bottom, transparent, white)',
borderRadius: 99999,
opacity: 0.12,
}}
/>
</div>
/>
</div>
<div
style={{
width: '100%',
paddingTop: 0,
paddingRight: 'calc(1px * var(--size-scale-factor, 1))',
paddingLeft: 'calc(2px * var(--size-scale-factor, 1))',
boxSizing: 'border-box',
position: 'absolute',
bottom: 'calc(8 / 52 * 100%)',
left: 0,
height: 'calc(1px * var(--size-scale-factor, 1))',
}}
>
<div <div
style={{ style={{
width: '100%', width: '100%',
paddingTop: 0,
paddingRight: 'calc(1px * var(--size-scale-factor, 1))',
paddingLeft: 'calc(2px * var(--size-scale-factor, 1))',
boxSizing: 'border-box',
position: 'absolute',
bottom: 'calc(8 / 52 * 100%)',
left: 0,
height: 'calc(1px * var(--size-scale-factor, 1))',
height: '100%',
backgroundColor: LIGHT_COLOR,
borderRadius: '0 0 calc(1px * var(--size-scale-factor, 1)) calc(1px * var(--size-scale-factor, 1))',
opacity: '0.4',
}} }}
>
<div
style={{
width: '100%',
height: '100%',
backgroundColor: LIGHT_COLOR,
borderRadius: '0 0 calc(1px * var(--size-scale-factor, 1)) calc(1px * var(--size-scale-factor, 1))',
opacity: '0.4',
}}
/>
</div>
/>
</div> </div>
</div> </div>
</div>
<div
style={{
position: 'absolute',
top: 0,
left: 0,
width: '100%',
height: '100%',
opacity: 'var(--opacity-highlight)',
}}
>
<div <div
style={{ style={{
position: 'absolute',
top: 0,
left: 0,
width: '100%', width: '100%',
height: '100%', height: '100%',
opacity: 'var(--opacity-highlight)',
position: 'relative',
}} }}
> >
<div <div
style={{ style={{
width: '100%', width: '100%',
height: '100%', height: '100%',
position: 'relative',
position: 'absolute',
top: 0,
left: 0,
borderRadius: 'calc(1px * var(--size-scale-factor, 1))',
boxShadow: '0 0 0 calc(1px * var(--size-scale-factor, 1)) rgba(0, 0, 0, 0.25)',
}}
/>
<div
style={{
width: '100%',
height: '100%',
backgroundColor: 'black',
position: 'absolute',
top: 0,
left: 0,
borderRadius: '0 0 calc(1px * var(--size-scale-factor, 1)) calc(1px * var(--size-scale-factor, 1))',
}}
/>
<div
style={{
width: '100%',
height: 'calc(6 / 50 * 100%)',
padding: '0 calc(1px * var(--size-scale-factor, 1)) calc(1px * var(--size-scale-factor, 1))',
boxSizing: 'border-box',
position: 'absolute',
bottom: 0,
left: 0,
}} }}
> >
<div <div
style={{ style={{
width: '100%', width: '100%',
height: '100%', height: '100%',
position: 'absolute',
top: 0,
left: 0,
borderRadius: 'calc(1px * var(--size-scale-factor, 1))',
boxShadow: '0 0 0 calc(1px * var(--size-scale-factor, 1)) rgba(0, 0, 0, 0.25)',
borderRadius: '0 0 calc(1px * var(--size-scale-factor, 1)) calc(1px * var(--size-scale-factor, 1))',
backgroundColor: 'var(--color-active-key, Highlight)',
maskImage: 'linear-gradient(to bottom, white, rgba(0, 0, 0, 0.9))',
WebkitMaskImage: 'linear-gradient(to bottom, white, rgba(0, 0, 0, 0.9))',
opacity: 0.75,
}} }}
/> />
</div>
<div
style={{
width: '100%',
height: 'calc(44 / 50 * 100%)',
padding: 'calc(1px * var(--size-scale-factor, 1)) calc(1px * var(--size-scale-factor, 1)) 0',
boxSizing: 'border-box',
position: 'absolute',
top: 0,
left: 0,
}}
>
<div <div
style={{ style={{
width: '100%', width: '100%',
height: '100%', height: '100%',
backgroundColor: 'black',
position: 'absolute',
top: 0,
left: 0,
borderRadius: '0 0 calc(1px * var(--size-scale-factor, 1)) calc(1px * var(--size-scale-factor, 1))',
backgroundColor: 'var(--color-active-key, Highlight)',
opacity: 0.75,
}} }}
/> />
</div>
<div
style={{
width: '100%',
height: 'calc(4px * var(--size-scale-factor, 1))',
padding: 'calc(1px * var(--size-scale-factor, 1)) 0 0 0',
boxSizing: 'border-box',
position: 'absolute',
top: 0,
left: 0,
}}
>
<div <div
style={{ style={{
width: '100%', width: '100%',
height: 'calc(6 / 50 * 100%)',
padding: '0 calc(1px * var(--size-scale-factor, 1)) calc(1px * var(--size-scale-factor, 1))',
boxSizing: 'border-box',
position: 'absolute',
bottom: 0,
left: 0,
height: '100%',
backgroundColor: 'black',
opacity: '0.12',
}} }}
>
<div
style={{
width: '100%',
height: '100%',
borderRadius: '0 0 calc(1px * var(--size-scale-factor, 1)) calc(1px * var(--size-scale-factor, 1))',
backgroundColor: 'var(--color-active-key, Highlight)',
maskImage: 'linear-gradient(to bottom, white, rgba(0, 0, 0, 0.9))',
WebkitMaskImage: 'linear-gradient(to bottom, white, rgba(0, 0, 0, 0.9))',
opacity: 0.75,
}}
/>
</div>
/>
</div>
<div
style={{
width: 'calc(2px * var(--size-scale-factor, 1))',
height: 'calc(10 / 52 * 100%)',
padding: '0 calc(1px * var(--size-scale-factor, 1)) 0 0',
boxSizing: 'border-box',
position: 'absolute',
top: 0,
right: 0,
opacity: 0.5,
}}
>
<div <div
style={{ style={{
width: '100%', width: '100%',
height: 'calc(44 / 50 * 100%)',
padding: 'calc(1px * var(--size-scale-factor, 1)) calc(1px * var(--size-scale-factor, 1)) 0',
boxSizing: 'border-box',
position: 'absolute',
top: 0,
left: 0,
height: '100%',
backgroundColor: LIGHT_COLOR,
maskImage: 'linear-gradient(to bottom, transparent, white)',
WebkitMaskImage: 'linear-gradient(to bottom, transparent, white)',
opacity: '0.4',
}} }}
>
<div
style={{
width: '100%',
height: '100%',
backgroundColor: 'var(--color-active-key, Highlight)',
opacity: 0.75,
}}
/>
</div>
/>
</div>
<div
style={{
width: 'calc(2px * var(--size-scale-factor, 1))',
height: 'calc(38 / 52 * 100%)',
boxSizing: 'border-box',
position: 'absolute',
bottom: 'calc(4 / 52 * 100%)',
right: 0,
paddingRight: 'calc(1px * var(--size-scale-factor, 1))',
paddingLeft: 0,
opacity: 0.5,
}}
>
<div <div
style={{ style={{
width: '100%', width: '100%',
height: 'calc(4px * var(--size-scale-factor, 1))',
padding: 'calc(1px * var(--size-scale-factor, 1)) 0 0 0',
boxSizing: 'border-box',
position: 'absolute',
top: 0,
left: 0,
}}
>
<div
style={{
width: '100%',
height: '100%',
backgroundColor: 'black',
opacity: '0.12',
}}
/>
</div>
<div
style={{
width: 'calc(2px * var(--size-scale-factor, 1))',
height: 'calc(10 / 52 * 100%)',
padding: '0 calc(1px * var(--size-scale-factor, 1)) 0 0',
boxSizing: 'border-box',
position: 'absolute',
top: 0,
right: 0,
opacity: 0.5,
}}
>
<div
style={{
width: '100%',
height: '100%',
backgroundColor: LIGHT_COLOR,
maskImage: 'linear-gradient(to bottom, transparent, white)',
WebkitMaskImage: 'linear-gradient(to bottom, transparent, white)',
opacity: '0.4',
}}
/>
</div>
<div
style={{
width: 'calc(2px * var(--size-scale-factor, 1))',
height: 'calc(38 / 52 * 100%)',
boxSizing: 'border-box',
position: 'absolute',
bottom: 'calc(4 / 52 * 100%)',
right: 0,
paddingRight: 'calc(1px * var(--size-scale-factor, 1))',
paddingLeft: 0,
opacity: 0.5,
height: '100%',
backgroundColor: LIGHT_COLOR,
opacity: '0.4',
borderBottomRightRadius: 'calc(1px * var(--size-scale-factor, 1))',
}} }}
>
<div
style={{
width: '100%',
height: '100%',
backgroundColor: LIGHT_COLOR,
opacity: '0.4',
borderBottomRightRadius: 'calc(1px * var(--size-scale-factor, 1))',
}}
/>
</div>
/>
</div>
<div
style={{
width: '100%',
height: 'calc(2 / 52 * 100%)',
padding:
'0 calc(1px * var(--size-scale-factor, 1)) calc(1px * var(--size-scale-factor, 1)) calc(1px * var(--size-scale-factor, 1))',
boxSizing: 'border-box',
position: 'absolute',
bottom: 0,
left: 0,
}}
>
<div <div
style={{ style={{
width: '100%', width: '100%',
height: 'calc(2 / 52 * 100%)',
padding:
'0 calc(1px * var(--size-scale-factor, 1)) calc(1px * var(--size-scale-factor, 1)) calc(1px * var(--size-scale-factor, 1))',
boxSizing: 'border-box',
position: 'absolute',
bottom: 0,
left: 0,
height: '100%',
backgroundColor: LIGHT_COLOR,
borderRadius:
'calc(4px * var(--size-scale-factor, 1)) calc(4px * var(--size-scale-factor, 1)) calc(1px * var(--size-scale-factor, 1)) calc(1px * var(--size-scale-factor, 1))',
opacity: '0.12',
}} }}
>
<div
style={{
width: '100%',
height: '100%',
backgroundColor: LIGHT_COLOR,
borderRadius:
'calc(4px * var(--size-scale-factor, 1)) calc(4px * var(--size-scale-factor, 1)) calc(1px * var(--size-scale-factor, 1)) calc(1px * var(--size-scale-factor, 1))',
opacity: '0.12',
}}
/>
</div>
/>
</div>
<div
style={{
width: '100%',
height: 'calc(42 / 52 * 100%)',
padding: '0 calc(3px * var(--size-scale-factor, 1)) 0 calc(3px * var(--size-scale-factor, 1))',
boxSizing: 'border-box',
position: 'absolute',
top: 'calc(3px * var(--size-scale-factor, 1))',
left: 0,
}}
>
<div <div
style={{ style={{
width: '100%', width: '100%',
height: 'calc(42 / 52 * 100%)',
padding: '0 calc(3px * var(--size-scale-factor, 1)) 0 calc(3px * var(--size-scale-factor, 1))',
boxSizing: 'border-box',
position: 'absolute',
top: 'calc(3px * var(--size-scale-factor, 1))',
left: 0,
height: '100%',
backgroundColor: LIGHT_COLOR,
maskImage: 'linear-gradient(to bottom, transparent, white)',
WebkitMaskImage: 'linear-gradient(to bottom, transparent, white)',
borderRadius: 99999,
opacity: 0.06,
}} }}
>
<div
style={{
width: '100%',
height: '100%',
backgroundColor: LIGHT_COLOR,
maskImage: 'linear-gradient(to bottom, transparent, white)',
WebkitMaskImage: 'linear-gradient(to bottom, transparent, white)',
borderRadius: 99999,
opacity: 0.06,
}}
/>
</div>
/>
</div>
<div
style={{
width: '100%',
paddingTop: 0,
paddingRight: 'calc(1px * var(--size-scale-factor, 1))',
paddingLeft: 'calc(2px * var(--size-scale-factor, 1))',
boxSizing: 'border-box',
position: 'absolute',
bottom: 'calc(4 / 52 * 100%)',
left: 0,
height: 'calc(1px * var(--size-scale-factor, 1))',
opacity: 0.5,
}}
>
<div <div
style={{ style={{
width: '100%', width: '100%',
paddingTop: 0,
paddingRight: 'calc(1px * var(--size-scale-factor, 1))',
paddingLeft: 'calc(2px * var(--size-scale-factor, 1))',
boxSizing: 'border-box',
position: 'absolute',
bottom: 'calc(4 / 52 * 100%)',
left: 0,
height: 'calc(1px * var(--size-scale-factor, 1))',
opacity: 0.5,
height: '100%',
backgroundColor: LIGHT_COLOR,
borderRadius: '0 0 calc(1px * var(--size-scale-factor, 1)) calc(1px * var(--size-scale-factor, 1))',
opacity: '0.4',
}} }}
>
<div
style={{
width: '100%',
height: '100%',
backgroundColor: LIGHT_COLOR,
borderRadius: '0 0 calc(1px * var(--size-scale-factor, 1)) calc(1px * var(--size-scale-factor, 1))',
opacity: '0.4',
}}
/>
</div>
/>
</div> </div>
</div> </div>
</div> </div>
)
}
<div
style={{
position: 'absolute',
display: 'grid',
placeContent: 'center',
filter: 'invert(100)',
[BOTTOM_CSS_ATTRIBUTES[orientation || 0]]: 0,
[LEFT_CSS_ATTRIBUTES[orientation || 0]]: 0,
[WIDTH_CSS_ATTRIBUTES[orientation || 0]]: '100%',
}}
>
{label}
</div>
</div>
)


export default StyledAccidentalKey export default StyledAccidentalKey

+ 316
- 292
src/components/StyledNaturalKey/StyledNaturalKey.tsx View File

@@ -1,399 +1,423 @@
import * as React from 'react' import * as React from 'react'
import * as PropTypes from 'prop-types'
import {
BOTTOM_CSS_ATTRIBUTES,
LEFT_CSS_ATTRIBUTES,
WIDTH_CSS_ATTRIBUTES,
ORIENTATIONS,
} from '../../services/constants'


const LIGHT_COLOR = 'white' const LIGHT_COLOR = 'white'


const StyledNaturalKey: React.FC = () => {
return (
const propTypes = {
label: PropTypes.string,
orientation: PropTypes.oneOf(ORIENTATIONS),
}

type Props = PropTypes.InferProps<typeof propTypes>

const StyledNaturalKey: React.FC<Props> = ({ label = '', orientation = 0 }) => (
<div
style={{
width: '100%',
height: '100%',
position: 'relative',
}}
>
<div <div
style={{ style={{
position: 'absolute',
top: 0,
left: 0,
width: '100%', width: '100%',
height: '100%', height: '100%',
position: 'relative',
}} }}
> >
<div <div
style={{ style={{
position: 'absolute',
top: 0,
left: 0,
width: '100%', width: '100%',
height: '100%', height: '100%',
position: 'relative',
}} }}
> >
<div <div
style={{ style={{
width: '100%', width: '100%',
height: '100%', height: '100%',
position: 'relative',
backgroundColor: 'black',
position: 'absolute',
top: '0',
left: '0',
}}
/>
<div
style={{
width: '100%',
height: '100%',
padding:
'calc(1px * var(--size-scale-factor, 1)) 0 calc(1px * var(--size-scale-factor, 1)) calc(1px * var(--size-scale-factor, 1))',
boxSizing: 'border-box',
position: 'absolute',
top: '0',
left: '0',
}} }}
> >
<div <div
style={{ style={{
width: '100%', width: '100%',
height: '100%', height: '100%',
backgroundColor: 'black',
position: 'absolute',
top: '0',
left: '0',
backgroundColor: `var(--color-natural-key, #e3e3e5)`,
borderRadius: '0 0 calc(1px * var(--size-scale-factor, 1)) calc(1px * var(--size-scale-factor, 1))',
opacity: 1,
}} }}
/> />
</div>
<div
style={{
width: '100%',
height: 'calc(33 / 80 * 100%)',
padding:
'0 calc(1px * var(--size-scale-factor, 1)) calc(2px * var(--size-scale-factor, 1)) calc(2px * var(--size-scale-factor, 1))',
boxSizing: 'border-box',
backgroundClip: 'content-box',
position: 'absolute',
bottom: '0',
left: '0',
maskImage: 'linear-gradient(to bottom, transparent, white)',
WebkitMaskImage: 'linear-gradient(to bottom, transparent, white)',
backgroundColor: LIGHT_COLOR,
opacity: 0.25,
}}
/>
<div
style={{
width: '100%',
height: '100%',
backgroundColor: 'black',
padding:
'calc(1px * var(--size-scale-factor, 1)) calc(2px * var(--size-scale-factor, 1)) calc(3px * var(--size-scale-factor, 1)) calc(3px * var(--size-scale-factor, 1))',
boxSizing: 'border-box',
backgroundClip: 'content-box',
position: 'absolute',
bottom: '0',
left: '0',
opacity: '0.08',
maskImage: 'linear-gradient(to bottom, transparent, white)',
WebkitMaskImage: 'linear-gradient(to bottom, transparent, white)',
}}
/>
<div
style={{
width: '100%',
height: 'calc(2px * var(--size-scale-factor, 1))',
padding: '0 0 calc(1px * var(--size-scale-factor, 1)) calc(1px * var(--size-scale-factor, 1))',
boxSizing: 'border-box',
position: 'absolute',
bottom: '0',
left: '0',
}}
>
<div <div
style={{ style={{
width: '100%', width: '100%',
height: '100%', height: '100%',
padding:
'calc(1px * var(--size-scale-factor, 1)) 0 calc(1px * var(--size-scale-factor, 1)) calc(1px * var(--size-scale-factor, 1))',
boxSizing: 'border-box',
position: 'absolute',
top: '0',
left: '0',
}}
>
<div
style={{
width: '100%',
height: '100%',
backgroundColor: `var(--color-natural-key, #e3e3e5)`,
borderRadius: '0 0 calc(1px * var(--size-scale-factor, 1)) calc(1px * var(--size-scale-factor, 1))',
opacity: 1,
}}
/>
</div>
<div
style={{
width: '100%',
height: 'calc(33 / 80 * 100%)',
padding:
'0 calc(1px * var(--size-scale-factor, 1)) calc(2px * var(--size-scale-factor, 1)) calc(2px * var(--size-scale-factor, 1))',
boxSizing: 'border-box',
backgroundClip: 'content-box',
position: 'absolute',
bottom: '0',
left: '0',
maskImage: 'linear-gradient(to bottom, transparent, white)',
WebkitMaskImage: 'linear-gradient(to bottom, transparent, white)',
backgroundColor: LIGHT_COLOR,
opacity: 0.25,
backgroundColor: 'black',
borderRadius: '0 0 calc(1px * var(--size-scale-factor, 1)) calc(1px * var(--size-scale-factor, 1))',
opacity: '0.25',
}} }}
/> />
</div>
<div
style={{
width: 'calc(2px * var(--size-scale-factor, 1))',
height: '100%',
padding:
'calc(1px * var(--size-scale-factor, 1)) 0 calc(1px * var(--size-scale-factor, 1)) calc(1px * var(--size-scale-factor, 1))',
boxSizing: 'border-box',
position: 'absolute',
bottom: '0',
left: '0',
}}
>
<div <div
style={{ style={{
width: '100%', width: '100%',
height: '100%', height: '100%',
backgroundColor: 'black', backgroundColor: 'black',
padding:
'calc(1px * var(--size-scale-factor, 1)) calc(2px * var(--size-scale-factor, 1)) calc(3px * var(--size-scale-factor, 1)) calc(3px * var(--size-scale-factor, 1))',
boxSizing: 'border-box',
backgroundClip: 'content-box',
position: 'absolute',
bottom: '0',
left: '0',
opacity: '0.08',
maskImage: 'linear-gradient(to bottom, transparent, white)',
WebkitMaskImage: 'linear-gradient(to bottom, transparent, white)',
borderRadius: '0 0 0 calc(1px * var(--size-scale-factor, 1))',
opacity: '0.07',
}} }}
/> />
</div>
<div
style={{
width: '100%',
height: 'calc(6px * var(--size-scale-factor, 1))',
padding: 'calc(1px * var(--size-scale-factor, 1)) 0 0 calc(1px * var(--size-scale-factor, 1))',
boxSizing: 'border-box',
position: 'absolute',
top: '0',
left: '0',
}}
>
<div <div
style={{ style={{
width: '100%', width: '100%',
height: 'calc(2px * var(--size-scale-factor, 1))',
padding: '0 0 calc(1px * var(--size-scale-factor, 1)) calc(1px * var(--size-scale-factor, 1))',
boxSizing: 'border-box',
position: 'absolute',
bottom: '0',
left: '0',
}}
>
<div
style={{
width: '100%',
height: '100%',
backgroundColor: 'black',
borderRadius: '0 0 calc(1px * var(--size-scale-factor, 1)) calc(1px * var(--size-scale-factor, 1))',
opacity: '0.25',
}}
/>
</div>
<div
style={{
width: 'calc(2px * var(--size-scale-factor, 1))',
height: '100%', height: '100%',
padding:
'calc(1px * var(--size-scale-factor, 1)) 0 calc(1px * var(--size-scale-factor, 1)) calc(1px * var(--size-scale-factor, 1))',
boxSizing: 'border-box',
position: 'absolute',
bottom: '0',
left: '0',
backgroundColor: 'black',
maskImage: 'linear-gradient(to bottom, white, transparent)',
WebkitMaskImage: 'linear-gradient(to bottom, white, transparent)',
opacity: '0.12',
}} }}
>
<div
style={{
width: '100%',
height: '100%',
backgroundColor: 'black',
borderRadius: '0 0 0 calc(1px * var(--size-scale-factor, 1))',
opacity: '0.07',
}}
/>
</div>
/>
</div>
<div
style={{
width: '100%',
padding: 'calc(1px * var(--size-scale-factor, 1)) 0 0 calc(1px * var(--size-scale-factor, 1))',
boxSizing: 'border-box',
position: 'absolute',
top: '0',
left: '0',
height: 'calc(3px * var(--size-scale-factor, 1))',
}}
>
<div <div
style={{ style={{
width: '100%', width: '100%',
height: 'calc(6px * var(--size-scale-factor, 1))',
padding: 'calc(1px * var(--size-scale-factor, 1)) 0 0 calc(1px * var(--size-scale-factor, 1))',
boxSizing: 'border-box',
position: 'absolute',
top: '0',
left: '0',
height: '100%',
backgroundColor: 'black',
opacity: '0.12',
}} }}
>
<div
style={{
width: '100%',
height: '100%',
backgroundColor: 'black',
maskImage: 'linear-gradient(to bottom, white, transparent)',
WebkitMaskImage: 'linear-gradient(to bottom, white, transparent)',
opacity: '0.12',
}}
/>
</div>
/>
</div>
<div
style={{
width: 'calc(1px * var(--size-scale-factor, 1))',
height: '100%',
padding: 'calc(1px * var(--size-scale-factor, 1)) 0 calc(1px * var(--size-scale-factor, 1)) 0',
boxSizing: 'border-box',
position: 'absolute',
bottom: '0',
right: '0',
}}
>
<div <div
style={{ style={{
width: '100%', width: '100%',
padding: 'calc(1px * var(--size-scale-factor, 1)) 0 0 calc(1px * var(--size-scale-factor, 1))',
boxSizing: 'border-box',
position: 'absolute',
top: '0',
left: '0',
height: 'calc(3px * var(--size-scale-factor, 1))',
}}
>
<div
style={{
width: '100%',
height: '100%',
backgroundColor: 'black',
opacity: '0.12',
}}
/>
</div>
<div
style={{
width: 'calc(1px * var(--size-scale-factor, 1))',
height: '100%', height: '100%',
padding: 'calc(1px * var(--size-scale-factor, 1)) 0 calc(1px * var(--size-scale-factor, 1)) 0',
boxSizing: 'border-box',
position: 'absolute',
bottom: '0',
right: '0',
backgroundColor: LIGHT_COLOR,
borderRadius: '0 0 calc(1px * var(--size-scale-factor, 1)) 0',
opacity: '0.12',
}} }}
>
<div
style={{
width: '100%',
height: '100%',
backgroundColor: LIGHT_COLOR,
borderRadius: '0 0 calc(1px * var(--size-scale-factor, 1)) 0',
opacity: '0.12',
}}
/>
</div>
/>
</div> </div>
</div> </div>
</div>
<div
style={{
position: 'absolute',
top: 0,
left: 0,
width: '100%',
height: '100%',
opacity: 'var(--opacity-highlight)',
}}
>
<div <div
style={{ style={{
position: 'absolute',
top: 0,
left: 0,
width: '100%', width: '100%',
height: '100%', height: '100%',
opacity: 'var(--opacity-highlight)',
position: 'relative',
}} }}
> >
<div <div
style={{ style={{
width: '100%', width: '100%',
height: '100%', height: '100%',
position: 'relative',
backgroundColor: 'black',
position: 'absolute',
top: '0',
left: '0',
}}
/>
<div
style={{
width: '100%',
height: '100%',
padding:
'calc(1px * var(--size-scale-factor, 1)) 0 calc(1px * var(--size-scale-factor, 1)) calc(1px * var(--size-scale-factor, 1))',
boxSizing: 'border-box',
position: 'absolute',
top: '0',
left: '0',
}} }}
> >
<div <div
style={{ style={{
width: '100%', width: '100%',
height: '100%', height: '100%',
backgroundColor: 'black',
position: 'absolute',
top: '0',
left: '0',
backgroundColor: `var(--color-active-key, Highlight)`,
borderRadius: '0 0 calc(1px * var(--size-scale-factor, 1)) calc(1px * var(--size-scale-factor, 1))',
opacity: 0.75,
}} }}
/> />
</div>
<div
style={{
width: '100%',
height: 'calc(33 / 80 * 100%)',
padding:
'0 calc(1px * var(--size-scale-factor, 1)) calc(2px * var(--size-scale-factor, 1)) calc(2px * var(--size-scale-factor, 1))',
boxSizing: 'border-box',
backgroundClip: 'content-box',
position: 'absolute',
bottom: '0',
left: '0',
maskImage: 'linear-gradient(to bottom, transparent, white)',
WebkitMaskImage: 'linear-gradient(to bottom, transparent, white)',
backgroundColor: LIGHT_COLOR,
opacity: 0.12,
}}
/>
<div
style={{
width: '100%',
height: '100%',
backgroundColor: 'black',
padding:
'calc(1px * var(--size-scale-factor, 1)) calc(2px * var(--size-scale-factor, 1)) calc(3px * var(--size-scale-factor, 1)) calc(3px * var(--size-scale-factor, 1))',
boxSizing: 'border-box',
backgroundClip: 'content-box',
position: 'absolute',
bottom: '0',
left: '0',
opacity: '0.08',
maskImage: 'linear-gradient(to bottom, transparent, white)',
WebkitMaskImage: 'linear-gradient(to bottom, transparent, white)',
}}
/>
<div
style={{
width: '100%',
height: 'calc(2px * var(--size-scale-factor, 1))',
padding: '0 0 calc(1px * var(--size-scale-factor, 1)) calc(1px * var(--size-scale-factor, 1))',
boxSizing: 'border-box',
position: 'absolute',
bottom: '0',
left: '0',
}}
>
<div <div
style={{ style={{
width: '100%', width: '100%',
height: '100%', height: '100%',
padding:
'calc(1px * var(--size-scale-factor, 1)) 0 calc(1px * var(--size-scale-factor, 1)) calc(1px * var(--size-scale-factor, 1))',
boxSizing: 'border-box',
position: 'absolute',
top: '0',
left: '0',
}}
>
<div
style={{
width: '100%',
height: '100%',
backgroundColor: `var(--color-active-key, Highlight)`,
borderRadius: '0 0 calc(1px * var(--size-scale-factor, 1)) calc(1px * var(--size-scale-factor, 1))',
opacity: 0.75,
}}
/>
</div>
<div
style={{
width: '100%',
height: 'calc(33 / 80 * 100%)',
padding:
'0 calc(1px * var(--size-scale-factor, 1)) calc(2px * var(--size-scale-factor, 1)) calc(2px * var(--size-scale-factor, 1))',
boxSizing: 'border-box',
backgroundClip: 'content-box',
position: 'absolute',
bottom: '0',
left: '0',
maskImage: 'linear-gradient(to bottom, transparent, white)',
WebkitMaskImage: 'linear-gradient(to bottom, transparent, white)',
backgroundColor: LIGHT_COLOR,
opacity: 0.12,
backgroundColor: 'black',
borderRadius: '0 0 calc(1px * var(--size-scale-factor, 1)) calc(1px * var(--size-scale-factor, 1))',
opacity: '0.25',
}} }}
/> />
</div>
<div
style={{
width: 'calc(2px * var(--size-scale-factor, 1))',
height: '100%',
padding:
'calc(1px * var(--size-scale-factor, 1)) 0 calc(1px * var(--size-scale-factor, 1)) calc(1px * var(--size-scale-factor, 1))',
boxSizing: 'border-box',
position: 'absolute',
bottom: '0',
left: '0',
}}
>
<div <div
style={{ style={{
width: '100%', width: '100%',
height: '100%', height: '100%',
backgroundColor: 'black', backgroundColor: 'black',
padding:
'calc(1px * var(--size-scale-factor, 1)) calc(2px * var(--size-scale-factor, 1)) calc(3px * var(--size-scale-factor, 1)) calc(3px * var(--size-scale-factor, 1))',
boxSizing: 'border-box',
backgroundClip: 'content-box',
position: 'absolute',
bottom: '0',
left: '0',
opacity: '0.08',
maskImage: 'linear-gradient(to bottom, transparent, white)',
WebkitMaskImage: 'linear-gradient(to bottom, transparent, white)',
borderRadius: '0 0 0 calc(1px * var(--size-scale-factor, 1))',
opacity: '0.07',
}} }}
/> />
</div>
<div
style={{
width: '100%',
height: 'calc(6px * var(--size-scale-factor, 1))',
padding: 'calc(1px * var(--size-scale-factor, 1)) 0 0 calc(1px * var(--size-scale-factor, 1))',
boxSizing: 'border-box',
position: 'absolute',
top: '0',
left: '0',
}}
>
<div <div
style={{ style={{
width: '100%', width: '100%',
height: 'calc(2px * var(--size-scale-factor, 1))',
padding: '0 0 calc(1px * var(--size-scale-factor, 1)) calc(1px * var(--size-scale-factor, 1))',
boxSizing: 'border-box',
position: 'absolute',
bottom: '0',
left: '0',
}}
>
<div
style={{
width: '100%',
height: '100%',
backgroundColor: 'black',
borderRadius: '0 0 calc(1px * var(--size-scale-factor, 1)) calc(1px * var(--size-scale-factor, 1))',
opacity: '0.25',
}}
/>
</div>
<div
style={{
width: 'calc(2px * var(--size-scale-factor, 1))',
height: '100%', height: '100%',
padding:
'calc(1px * var(--size-scale-factor, 1)) 0 calc(1px * var(--size-scale-factor, 1)) calc(1px * var(--size-scale-factor, 1))',
boxSizing: 'border-box',
position: 'absolute',
bottom: '0',
left: '0',
backgroundColor: 'black',
maskImage: 'linear-gradient(to bottom, white, transparent)',
WebkitMaskImage: 'linear-gradient(to bottom, white, transparent)',
opacity: '0.12',
}} }}
>
<div
style={{
width: '100%',
height: '100%',
backgroundColor: 'black',
borderRadius: '0 0 0 calc(1px * var(--size-scale-factor, 1))',
opacity: '0.07',
}}
/>
</div>
/>
</div>
<div
style={{
width: '100%',
padding: 'calc(1px * var(--size-scale-factor, 1)) 0 0 calc(1px * var(--size-scale-factor, 1))',
boxSizing: 'border-box',
position: 'absolute',
top: '0',
left: '0',
height: 'calc(4px * var(--size-scale-factor, 1))',
}}
>
<div <div
style={{ style={{
width: '100%', width: '100%',
height: 'calc(6px * var(--size-scale-factor, 1))',
padding: 'calc(1px * var(--size-scale-factor, 1)) 0 0 calc(1px * var(--size-scale-factor, 1))',
boxSizing: 'border-box',
position: 'absolute',
top: '0',
left: '0',
height: '100%',
backgroundColor: 'black',
opacity: '0.12',
}} }}
>
<div
style={{
width: '100%',
height: '100%',
backgroundColor: 'black',
maskImage: 'linear-gradient(to bottom, white, transparent)',
WebkitMaskImage: 'linear-gradient(to bottom, white, transparent)',
opacity: '0.12',
}}
/>
</div>
/>
</div>
<div
style={{
width: 'calc(1px * var(--size-scale-factor, 1))',
height: '100%',
padding: 'calc(1px * var(--size-scale-factor, 1)) 0 calc(1px * var(--size-scale-factor, 1)) 0',
boxSizing: 'border-box',
position: 'absolute',
bottom: '0',
right: '0',
}}
>
<div <div
style={{ style={{
width: '100%', width: '100%',
padding: 'calc(1px * var(--size-scale-factor, 1)) 0 0 calc(1px * var(--size-scale-factor, 1))',
boxSizing: 'border-box',
position: 'absolute',
top: '0',
left: '0',
height: 'calc(4px * var(--size-scale-factor, 1))',
}}
>
<div
style={{
width: '100%',
height: '100%',
backgroundColor: 'black',
opacity: '0.12',
}}
/>
</div>
<div
style={{
width: 'calc(1px * var(--size-scale-factor, 1))',
height: '100%', height: '100%',
padding: 'calc(1px * var(--size-scale-factor, 1)) 0 calc(1px * var(--size-scale-factor, 1)) 0',
boxSizing: 'border-box',
position: 'absolute',
bottom: '0',
right: '0',
backgroundColor: LIGHT_COLOR,
borderRadius: '0 0 calc(1px * var(--size-scale-factor, 1)) 0',
opacity: '0.12',
}} }}
>
<div
style={{
width: '100%',
height: '100%',
backgroundColor: LIGHT_COLOR,
borderRadius: '0 0 calc(1px * var(--size-scale-factor, 1)) 0',
opacity: '0.12',
}}
/>
</div>
/>
</div> </div>
</div> </div>
</div> </div>
)
}
<div
style={{
position: 'absolute',
display: 'grid',
placeContent: 'center',
[BOTTOM_CSS_ATTRIBUTES[orientation || 0]]: 0,
[LEFT_CSS_ATTRIBUTES[orientation || 0]]: 0,
[WIDTH_CSS_ATTRIBUTES[orientation || 0]]: '100%',
}}
>
{label}
</div>
</div>
)


export default StyledNaturalKey export default StyledNaturalKey

+ 27
- 0
src/services/constants.ts View File

@@ -93,3 +93,30 @@ export const BEHAVIORS = ['link', 'checkbox', 'radio'] as const
export const OCTAVE_DIVISIONS = [12, 17, 19, 21, 24, 36] as const export const OCTAVE_DIVISIONS = [12, 17, 19, 21, 24, 36] as const


export const ORIENTATIONS = [0, 90, 180, 270] as const export const ORIENTATIONS = [0, 90, 180, 270] as const

export const BOTTOM_CSS_ATTRIBUTES: Record<0 | 90 | 180 | 270, string> = {
0: 'bottom',
90: 'right',
180: 'top',
270: 'left',
}

export const LEFT_CSS_ATTRIBUTES: Record<0 | 90 | 180 | 270, string> = {
0: 'left',
90: 'bottom',
180: 'right',
270: 'top',
}

export const WIDTH_CSS_ATTRIBUTES: Record<0 | 90 | 180 | 270, string> = {
0: 'width',
180: 'width',
90: 'height',
270: 'height',
}

export const COMPONENTS: Record<string, string> = {
link: 'a',
checkbox: 'label',
radio: 'label',
}

Loading…
Cancel
Save