mirror of
https://github.com/roleypoly/roleypoly-v1.git
synced 2025-06-16 02:19:08 +00:00
greatly improve role component visual feel
This commit is contained in:
parent
73f60cbd3d
commit
998b1930b3
2 changed files with 160 additions and 59 deletions
|
@ -1,7 +1,9 @@
|
||||||
// @flow
|
// @flow
|
||||||
import * as React from 'react'
|
import * as React from 'react'
|
||||||
import styled from 'styled-components'
|
import { colors } from '../global-colors'
|
||||||
import MediaQuery from '../../kit/media'
|
import Color from 'color'
|
||||||
|
import RoleStyled from './role.styled'
|
||||||
|
import Tooltip from '../tooltip'
|
||||||
|
|
||||||
export type RoleData = {
|
export type RoleData = {
|
||||||
color: string,
|
color: string,
|
||||||
|
@ -18,65 +20,17 @@ export type RoleProps = {
|
||||||
connectDragSource?: (component: React.Node) => void
|
connectDragSource?: (component: React.Node) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
const Outer = styled.div`
|
// const tooltip = ({ show = true, text, ...rest }) => <div {...rest}>{text}</div>
|
||||||
box-sizing: border-box;
|
|
||||||
padding: 4px 0.5em;
|
|
||||||
padding-top: 2px;
|
|
||||||
border: solid 1px var(--outer-color);
|
|
||||||
display: inline-block;
|
|
||||||
border-radius: 1.2em;
|
|
||||||
margin: 0.3em;
|
|
||||||
font-size: 1.2em;
|
|
||||||
transition: box-shadow 0.3s ease-in-out;
|
|
||||||
text-shadow: 1px 1px 1px rgba(0,0,0,0.45);
|
|
||||||
cursor: pointer;
|
|
||||||
user-select: none;
|
|
||||||
${(props: any) => (props.active) ? 'box-shadow: inset 0 0 0 3em var(--outer-color);' : ''}
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
&:hover::after {
|
type RoleState = {
|
||||||
transform: translateY(-1px);
|
hovering: boolean
|
||||||
box-shadow: 0 0 1px rgba(0,0,0,0.75);
|
}
|
||||||
|
|
||||||
|
export default class Role extends React.Component<RoleProps, RoleState> {
|
||||||
|
state = {
|
||||||
|
hovering: false
|
||||||
}
|
}
|
||||||
|
|
||||||
&:active::after {
|
|
||||||
transform: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
&::after {
|
|
||||||
display: none;
|
|
||||||
content: '';
|
|
||||||
position: absolute;
|
|
||||||
box-sizing: border-box;
|
|
||||||
top: 4px;
|
|
||||||
left: 4px;
|
|
||||||
bottom: 2px;
|
|
||||||
border-radius: 100%;
|
|
||||||
width: 22px;
|
|
||||||
height: 22px;
|
|
||||||
clip-path: border-box circle(50% at 50% 50%); /* firefox fix */
|
|
||||||
transform: none;
|
|
||||||
border: 1px solid var(--outer-color);
|
|
||||||
transition: border 0.3s ease-in-out, transform 0.1s ease-in-out;
|
|
||||||
${(props: any) => (props.active) ? 'border-left-width: 21px;' : ''}
|
|
||||||
}
|
|
||||||
|
|
||||||
${(props: any) => MediaQuery({
|
|
||||||
md: `
|
|
||||||
font-size: 1em;
|
|
||||||
text-shadow: none;
|
|
||||||
padding-left: 32px;
|
|
||||||
${(props.active) ? 'box-shadow: none;' : ''}
|
|
||||||
&::after {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
`
|
|
||||||
})}
|
|
||||||
|
|
||||||
|
|
||||||
`
|
|
||||||
|
|
||||||
export default class Role extends React.Component<RoleProps> {
|
|
||||||
onToggle = () => {
|
onToggle = () => {
|
||||||
if (!this.props.disabled && this.props.onToggle) {
|
if (!this.props.disabled && this.props.onToggle) {
|
||||||
const { active = false } = this.props
|
const { active = false } = this.props
|
||||||
|
@ -84,7 +38,45 @@ export default class Role extends React.Component<RoleProps> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onMouseOver = () => {
|
||||||
|
console.log('caught hovering')
|
||||||
|
if (this.props.disabled && this.state.hovering === false) {
|
||||||
|
console.log('set hovering')
|
||||||
|
this.setState({ hovering: true })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onMouseOut = () => {
|
||||||
|
console.log('out hovering')
|
||||||
|
this.setState({ hovering: false })
|
||||||
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
return <Outer active={this.props.active} onClick={this.onToggle} style={{ '--outer-color': this.props.role.color }}>{this.props.role.name}</Outer>
|
let color = Color(this.props.role.color)
|
||||||
|
if (this.props.role.color === 0) {
|
||||||
|
color = colors.white
|
||||||
|
}
|
||||||
|
|
||||||
|
const roleColors = {
|
||||||
|
outline: Color(color).alpha(0.7).hsl().string(),
|
||||||
|
outlineAlt: Color(color).alpha(0.4).hsl().string(),
|
||||||
|
active: Color(color).lighten(0.1).hsl().string(),
|
||||||
|
base: Color(color).hsl().string()
|
||||||
|
}
|
||||||
|
|
||||||
|
return <RoleStyled
|
||||||
|
active={this.props.active}
|
||||||
|
disabled={this.props.disabled}
|
||||||
|
onClick={this.onToggle}
|
||||||
|
onMouseOver={this.onMouseOver}
|
||||||
|
onMouseOut={this.onMouseOut}
|
||||||
|
onTouchStart={this.onMouseOver}
|
||||||
|
onTouchEnd={this.onMouseOut}
|
||||||
|
colors={roleColors}
|
||||||
|
// title={(this.props.disabled) ? 'This role is disabled for safety.' : null}
|
||||||
|
>
|
||||||
|
{this.props.role.name}
|
||||||
|
{ (this.props.disabled && this.state.hovering) && <Tooltip>This role has unsafe permissions.</Tooltip> }
|
||||||
|
</RoleStyled>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
109
ui/components/role/role.styled.js
Normal file
109
ui/components/role/role.styled.js
Normal file
|
@ -0,0 +1,109 @@
|
||||||
|
import styled from 'styled-components'
|
||||||
|
import MediaQuery from '../../kit/media'
|
||||||
|
|
||||||
|
export default styled.div`
|
||||||
|
border: solid 1px ${(props: any) => props.colors.outline};
|
||||||
|
border-radius: 1.2em;
|
||||||
|
|
||||||
|
box-sizing: border-box;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
position: relative;
|
||||||
|
display: inline-flex;
|
||||||
|
overflow: hidden;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-start;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
font-size: 1.2em;
|
||||||
|
line-height: 1.3;
|
||||||
|
|
||||||
|
margin: 0.3em;
|
||||||
|
padding: 4px 0.5em;
|
||||||
|
|
||||||
|
min-height: 32px;
|
||||||
|
max-width: 90vw;
|
||||||
|
|
||||||
|
transition: box-shadow 0.3s ease-in-out;
|
||||||
|
|
||||||
|
text-shadow: 1px 1px 1px rgba(0,0,0,0.45);
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
user-select: none;
|
||||||
|
white-space: nowrap;
|
||||||
|
transform: rotateZ(0);
|
||||||
|
|
||||||
|
${(props: any) => (props.active) ? `box-shadow: inset 0 0 0 3em ${props.colors.outlineAlt};` : ''}
|
||||||
|
|
||||||
|
.wf-active & {
|
||||||
|
padding-top: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&[disabled]:hover {
|
||||||
|
overflow: visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover::after {
|
||||||
|
transform: translateY(-1px) rotateZ(0);
|
||||||
|
box-shadow: 0 0 1px rgba(0,0,0,0.75);
|
||||||
|
border-color: ${(props: any) => props.colors.active}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active::after {
|
||||||
|
transform: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
content: '';
|
||||||
|
display: none;
|
||||||
|
box-sizing: border-box;
|
||||||
|
|
||||||
|
position: absolute;
|
||||||
|
left: 4px;
|
||||||
|
bottom: 2px;
|
||||||
|
top: 4px;
|
||||||
|
|
||||||
|
width: 22px;
|
||||||
|
height: 22px;
|
||||||
|
|
||||||
|
border: 1px solid ${(props: any) => props.colors.base};
|
||||||
|
border-radius: 100%;
|
||||||
|
|
||||||
|
transition: border 0.3s ease-in-out, transform 0.1s ease-in-out;
|
||||||
|
|
||||||
|
clip-path: border-box circle(50% at 50% 50%); /* firefox fix */
|
||||||
|
|
||||||
|
transform: rotateZ(0);
|
||||||
|
${(props: any) => (props.active) ? 'border-left-width: 21px;' : ''}
|
||||||
|
}
|
||||||
|
|
||||||
|
${(props: any) => MediaQuery({
|
||||||
|
md: `
|
||||||
|
font-size: 1em;
|
||||||
|
text-shadow: none;
|
||||||
|
padding-left: 32px;
|
||||||
|
${(props.active) ? 'box-shadow: none;' : ''}
|
||||||
|
&::after {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
`
|
||||||
|
})}
|
||||||
|
|
||||||
|
${(props: any) => (props.disabled) ? `
|
||||||
|
border-color: hsl(0,0%,40%);
|
||||||
|
color: hsla(0,0%,40%,0.7);
|
||||||
|
cursor: default;
|
||||||
|
box-shadow: none;
|
||||||
|
${(props.active) ? `box-shadow: inset 0 0 0 3em hsla(0,0%,40%,0.1);` : ''}
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
border-color: hsl(0,0%,40%);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover::after {
|
||||||
|
border-color: hsl(0,0%,40%);
|
||||||
|
transform: none;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
` : ''}
|
||||||
|
`
|
Loading…
Add table
Add a link
Reference in a new issue