add feature remove button, style buttons

This commit is contained in:
Sorrel Bri 2020-02-28 13:12:19 -08:00
parent e7a7673d68
commit e570bdfeff
8 changed files with 133 additions and 79 deletions

View file

@ -24,7 +24,7 @@ div.App {
display: grid;
width: 100%;
place-items: center center;
grid-template-columns: repeat(auto-fit, minmax(20em, 1fr));
grid-template-columns: repeat(auto-fit, minmax(25em, 1fr));
grid-template-rows: repeat(auto-fill, minmax(300px, 1fr));
div {
@ -34,4 +34,22 @@ div.App {
overflow-y: scroll;
}
}
button.form, input[type="submit"].form, input[type="button"].form {
height: 2em;
border-radius: 0.25em;
border-color: transparent;
margin: 0.2em auto;
width: 10em;
}
button.form--add, input[type="submit"].form--add, input[type="button"].form--add{
background-color: greenyellow;
color: black;
}
button.form--remove, input[type="submit"].form--remove, input[type="button"].form--remove {
background-color: red;
color: white;
}
}

View file

@ -41,7 +41,7 @@ const Epochs = ({epochs, errors, dispatch}) => {
const renderAddEpochButton = index => {
if (index === epochs.length - 1 ) return (
<form onSubmit={e=>addEpoch(e)}>
<input type="submit" name="add-epoch" value="Add Epoch" ></input>
<input className="form form--add" type="submit" name="add-epoch" value="Add Epoch" ></input>
</form>
)
return <></>

View file

@ -4,69 +4,6 @@ import './Features.scss';
import type { featureAction } from '../reducers/reducer.features';
const parsePhonesFromFeatureObject = featureObject => {
const getProperty = property => object => object[property]
const getFeatureMap = (featureObject) => {
return Object.keys(featureObject).map(feature => {
const plusPhones = featureObject[feature].positive.map(getProperty('grapheme')).join(' / ');
const minusPhones = featureObject[feature].negative.map(getProperty('grapheme')).join(' / ');
return {[feature]: {plus: plusPhones, minus: minusPhones}}
})
}
const getFeatureMapJSX = (featureMap) => {
return featureMap.map((feature, index) => {
const featureName = Object.keys(feature);
const { plus, minus } = feature[featureName];
return (
<li key={`feature__${featureName}`}>
<span className="feature--names-and-phones">
<span className="feature--feature-name">
{`[+ ${featureName}]`}
</span>
<span className="feature--feature-phones">
{plus}
</span>
</span>
<span className="feature--names-and-phones">
<span className="feature--feature-name">
{`[- ${featureName}]`}
</span>
<span className="feature--feature-phones">
{minus}
</span>
</span>
</li>
)
})
}
const featureMap = getFeatureMap(featureObject);
const featureMapJSX = getFeatureMapJSX(featureMap);
return featureMapJSX;
}
const parseNewPhones = somePhones => {
if (somePhones === '') return [''];
return somePhones.split('/').map(phone => phone.trim());
}
const handleClickDispatch = e => dispatchFunction => actionBuilder => actionParameters => {
e.preventDefault();
return dispatchFunction(actionBuilder(actionParameters));
}
const buildAddFeatureAction = ([newPositivePhones, newNegativePhones, feature]): featureAction => (
{
type: "ADD_FEATURE",
value: {
positivePhones: parseNewPhones(newPositivePhones),
negativePhones: parseNewPhones(newNegativePhones),
feature
}
}
)
const Features = ({ phones, features, dispatch }) => {
const [feature, setFeature] = useState('aspirated')
@ -80,6 +17,80 @@ const Features = ({ phones, features, dispatch }) => {
setNewNegativePhones('');
}
const handleDeleteClick = (e, feature) => {
e.preventDefault();
const deleteFeatureAction = {
type: "DELETE_FEATURE",
value: feature
}
return dispatch(deleteFeatureAction);
}
const parsePhonesFromFeatureObject = featureObject => {
const getProperty = property => object => object[property]
const getFeatureMap = (featureObject) => {
return Object.keys(featureObject).map(feature => {
const plusPhones = featureObject[feature].positive.map(getProperty('grapheme')).join(' / ');
const minusPhones = featureObject[feature].negative.map(getProperty('grapheme')).join(' / ');
return {[feature]: {plus: plusPhones, minus: minusPhones}}
})
}
const getFeatureMapJSX = (featureMap) => {
return featureMap.map((feature, index) => {
const [featureName] = Object.keys(feature);
const { plus, minus } = feature[featureName];
return (
<li key={`feature__${featureName}`}>
<span className="feature--names-and-phones">
<span className="feature--feature-name">
{`[+ ${featureName}]`}
</span>
<span className="feature--feature-phones">
{plus}
</span>
</span>
<span className="feature--names-and-phones">
<span className="feature--feature-name">
{`[- ${featureName}]`}
</span>
<span className="feature--feature-phones">
{minus}
</span>
</span>
<button className="delete-feature" onClick={e => handleDeleteClick(e, featureName)}>X</button>
</li>
)
})
}
const featureMap = getFeatureMap(featureObject);
const featureMapJSX = getFeatureMapJSX(featureMap);
return featureMapJSX;
}
const parseNewPhones = somePhones => {
if (somePhones === '') return [''];
return somePhones.split('/').map(phone => phone.trim());
}
const handleClickDispatch = e => dispatchFunction => actionBuilder => actionParameters => {
e.preventDefault();
return dispatchFunction(actionBuilder(actionParameters));
}
const buildAddFeatureAction = ([newPositivePhones, newNegativePhones, feature]): featureAction => (
{
type: "ADD_FEATURE",
value: {
positivePhones: parseNewPhones(newPositivePhones),
negativePhones: parseNewPhones(newNegativePhones),
feature
}
}
)
return (
<div className="Features" data-testid="Features">
@ -114,6 +125,7 @@ const Features = ({ phones, features, dispatch }) => {
</label>
<input
className="form form--add"
type="submit"
onClick={e => handleClickDispatch(e)(dispatch)(buildAddFeatureAction)([newPositivePhones, newNegativePhones, feature])}
value="Add feature"

View file

@ -1,16 +1,22 @@
div.Features {
ul.Features__list li {
display: grid;
grid-template-columns: 1fr 1fr;
ul.Features__list {
width: 100%;
span.feature--names-and-phones {
li {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(60px, 1fr));
}
grid-template-columns: 10fr 10fr 1fr;
margin: 0.5em 0;
place-items: center center;
span.feature-name {
font-weight: 600;
span.feature--names-and-phones {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
}
span.feature-name {
font-weight: 600;
}
}
}
@ -23,4 +29,12 @@ div.Features {
font-size: 1em;
}
}
button.delete-feature {
background-color: red;
border-color: transparent;
border-radius: 0.5em;
color: white;
max-height: 1.5em;
}
}

View file

@ -65,8 +65,8 @@ const Options = ({ options, dispatch }) => {
<span className="Options__output-example"> *proto > *epoch > output</span>
</label> */}
<input type="submit" value="Run Changes"></input>
<input type="button" value="Clear Output" onClick={e=>handleOutputClearSubmit(e)}/>
<input className="form form--add" type="submit" value="Run Changes"></input>
<input className="form form--remove" type="button" value="Clear Output" onClick={e=>handleOutputClearSubmit(e)}/>
</form>

View file

@ -103,7 +103,7 @@ const SoundChangeSuite = props => {
></textarea>
</form>
<form onSubmit={e=>removeEpoch(e, epoch.name)}>
<input type="submit" name="remove-epoch" value={`remove ${epoch.name}`}></input>
<input className="form form--remove" type="submit" name="remove-epoch" value={`remove ${epoch.name}`}></input>
</form>
</>
);

View file

@ -78,3 +78,11 @@ export const addFeature = (state: stateType, action: featureAction): stateType =
let newFeature = {[action.value.feature]: {positive: positivePhones, negative: negativePhones}};
return {...state, features:{...state.features, ...newFeature}, phones: newPhoneObject}
}
export const deleteFeature = (state, action) => {
console.log('deleting')
const deletedFeature = action.value;
delete state.features[deletedFeature];
console.log(state)
return {...state}
}

View file

@ -3,7 +3,7 @@ import { addLexeme, setLexicon } from './reducer.lexicon';
import type { lexiconAction } from './reducer.lexicon';
import { addEpoch, setEpoch, removeEpoch } from './reducer.epochs';
import type { epochAction } from './reducer.epochs';
import { addFeature } from './reducer.features';
import { addFeature, deleteFeature } from './reducer.features';
import type { featureAction } from './reducer.features';
import type { optionsAction } from './reducer.options';
import { setOptions } from './reducer.options';
@ -56,6 +56,8 @@ export const stateReducer = (state: stateType, action: actionType): stateType =>
case 'ADD_FEATURE': return addFeature(state, action);
case 'DELETE_FEATURE': return deleteFeature(state, action);
case 'SET_OPTIONS': return setOptions(state, action);
case 'CLEAR': return clearOutput(state, action);