Browse Source

Add labels, change props

Add function prop for labelling keys. Also changed some props for clearer usage.
master
TheoryOfNekomata 3 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>

+ 1
- 1
example/index.tsx View File

@@ -117,7 +117,7 @@ const App = () => {
<Keyboard
startKey={0}
endKey={127}
keyChannels={keyChannels}
keysOn={keyChannels}
height="100%"
keyboardVelocity={0.75}
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",
"main": "dist/index.js",
"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 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
style={{
width: '100%',
@@ -22,6 +36,19 @@ const AccidentalKey: React.FC = () => (
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>
)



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

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

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

type Props = PropTypes.InferProps<typeof propTypes>

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

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

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

export const Link = (props?: Partial<Props>) => (
<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>
)

@@ -314,3 +311,73 @@ export const Rotated180Mirrored = (props?: Partial<Props>) => <HasMapComponent {
export const Rotated270Mirrored = (props?: Partial<Props>) => (
<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 KeyboardMap from '../KeyboardMap/KeyboardMap'
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.
*/
@@ -34,7 +34,7 @@ export const propTypes = {
/**
* Current active keys and their channel assignments.
*/
keyChannels: PropTypes.arrayOf(
keysOn: PropTypes.arrayOf(
PropTypes.shape({
key: PropTypes.number.isRequired,
velocity: PropTypes.number.isRequired,
@@ -58,26 +58,32 @@ export const propTypes = {
* Height of the component.
*/
height: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),

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

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

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

/**
* Name of the component used for forms.
*/
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,

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

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

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

/**
* Is the component mirrored?
*/
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.
@@ -109,19 +123,20 @@ const Keyboard: React.FC<Props> = ({
endKey,
octaveDivision = 12,
accidentalKeyLengthRatio = 0.65,
keyChannels = [],
keysOn = [],
width = '100%',
keyComponents = {},
height = 80,
onChange,
keyboardMapping,
behavior,
fallbackBehavior,
name,
href,
midiInput,
keyboardVelocity,
orientation = 0,
mirrored = false,
keyLabels,
}) => {
const [clientSide, setClientSide] = React.useState(false)
const [clientSideKeys, setClientSideKeys] = React.useState<number[]>([])
@@ -188,7 +203,7 @@ const Keyboard: React.FC<Props> = ({
{keys.map((key) => {
const isNatural = isNaturalKey(key)
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 left = getKeyLeft(key)
const { left: leftBounds, right: rightBounds } = getKeyBounds(
@@ -198,24 +213,20 @@ const Keyboard: React.FC<Props> = ({
getKeyWidth,
)(key, left, width)
const octaveStart = Math.floor(key / 12) * 12
// TODO implement xenharmonic keyboards
const theOctaveDivision = (octaveDivision as number) !== 12 ? 12 : octaveDivision
const octaveEnd = octaveStart + 12 * (1 - 1 / theOctaveDivision!)
const octaveLeftBounds = getKeyLeft(octaveStart)
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

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


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

@@ -1,6 +1,20 @@
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
style={{
width: '100%',
@@ -22,7 +36,21 @@ const NaturalKey: React.FC = () => (
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>
)

NaturalKey.propTypes = propTypes

export default NaturalKey

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

@@ -1,452 +1,477 @@
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 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
style={{
position: 'absolute',
top: 0,
left: 0,
width: '100%',
height: '100%',
position: 'relative',
}}
>
<div
style={{
position: 'absolute',
top: 0,
left: 0,
width: '100%',
height: '100%',
position: 'relative',
}}
>
<div
style={{
width: '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
style={{
width: '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
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))',
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
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,
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
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,
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
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
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
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,
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
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,
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
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))',
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
style={{
position: 'absolute',
top: 0,
left: 0,
width: '100%',
height: '100%',
opacity: 'var(--opacity-highlight)',
}}
>
<div
style={{
position: 'absolute',
top: 0,
left: 0,
width: '100%',
height: '100%',
opacity: 'var(--opacity-highlight)',
position: 'relative',
}}
>
<div
style={{
width: '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
style={{
width: '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
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))',
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
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,
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
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,
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
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
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
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,
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
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,
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
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,
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
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

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

@@ -1,399 +1,423 @@
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 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
style={{
position: 'absolute',
top: 0,
left: 0,
width: '100%',
height: '100%',
position: 'relative',
}}
>
<div
style={{
position: 'absolute',
top: 0,
left: 0,
width: '100%',
height: '100%',
position: 'relative',
}}
>
<div
style={{
width: '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
style={{
width: '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
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
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
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)',
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
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
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%',
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
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',
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
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
style={{
width: '100%',
height: '100%',
backgroundColor: 'black',
opacity: '0.12',
}}
/>
</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',
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
style={{
position: 'absolute',
top: 0,
left: 0,
width: '100%',
height: '100%',
opacity: 'var(--opacity-highlight)',
}}
>
<div
style={{
position: 'absolute',
top: 0,
left: 0,
width: '100%',
height: '100%',
opacity: 'var(--opacity-highlight)',
position: 'relative',
}}
>
<div
style={{
width: '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
style={{
width: '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
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
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
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)',
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
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
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%',
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
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',
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
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
style={{
width: '100%',
height: '100%',
backgroundColor: 'black',
opacity: '0.12',
}}
/>
</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',
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
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

+ 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 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