Improve mobile responsiveness and styling
This commit is contained in:
parent
650b7c28d6
commit
8c82698593
233
src/App.scss
233
src/App.scss
@ -1,7 +1,18 @@
|
||||
// Color variables
|
||||
$background-color: #f0f0b8;
|
||||
$primary-color: #b2a336;
|
||||
$primary-color-dark: #a69530;
|
||||
$text-color: #333;
|
||||
$accent-color: #a63333;
|
||||
$accent-color-dark: #6a3131;
|
||||
$white: #fff;
|
||||
|
||||
body {
|
||||
background-color: #f0f0b8;
|
||||
background-color: $background-color;
|
||||
font-size: 18pt;
|
||||
font-family: "Biwa";
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
input {
|
||||
@ -10,11 +21,13 @@ input {
|
||||
|
||||
main {
|
||||
text-align: center;
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
div .container {
|
||||
max-width: 62rem;
|
||||
margin: auto;
|
||||
padding: 0 1rem;
|
||||
}
|
||||
|
||||
div .results {
|
||||
@ -22,30 +35,74 @@ div .results {
|
||||
}
|
||||
|
||||
div .textInput {
|
||||
max-width: 70%;
|
||||
max-width: 100%;
|
||||
margin: auto;
|
||||
font-size: 22px;
|
||||
}
|
||||
|
||||
input {
|
||||
width: 100%;
|
||||
padding: 8px;
|
||||
box-sizing: border-box;
|
||||
border: 1px solid $primary-color;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.searchDropdown {
|
||||
font-size: 22px;
|
||||
font-family: "Biwa";
|
||||
padding: 10px 15px;
|
||||
border: 2px solid $primary-color;
|
||||
border-radius: 8px;
|
||||
background-color: $white;
|
||||
color: $text-color;
|
||||
cursor: pointer;
|
||||
appearance: none;
|
||||
-webkit-appearance: none;
|
||||
-moz-appearance: none;
|
||||
$encoded-primary-color: str-slice("#{$primary-color}", 2);
|
||||
background-image: url("data:image/svg+xml;charset=US-ASCII,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22292.4%22%20height%3D%22292.4%22%3E%3Cpath%20fill%3D%22%23#{$encoded-primary-color}%22%20d%3D%22M287%2069.4a17.6%2017.6%200%200%200-13-5.4H18.4c-5%200-9.3%201.8-12.9%205.4A17.6%2017.6%200%200%200%200%2082.2c0%205%201.8%209.3%205.4%2012.9l128%20127.9c3.6%203.6%207.8%205.4%2012.8%205.4s9.2-1.8%2012.8-5.4L287%2095c3.5-3.5%205.4-7.8%205.4-12.8%200-5-1.9-9.2-5.5-12.8z%22%2F%3E%3C%2Fsvg%3E");
|
||||
background-repeat: no-repeat;
|
||||
background-position: right 15px top 50%;
|
||||
background-size: 12px auto;
|
||||
padding-right: 35px;
|
||||
transition: border-color 0.3s, box-shadow 0.3s;
|
||||
width: 100%;
|
||||
max-width: 300px;
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
.searchDropdown:hover, .searchDropdown:focus {
|
||||
border-color: $primary-color-dark;
|
||||
box-shadow: 0 0 0 3px rgba($primary-color, 0.25);
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.searchButton {
|
||||
padding: 5px;
|
||||
margin: 10px;
|
||||
padding: 10px 15px;
|
||||
margin: 10px 5px;
|
||||
font-size: 22px;
|
||||
font-family: "Biwa";
|
||||
background-color: $primary-color;
|
||||
color: $white;
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
cursor: pointer;
|
||||
transition: background-color 0.3s, transform 0.1s;
|
||||
min-width: 120px;
|
||||
}
|
||||
|
||||
.searchButton:hover {
|
||||
background-color: $primary-color-dark;
|
||||
}
|
||||
|
||||
.searchButton:active {
|
||||
transform: translateY(1px);
|
||||
}
|
||||
|
||||
.searchResult {
|
||||
border-bottom: 1px solid #b2a336;
|
||||
padding: 5px;
|
||||
border-bottom: 1px solid $primary-color;
|
||||
padding: 10px 5px;
|
||||
}
|
||||
|
||||
.searchResultHeader {
|
||||
@ -53,18 +110,172 @@ input {
|
||||
}
|
||||
|
||||
.additionalNotes {
|
||||
color: #a63333;
|
||||
color: $accent-color;
|
||||
}
|
||||
|
||||
.semField {
|
||||
font-variant: small-caps;
|
||||
color: #6a3131;
|
||||
color: $accent-color-dark;
|
||||
}
|
||||
|
||||
.saimiarNounMorpho {
|
||||
color: #a63333;
|
||||
color: $accent-color;
|
||||
i {
|
||||
color: #6a3131;
|
||||
|
||||
color: $accent-color-dark;
|
||||
}
|
||||
}
|
||||
|
||||
.passwordDialog {
|
||||
padding: 20px;
|
||||
border-radius: 4px;
|
||||
border: 1px solid $primary-color;
|
||||
background-color: $background-color;
|
||||
width: 90%;
|
||||
max-width: 400px;
|
||||
}
|
||||
|
||||
.passwordDialog h3 {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.passwordDialog input {
|
||||
margin-bottom: 10px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.dialogButtons {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.passwordDialog button {
|
||||
margin: 5px;
|
||||
padding: 8px 15px;
|
||||
background-color: $primary-color;
|
||||
color: $white;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
min-width: 80px;
|
||||
}
|
||||
|
||||
.passwordDialog button:hover {
|
||||
background-color: $primary-color-dark;
|
||||
}
|
||||
|
||||
.searchControls {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
.buttonGroup {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
|
||||
.dropdownContainer {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.dropdownLabel {
|
||||
font-weight: bold;
|
||||
margin-bottom: 5px;
|
||||
color: $accent-color-dark;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
/* Responsive styles for mobile devices */
|
||||
@media (max-width: 768px) {
|
||||
body {
|
||||
font-size: 16pt;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 1.8rem;
|
||||
}
|
||||
|
||||
div .textInput {
|
||||
max-width: 100%;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.searchDropdown {
|
||||
font-size: 18px;
|
||||
padding: 12px 15px;
|
||||
margin: 10px auto;
|
||||
width: 100%;
|
||||
max-width: none;
|
||||
}
|
||||
|
||||
.search {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.search button {
|
||||
width: 100%;
|
||||
margin: 5px 0;
|
||||
}
|
||||
|
||||
.searchControls {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.buttonGroup {
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.dropdownContainer {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.dropdownLabel {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.searchButton {
|
||||
font-size: 18px;
|
||||
padding: 12px 15px;
|
||||
margin: 5px 0;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
body {
|
||||
font-size: 14pt;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
main {
|
||||
padding: 0.5rem;
|
||||
}
|
||||
|
||||
div .container {
|
||||
padding: 0 0.5rem;
|
||||
}
|
||||
|
||||
.searchDropdown {
|
||||
font-size: 16px;
|
||||
padding: 10px 12px;
|
||||
}
|
||||
|
||||
.searchButton {
|
||||
font-size: 16px;
|
||||
padding: 10px 12px;
|
||||
}
|
||||
}
|
||||
|
60
src/App.tsx
60
src/App.tsx
@ -25,9 +25,17 @@ const PasswordDialog = (_props) => {
|
||||
|
||||
return (
|
||||
<dialog className="passwordDialog">
|
||||
<input type="password" placeholder="enter password" value={password} onChange={ (evt) => setPasswordStr(evt.target.value) } />
|
||||
<button onClick={save}>Save</button>
|
||||
<button onClick={cancel}>Cancel</button>
|
||||
<h3>Enter Password</h3>
|
||||
<input
|
||||
type="password"
|
||||
placeholder="enter password"
|
||||
value={password}
|
||||
onChange={ (evt) => setPasswordStr(evt.target.value) }
|
||||
/>
|
||||
<div className="dialogButtons">
|
||||
<button onClick={save}>Save</button>
|
||||
<button onClick={cancel}>Cancel</button>
|
||||
</div>
|
||||
</dialog>);
|
||||
};
|
||||
|
||||
@ -157,9 +165,22 @@ const App = (_props) => {
|
||||
|
||||
const conlangs = [Conlang.Saimiar, Conlang.Elesu, Conlang.Tukvaysi, Conlang.Juteyuji];
|
||||
const langSelectDropdown = (
|
||||
<select className="searchDropdown" value={conlang} onChange={ handleLangChange }>
|
||||
{conlangs.map((conlang) => <option value={conlang} key={conlang}>{renderConlang(conlang)}</option>)}
|
||||
</select>
|
||||
<div className="dropdownContainer">
|
||||
<label htmlFor="languageSelect" className="dropdownLabel">Select Language:</label>
|
||||
<select
|
||||
id="languageSelect"
|
||||
className="searchDropdown"
|
||||
value={conlang}
|
||||
onChange={handleLangChange}
|
||||
aria-label="Select language"
|
||||
>
|
||||
{conlangs.map((conlang) => (
|
||||
<option value={conlang} key={conlang}>
|
||||
{renderConlang(conlang)}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
);
|
||||
|
||||
const showPasswordBox = () => {
|
||||
@ -177,19 +198,28 @@ const App = (_props) => {
|
||||
<p><b>Kucinako</b> (<i>Saimiar</i> "word-book") is a dictionary of words in various languages of the world Arzhanø, and their English
|
||||
equivalents.</p>
|
||||
<div className="textInput">
|
||||
<input className="textInput" type="text" value={ searchBoxInput } onChange={ (evt) => {
|
||||
setSearchBoxInput(evt.target.value);
|
||||
} } />
|
||||
<input
|
||||
className="textInput"
|
||||
type="text"
|
||||
value={ searchBoxInput }
|
||||
onChange={ (evt) => {
|
||||
setSearchBoxInput(evt.target.value);
|
||||
}}
|
||||
placeholder="Enter search term"
|
||||
/>
|
||||
</div>
|
||||
<div className="searchControls">
|
||||
{ langSelectDropdown }
|
||||
<div className="buttonGroup">
|
||||
<button onClick={ () => handleSearch(SearchDirection.ToEnglish) } className="searchButton">{renderConlang(conlang)}</button>
|
||||
<button onClick={ () => handleSearch(SearchDirection.ToConlang) } className="searchButton">English</button>
|
||||
<button onClick={ showPasswordBox } className="searchButton">Password</button>
|
||||
</div>
|
||||
</div>
|
||||
<br/>
|
||||
{ langSelectDropdown }
|
||||
<button onClick={ () => handleSearch(SearchDirection.ToEnglish) } className="searchButton">{renderConlang(conlang)}</button>
|
||||
<button onClick={ () => handleSearch(SearchDirection.ToConlang) } className="searchButton">English</button>
|
||||
<button onClick={ showPasswordBox } className="searchButton">Password</button>
|
||||
</div>
|
||||
<Results
|
||||
searchResults={ searchResults }
|
||||
searchTerm= { searchTerm }
|
||||
searchTerm={ searchTerm }
|
||||
conlang={ conlang }
|
||||
direction={ direction }
|
||||
/>
|
||||
|
@ -20,6 +20,7 @@ const EntryBase = (props: BaseProps) => {
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
flexDirection: "row",
|
||||
flexWrap: "wrap",
|
||||
};
|
||||
|
||||
const controlStyle = {
|
||||
@ -27,14 +28,20 @@ const EntryBase = (props: BaseProps) => {
|
||||
justifyContent: "space-between",
|
||||
flexDirection: "row",
|
||||
minWidth: "20%",
|
||||
marginTop: "10px",
|
||||
};
|
||||
|
||||
const save = () => {
|
||||
updateEntry(props.conlang, props.id, english);
|
||||
};
|
||||
|
||||
const engTranslation = editing ? <input type="text" value={ english } onChange={ (evt) => setEnglish(evt.target.value) }/>
|
||||
: english;
|
||||
const engTranslation = editing ?
|
||||
<input
|
||||
type="text"
|
||||
value={ english }
|
||||
onChange={ (evt) => setEnglish(evt.target.value) }
|
||||
style={{ width: "100%", marginTop: "5px" }}
|
||||
/> : english;
|
||||
|
||||
const EditControls = ({onSave}: { onSave: () => void }) => {
|
||||
const cancel = () => setEditing(false);
|
||||
|
@ -1,6 +1,8 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"lib": ["ES2020", "dom"]
|
||||
"lib": ["ES2020", "dom"],
|
||||
"jsx": "react",
|
||||
"esModuleInterop": true
|
||||
},
|
||||
"include": ["src/**/*"]
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user