add feature remove button, style buttons
This commit is contained in:
parent
e7a7673d68
commit
e570bdfeff
8 changed files with 133 additions and 79 deletions
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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 <></>
|
||||
|
|
|
@ -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')
|
||||
|
@ -79,6 +16,80 @@ const Features = ({ phones, features, dispatch }) => {
|
|||
setNewPositivePhones('');
|
||||
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"
|
||||
|
|
|
@ -1,16 +1,22 @@
|
|||
div.Features {
|
||||
|
||||
ul.Features__list li {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
|
||||
span.feature--names-and-phones {
|
||||
ul.Features__list {
|
||||
width: 100%;
|
||||
|
||||
li {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(60px, 1fr));
|
||||
}
|
||||
|
||||
span.feature-name {
|
||||
font-weight: 600;
|
||||
grid-template-columns: 10fr 10fr 1fr;
|
||||
margin: 0.5em 0;
|
||||
place-items: center center;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
|
@ -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>
|
||||
|
||||
|
||||
|
|
|
@ -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>
|
||||
</>
|
||||
);
|
||||
|
|
|
@ -77,4 +77,12 @@ 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}
|
||||
}
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue