feat: steps++
This commit is contained in:
parent
2c9fe3a1a7
commit
35e2a36e58
|
@ -1,4 +1,5 @@
|
|||
import {compose} from '@avocado/core';
|
||||
import {Entity} from '@avocado/entity';
|
||||
import contempo from 'contempo';
|
||||
import React from 'react';
|
||||
|
||||
|
@ -8,19 +9,21 @@ const decorate = compose(
|
|||
contempo(require('./entity.raw.scss')),
|
||||
);
|
||||
|
||||
const kitty = require('~/../fixtures/kitty.entity.json');
|
||||
const json = require('~/../fixtures/kitty.entity.json');
|
||||
|
||||
const Entity = () => {
|
||||
const entity = kitty;
|
||||
const {traits} = entity;
|
||||
const EntityComponent = (props) => {
|
||||
const {context} = props;
|
||||
const entity = new Entity(json);
|
||||
context.add('entity', entity);
|
||||
const {traits} = json;
|
||||
return (
|
||||
<div className="entity">
|
||||
<div className="document-pane" />
|
||||
<div className="settings-pane">
|
||||
<Traits traits={traits} />
|
||||
<Traits context={context} traits={traits} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default decorate(Entity);
|
||||
export default decorate(EntityComponent);
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
import {Context} from '@avocado/behavior';
|
||||
import {hot} from 'react-hot-loader';
|
||||
import React from 'react';
|
||||
|
||||
import Entity from './entity';
|
||||
|
||||
const context = new Context();
|
||||
|
||||
const Persea = () => (
|
||||
<Entity />
|
||||
<Entity context={context} />
|
||||
);
|
||||
|
||||
export default hot(module)(Persea);
|
||||
|
|
|
@ -53,7 +53,7 @@ const ensureTypeRenderers = () => {
|
|||
}
|
||||
};
|
||||
|
||||
const makeTabSelector = (type) => createSelector(
|
||||
const makeTabSelector = (context, type) => createSelector(
|
||||
(_) => _,
|
||||
(trait) => {
|
||||
ensureTypeRenderers();
|
||||
|
@ -79,6 +79,7 @@ const makeTabSelector = (type) => createSelector(
|
|||
</span>
|
||||
<div className="invisible-separator" />
|
||||
<Component
|
||||
context={context}
|
||||
key={key}
|
||||
label={label}
|
||||
name={key}
|
||||
|
@ -102,7 +103,7 @@ const makeTabSelector = (type) => createSelector(
|
|||
);
|
||||
|
||||
const Traits = (props) => {
|
||||
const {traits} = props;
|
||||
const {context, traits} = props;
|
||||
const [tabSelectorMap, setTabSelectorMap] = useState({});
|
||||
useEffect(() => {
|
||||
const entries = Object.entries(traits);
|
||||
|
@ -114,7 +115,7 @@ const Traits = (props) => {
|
|||
draft[type] = new WeakMap();
|
||||
}
|
||||
if (!draft[type].has(traits)) {
|
||||
draft[type].set(traits, makeTabSelector(type));
|
||||
draft[type].set(traits, makeTabSelector(context, type));
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
|
|
@ -1,28 +1,19 @@
|
|||
.args {
|
||||
margin-left: 2em;
|
||||
}
|
||||
|
||||
.arg {
|
||||
margin-top: 0.125em;
|
||||
> :first-child::after {
|
||||
color: #999999;
|
||||
content: ', ';
|
||||
}
|
||||
}
|
||||
|
||||
.bracket, .paren {
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
.object {
|
||||
background-color: #333333;
|
||||
border: 1px solid black;
|
||||
padding: 0.25em;
|
||||
:scope {
|
||||
margin-top: 0.5em;
|
||||
}
|
||||
|
||||
li {
|
||||
margin-bottom: 0.5em;
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
border-bottom: none;
|
||||
padding: 1em;
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
&:nth-of-type(2n) {
|
||||
background-color: rgba(0, 0, 0, 0.025);
|
||||
}
|
||||
&:nth-of-type(2n+1) {
|
||||
background-color: rgba(255, 255, 255, 0.025);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@ const decorate = compose(
|
|||
);
|
||||
|
||||
const Actions = ({
|
||||
context,
|
||||
name,
|
||||
label,
|
||||
options,
|
||||
|
@ -22,7 +23,15 @@ const Actions = ({
|
|||
{
|
||||
value.traversals.length > 0 && (
|
||||
value.traversals.map(
|
||||
(traversal) => <li><Value.component value={traversal} /></li>,
|
||||
(traversal) => (
|
||||
<li>
|
||||
<Value.component
|
||||
context={context}
|
||||
type="void|ticking-promise"
|
||||
value={traversal}
|
||||
/>
|
||||
</li>
|
||||
),
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
|
@ -8,7 +8,10 @@ const Bool = ({
|
|||
label,
|
||||
value,
|
||||
}) => (
|
||||
<input name={name} type="checkbox" checked={value} />
|
||||
<select value={value}>
|
||||
<option>false</option>
|
||||
<option>true</option>
|
||||
</select>
|
||||
);
|
||||
|
||||
Bool.propTypes = {
|
||||
|
|
|
@ -1,11 +1,16 @@
|
|||
.condition {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.operator {
|
||||
margin: 0 0.5em;
|
||||
margin: 0.25em 0;
|
||||
text-align: center;
|
||||
text-align-last: center;
|
||||
}
|
||||
|
||||
.operand .steps {
|
||||
display: flex;
|
||||
}
|
||||
|
|
|
@ -4,29 +4,11 @@ import PropTypes from 'prop-types';
|
|||
import React from 'react';
|
||||
|
||||
import propertyPropTypes from './property-prop-types';
|
||||
import Value from './value.type-renderer';
|
||||
|
||||
const renderValue = (value) => {
|
||||
switch (value.type) {
|
||||
case 'traversal': {
|
||||
const {steps} = value;
|
||||
return (
|
||||
<span>
|
||||
{steps.length > 0 && (
|
||||
steps.slice(1).reduce((r, step) => `${r}.${step.key}`, steps[0].key)
|
||||
)}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
case 'literal':
|
||||
return <input value={value.value} />;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
const renderOperand = (operand) => (
|
||||
const renderOperand = (context, operand, type) => (
|
||||
<span className="operand">
|
||||
{renderValue(operand)}
|
||||
<Value.component context={context} type={type} value={operand} />
|
||||
</span>
|
||||
);
|
||||
|
||||
|
@ -44,6 +26,7 @@ const decorate = compose(
|
|||
);
|
||||
|
||||
const Condition = ({
|
||||
context,
|
||||
name,
|
||||
label,
|
||||
options,
|
||||
|
@ -59,6 +42,7 @@ const Condition = ({
|
|||
case '>=':
|
||||
case '<':
|
||||
case '<=':
|
||||
const type = -1 !== ['is', 'isnt'].indexOf(value.operator) ? 'any' : 'number';
|
||||
return value.operands.slice(1).reduce(
|
||||
(r, operand) => (
|
||||
<>
|
||||
|
@ -66,10 +50,10 @@ const Condition = ({
|
|||
<select className="operator" value={value.operator}>
|
||||
{binaryOps.map(([k, v]) => <option value={k}>{v}</option>)}
|
||||
</select>
|
||||
{renderOperand(operand)}
|
||||
{renderOperand(context, operand, type)}
|
||||
</>
|
||||
),
|
||||
renderOperand(value.operands[0]),
|
||||
renderOperand(context, value.operands[0], type),
|
||||
);
|
||||
default:
|
||||
return undefined;
|
||||
|
|
0
src/client/components/types/routines.raw.scss
Normal file
0
src/client/components/types/routines.raw.scss
Normal file
49
src/client/components/types/routines.type-renderer.jsx
Normal file
49
src/client/components/types/routines.type-renderer.jsx
Normal file
|
@ -0,0 +1,49 @@
|
|||
import {compose} from '@avocado/core';
|
||||
import classnames from 'classnames';
|
||||
import contempo from 'contempo';
|
||||
import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
|
||||
import propertyPropTypes from './property-prop-types';
|
||||
import Actions from './actions.type-renderer';
|
||||
|
||||
const decorate = compose(
|
||||
contempo(require('./routines.raw.scss')),
|
||||
);
|
||||
|
||||
const Routines = ({
|
||||
context,
|
||||
name,
|
||||
label,
|
||||
options,
|
||||
value,
|
||||
}) => {
|
||||
const entries = Object.entries(value.routines);
|
||||
return (
|
||||
<div className="routines">
|
||||
<ol>
|
||||
{
|
||||
entries.length > 0 && (
|
||||
entries.map(
|
||||
([name, routine]) => (
|
||||
<li className="routine">
|
||||
<Actions.component context={context} value={routine.routine} />
|
||||
</li>
|
||||
),
|
||||
)
|
||||
)
|
||||
}
|
||||
</ol>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
Routines.propTypes = {
|
||||
...propertyPropTypes,
|
||||
value: PropTypes.shape({}).isRequired,
|
||||
};
|
||||
|
||||
export default {
|
||||
type: 'routines',
|
||||
component: decorate(Routines),
|
||||
};
|
35
src/client/components/types/steps-lists.js
Normal file
35
src/client/components/types/steps-lists.js
Normal file
|
@ -0,0 +1,35 @@
|
|||
import {flatten} from '@avocado/core';
|
||||
|
||||
import {typeFits, typeFromV} from './typing';
|
||||
|
||||
export const variableStepsList = (key, variable, description, type) => {
|
||||
const steps = [];
|
||||
if (typeFits(type, description.type)) {
|
||||
steps.push({type: 'key', key});
|
||||
if ('function' === typeof variable) {
|
||||
steps.push({type: 'invoke', args: []});
|
||||
}
|
||||
}
|
||||
if (!variable || !variable.contextDescription) {
|
||||
return steps;
|
||||
}
|
||||
const {children} = variable.contextDescription();
|
||||
const sublists = Object.entries(children)
|
||||
.map(([key, description]) => (
|
||||
flatten(variableStepsList(key, variable[key], description, type))
|
||||
))
|
||||
.map((childLists) => (
|
||||
childLists.length > 0 ? [{type: 'key', key}].concat(childLists) : []
|
||||
))
|
||||
.filter((lists) => lists.length > 0)
|
||||
return sublists.length > 0 ? sublists : [steps];
|
||||
};
|
||||
|
||||
export const contextStepsList = (context, type) => (
|
||||
flatten(
|
||||
Object.entries(context.all())
|
||||
.map(([key, variable]) => (
|
||||
variableStepsList(key, variable, {type: typeFromV(variable)}, type)
|
||||
))
|
||||
)
|
||||
);
|
95
src/client/components/types/steps.jsx
Normal file
95
src/client/components/types/steps.jsx
Normal file
|
@ -0,0 +1,95 @@
|
|||
import {compose} from '@avocado/core';
|
||||
import contempo from 'contempo';
|
||||
import React, {useState} from 'react';
|
||||
|
||||
import {contextStepsList} from './steps-lists';
|
||||
import {typeFits, typeFromSteps, typeFromV} from './typing';
|
||||
import Value from './value.type-renderer';
|
||||
|
||||
const decorate = compose(
|
||||
contempo(require('./steps.raw.scss')),
|
||||
);
|
||||
|
||||
const Steps = (props) => {
|
||||
const {context, steps, type, value} = props;
|
||||
let stepsList;
|
||||
if ('undefined' === typeof value) {
|
||||
stepsList = contextStepsList(context, type);
|
||||
}
|
||||
else {
|
||||
stepsList = contextStepsList(
|
||||
context,
|
||||
value.steps ? typeFromSteps(context, value.steps) : typeFromV(value.value),
|
||||
);
|
||||
}
|
||||
return (
|
||||
<div className="steps">
|
||||
{steps.map((step, i) => {
|
||||
switch (step.type) {
|
||||
case 'key':
|
||||
const tierOptions = Object.keys(stepsList.reduce((r, optionSteps) => {
|
||||
if (!optionSteps[i] || !optionSteps[i].key) {
|
||||
return r;
|
||||
}
|
||||
for (let j = 0; j < i; ++j) {
|
||||
if (steps[j].key !== optionSteps[j].key) {
|
||||
return r;
|
||||
}
|
||||
}
|
||||
return {...r, [optionSteps[i].key]: true};
|
||||
}, {}));
|
||||
if (0 === i) {
|
||||
const index = tierOptions.indexOf('context');
|
||||
if (-1 !== index) {
|
||||
tierOptions.splice(index, 1);
|
||||
}
|
||||
tierOptions.push('Literal');
|
||||
}
|
||||
return (
|
||||
<span className="key">
|
||||
<select value={steps[i].key}>
|
||||
{
|
||||
tierOptions
|
||||
.sort((l, r) => l.toLowerCase() < r.toLowerCase() ? -1 : 1)
|
||||
.map((tierOption) => <option>{tierOption}</option>)
|
||||
}
|
||||
</select>
|
||||
</span>
|
||||
);
|
||||
case 'invoke':
|
||||
return (
|
||||
<div className="invoke">
|
||||
<span className="paren open">(</span>
|
||||
{step.args.map((arg) => (
|
||||
<div className="arg">
|
||||
<Value.component
|
||||
context={context}
|
||||
type={arg.steps ? typeFromSteps(context, arg.steps) : typeFromV(arg.value)}
|
||||
value={arg}
|
||||
/>
|
||||
</div>
|
||||
))}
|
||||
<span className="paren close">)</span>
|
||||
</div>
|
||||
);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
})}
|
||||
{
|
||||
value && (
|
||||
<span className="assign">
|
||||
<span className="op">=</span>
|
||||
<Value.component
|
||||
context={context}
|
||||
type={typeFromSteps(context, steps)}
|
||||
value={value}
|
||||
/>
|
||||
</span>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default decorate(Steps);
|
53
src/client/components/types/steps.raw.scss
Normal file
53
src/client/components/types/steps.raw.scss
Normal file
|
@ -0,0 +1,53 @@
|
|||
:scope {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.key + .key {
|
||||
select {
|
||||
border-left: none;
|
||||
}
|
||||
}
|
||||
|
||||
.args {
|
||||
margin-left: 2em;
|
||||
}
|
||||
|
||||
.arg {
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
display: flex;
|
||||
margin-left: 2em;
|
||||
padding: 0.5em;
|
||||
&:not(:last-of-type) {
|
||||
border-bottom: none;
|
||||
}
|
||||
&:nth-of-type(2n) {
|
||||
background-color: rgba(0, 0, 0, 0.025);
|
||||
}
|
||||
&:nth-of-type(2n+1) {
|
||||
background-color: rgba(255, 255, 255, 0.025);
|
||||
}
|
||||
}
|
||||
|
||||
.arg .steps {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.bracket, .paren {
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
.invoke {
|
||||
// border-left: 1px dotted rgba(255, 255, 255, 0.1);
|
||||
padding-left: 1em;
|
||||
}
|
||||
|
||||
.assign {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.op {
|
||||
align-self: flex-start;
|
||||
margin: 0.5em 1em;
|
||||
}
|
61
src/client/components/types/typing.js
Normal file
61
src/client/components/types/typing.js
Normal file
|
@ -0,0 +1,61 @@
|
|||
export function typeFromV(v) {
|
||||
if ('undefined' === typeof v) {
|
||||
return 'undefined';
|
||||
}
|
||||
if (null === v) {
|
||||
return 'null';
|
||||
}
|
||||
if ('number' === typeof v) {
|
||||
return 'number';
|
||||
}
|
||||
if ('string' === typeof v) {
|
||||
return 'string';
|
||||
}
|
||||
if ('boolean' === typeof v) {
|
||||
return 'bool';
|
||||
}
|
||||
if (v.length && 2 === v.length && v instanceof Array) {
|
||||
return 'vector';
|
||||
}
|
||||
if (!v.contextDescription) {
|
||||
return 'object';
|
||||
}
|
||||
const {type} = v.contextDescription();
|
||||
return type;
|
||||
}
|
||||
|
||||
export function typeFromSteps(context, steps) {
|
||||
if (!steps || 0 === steps.length) {
|
||||
return 'undefined';
|
||||
}
|
||||
const first = context.map.get(steps[0].key);
|
||||
const [, type] = steps.slice(1).reduce(
|
||||
([v, type], step, i) => {
|
||||
if (i === steps.length - 2) {
|
||||
if (v.contextDescription) {
|
||||
const {children} = v.contextDescription();
|
||||
return [undefined, step.key ? children[step.key].type : type];
|
||||
}
|
||||
else {
|
||||
return [undefined, type];
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (step.key) {
|
||||
const {children} = v.contextDescription();
|
||||
return [v[step.key], children[step.key].type];
|
||||
}
|
||||
else {
|
||||
return [v, type];
|
||||
}
|
||||
}
|
||||
step
|
||||
},
|
||||
[first, typeFromV(first)],
|
||||
);
|
||||
return type;
|
||||
}
|
||||
|
||||
export function typeFits(reference, candidate) {
|
||||
return 'any' === reference || -1 !== (reference.split('|') || []).indexOf(candidate);
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
.fn {
|
||||
text-align-last: right;
|
||||
}
|
||||
|
||||
:scope {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.object {
|
||||
background-color: #333333;
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
padding: 0.25em;
|
||||
}
|
||||
|
||||
.object, input {
|
||||
// border-left: none;
|
||||
}
|
||||
|
||||
select {
|
||||
margin-right: 0.25em;
|
||||
}
|
|
@ -4,67 +4,46 @@ import contempo from 'contempo';
|
|||
import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
|
||||
import Bool from './bool.type-renderer';
|
||||
import propertyPropTypes from './property-prop-types';
|
||||
import Steps from './steps';
|
||||
import {contextStepsList} from './steps-lists';
|
||||
import {typeFits, typeFromSteps, typeFromV} from './typing';
|
||||
|
||||
const reduceStep = (r, step) => {
|
||||
switch (step.type) {
|
||||
case 'key':
|
||||
return `${r}.${step.key}`;
|
||||
case 'invoke':
|
||||
return (
|
||||
<span className="step">
|
||||
<span className="fn"><input value={r} /></span>
|
||||
<span className="paren open">(</span>
|
||||
<div className="args">
|
||||
{
|
||||
step.args.length > 0 && (
|
||||
step.args.slice(1).map(renderValue).reduce(
|
||||
(r2, element, i) => (
|
||||
<>
|
||||
{r2}
|
||||
<div className={classnames('arg', step.args[i + 1].type)}>
|
||||
{element}
|
||||
</div>
|
||||
</>
|
||||
),
|
||||
<div className={classnames('arg', step.args[0].type)}>
|
||||
{renderValue(step.args[0])}
|
||||
</div>,
|
||||
)
|
||||
)
|
||||
}
|
||||
</div>
|
||||
<span className="paren close">)</span>
|
||||
</span>
|
||||
);
|
||||
default:
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
|
||||
const renderValue = (value) => {
|
||||
const renderValue = (context, type, value) => {
|
||||
switch (value.type) {
|
||||
case 'traversal': {
|
||||
const {steps} = value;
|
||||
return (
|
||||
<span>
|
||||
{steps.length > 0 && (
|
||||
steps.slice(1).reduce(
|
||||
reduceStep,
|
||||
steps[0].key,
|
||||
)
|
||||
)}
|
||||
</span>
|
||||
);
|
||||
return <Steps context={context} steps={value.steps} type={type} value={value.value} />;
|
||||
}
|
||||
case 'literal':
|
||||
if (
|
||||
null === value.value
|
||||
|| 'string' === typeof value.value
|
||||
|| 'number' === typeof value.value
|
||||
) {
|
||||
return <span className="wrapper"><input value={value.value} /></span>;
|
||||
// const type = typeFromV(value.value);
|
||||
const stepsList = contextStepsList(context, type);
|
||||
const tierOptions = Object.keys(stepsList.reduce((r, optionSteps) => {
|
||||
if (!optionSteps[0] || !optionSteps[0].key) {
|
||||
return r;
|
||||
}
|
||||
return {...r, [optionSteps[0].key]: true};
|
||||
}, {}));
|
||||
tierOptions.splice(tierOptions.indexOf('context'), 1);
|
||||
tierOptions.push('Literal');
|
||||
return (
|
||||
<div className="literal">
|
||||
<select value="Literal">
|
||||
{
|
||||
tierOptions
|
||||
.sort((l, r) => l.toLowerCase() < r.toLowerCase() ? -1 : 1)
|
||||
.map((tierOption) => <option>{tierOption}</option>)
|
||||
}
|
||||
</select>
|
||||
{
|
||||
(() => {
|
||||
switch (type) {
|
||||
case 'bool':
|
||||
return <Bool.component value={value.value} />;
|
||||
case 'number':
|
||||
case 'string':
|
||||
return <span className="wrapper"><input value={value.value} /></span>;
|
||||
case 'object':
|
||||
return (
|
||||
<div className="object">
|
||||
<span className="bracket open">{'{'}</span>
|
||||
|
@ -80,6 +59,13 @@ const renderValue = (value) => {
|
|||
default:
|
||||
return null;
|
||||
}
|
||||
})()
|
||||
}
|
||||
</div>
|
||||
);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
const decorate = compose(
|
||||
|
@ -87,11 +73,13 @@ const decorate = compose(
|
|||
);
|
||||
|
||||
const Value = ({
|
||||
context,
|
||||
name,
|
||||
label,
|
||||
options,
|
||||
type,
|
||||
value,
|
||||
}) => renderValue(value);
|
||||
}) => renderValue(context, type || 'any', value);
|
||||
|
||||
Value.propTypes = {
|
||||
...propertyPropTypes,
|
||||
|
|
|
@ -72,7 +72,7 @@ code {
|
|||
|
||||
label {
|
||||
align-items: left;
|
||||
background-color: #272727;
|
||||
background-color: rgba(255, 255, 255, 0.025);
|
||||
color: #ffffff;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
@ -93,12 +93,16 @@ label {
|
|||
}
|
||||
|
||||
label:nth-of-type(2n+1) {
|
||||
background-color: #1d1d1d
|
||||
background-color: rgba(0, 0, 0, 0.025);
|
||||
}
|
||||
|
||||
[contenteditable] {
|
||||
cursor: text;
|
||||
}
|
||||
|
||||
input {
|
||||
background: #333;
|
||||
border: 1px solid black;
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
color: #ffffff;
|
||||
font-size: 0.75em;
|
||||
padding: 0.5em;
|
||||
|
@ -106,7 +110,7 @@ input {
|
|||
|
||||
fieldset {
|
||||
background-color: #151515;
|
||||
border: 1px solid #000000;
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
display: inline-block;
|
||||
margin: 0 0 1em 0;
|
||||
padding: 0.5em;
|
||||
|
@ -121,16 +125,19 @@ button, input[type="checkbox"], input[type="checkbox"] + label {
|
|||
|
||||
select {
|
||||
background: #222222;
|
||||
border: 1px solid #000000;
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
color: #ffffff;
|
||||
cursor: pointer;
|
||||
font-size: 0.75em;
|
||||
line-height: 1em;
|
||||
margin: 0.25em 0;
|
||||
-moz-appearance: none;
|
||||
-webkit-appearance: none;
|
||||
padding: 0.5em;
|
||||
}
|
||||
|
||||
*:focus {
|
||||
position: relative;
|
||||
box-shadow: 0 0 2px 0 #d68030ff;
|
||||
outline: none;
|
||||
z-index: 1;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user