v3/src/design-system/atoms/role/Role.tsx
Katalina Okano 156bd8f06e Merge branch 'gcf' into main
Signed-off-by: Katalina Okano <git@kat.cafe>
2020-12-05 03:11:12 -05:00

82 lines
2.7 KiB
TypeScript

import * as React from 'react';
import { Role as RPCRole, RoleSafety } from 'roleypoly/common/types';
import * as styled from './Role.styled';
import { FaCheck, FaTimes } from 'react-icons/fa';
import { numberToChroma } from 'roleypoly/design-system/atoms/colors';
import chroma from 'chroma-js';
type Props = {
role: RPCRole;
selected: boolean;
disabled?: boolean;
onClick?: (newState: boolean) => void;
tooltipId?: string;
type?: 'delete';
};
export const Role = (props: Props) => {
const colorVars = {
'--role-color': 'white',
'--role-contrast': 'hsl(0,0,0%)',
'--role-accent': 'hsl(0,0,70%)',
};
if (props.role.color !== 0) {
const baseColor = numberToChroma(props.role.color);
const contrastColorUp = baseColor.brighten(5);
const contrastColorDown = baseColor.darken(5);
const ratio = chroma.contrast(contrastColorDown, baseColor);
const contrastColor = ratio > 2 ? contrastColorDown : contrastColorUp;
const accentColor = ratio > 2 ? baseColor.darken(2) : baseColor.brighten(2);
colorVars['--role-color'] = baseColor.css();
colorVars['--role-accent'] = accentColor.css();
colorVars['--role-contrast'] = contrastColor.css();
}
const styledProps: styled.StyledProps = {
selected: props.selected,
defaultColor: props.role.color === 0,
disabled: !!props.disabled,
type: props.type,
};
const extra = !props.disabled
? {}
: {
'data-tip': disabledReason(props.role),
'data-for': props.tooltipId,
};
return (
<styled.Outer
{...styledProps}
style={colorVars as any}
onClick={() => !props.disabled && props.onClick?.(!props.selected)}
{...extra}
>
<styled.Circle {...styledProps}>
{!props.disabled && props.type !== 'delete' ? <FaCheck /> : <FaTimes />}
</styled.Circle>
<styled.Text>{props.role.name}</styled.Text>
</styled.Outer>
);
};
const disabledReason = (role: RPCRole) => {
switch (role.safety) {
case RoleSafety.HIGHERTHANBOT:
return `This role is above Roleypoly's own role.`;
case RoleSafety.DANGEROUSPERMISSIONS:
const { permissions } = role;
let permissionHits: string[] = [];
(permissions & 0x00000008) === 0x00000008 &&
permissionHits.push('Administrator');
(permissions & 0x10000000) === 0x10000000 &&
permissionHits.push('Manage Roles');
return `This role has unsafe permissions: ${permissionHits.join(', ')}`;
default:
return `This role is disabled.`;
}
};