Skip to content
Snippets Groups Projects
Commit 6bc645be authored by Thomas Schneider's avatar Thomas Schneider
Browse files

Merge branch 'irgendwas-mit-design' into 'main'

A bunch of design stuff

See merge request !3
parents 1a0f734a ca7f36bd
No related branches found
No related tags found
1 merge request!3A bunch of design stuff
...@@ -6,7 +6,7 @@ end_of_line = lf ...@@ -6,7 +6,7 @@ end_of_line = lf
trim_trailing_whitespace = true trim_trailing_whitespace = true
insert_final_newline = true insert_final_newline = true
[*.{json,less,ts,html.j2}] [*.{json,less,ts,html.j2,css}]
indent_style = tab indent_style = tab
indent_size = 4 indent_size = 4
......
...@@ -12,8 +12,11 @@ body { ...@@ -12,8 +12,11 @@ body {
font-family: "Noto Sans", sans-serif; font-family: "Noto Sans", sans-serif;
padding: 0; padding: 0;
margin: 0; margin: 0;
background-color: #fff;
color: #000;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@media not print { @media not print {
/* This magic constant approximately corresponds to 48px at A4 size, but scales /* This magic constant approximately corresponds to 48px at A4 size, but scales
* with the viewport/iframe size * with the viewport/iframe size
......
// the threshold at which we consider the screen "mobile" // the threshold at which we consider the screen "mobile"
@mobile_threshold: 700px; @mobile_threshold: 700px;
// the threshold at which we consider the screen "wide", i.e. display the preview on the
// side instead of at the bottom
@wide_threshold: 1700px;
// the border around the options in the fieldset-select-like things
@option_border: .3rem;
// the minimum size of the left area in the form layout
@label-width: 90px;
* { * {
box-sizing: border-box; box-sizing: border-box;
...@@ -13,6 +20,7 @@ body { ...@@ -13,6 +20,7 @@ body {
// adjust colors for light theme here // adjust colors for light theme here
--bg: #fff; --bg: #fff;
--fg: #000; --fg: #000;
--fg-dark: #bbb;
--accent: #80f; --accent: #80f;
--accent2: #c4f; --accent2: #c4f;
...@@ -20,10 +28,39 @@ body { ...@@ -20,10 +28,39 @@ body {
// adjust colors for dark theme here // adjust colors for dark theme here
--bg: #222; --bg: #222;
--fg: #fff; --fg: #fff;
--fg-dark: #888;
} }
}
@inputs: ~'input[type = "text"], input[type = "number"], textarea, select';
@buttons: ~'input[type = "submit"], button, a.button';
body, @{inputs}, @{buttons} {
&, &:hover, &:visited {
background-color: var(--bg); background-color: var(--bg);
color: var(--fg); color: var(--fg);
// ja, user agents haben lack gesoffen
font-size: 1rem;
}
}
@{inputs}, @{buttons}, fieldset {
border: .15rem solid var(--fg-dark);
border-radius: .25rem;
}
@{inputs} {
padding: .2rem .3rem;
}
@{buttons} {
padding: .2rem .6rem;
&:hover {
border-color: var(--accent2);
cursor: pointer;
text-decoration: none;
}
} }
a { a {
...@@ -127,84 +164,126 @@ main { ...@@ -127,84 +164,126 @@ main {
} }
} }
.preview { .section-container {
width: min(95vw, 100rem); display: grid;
/* A4 aspect ratio: √2:1 */ grid-gap: 1rem;
aspect-ratio: 1.4142135623730951; grid-template-columns: 1fr;
background-color: #fff; .section {
color: #000; grid-column-start: 1;
} }
.preview-small { @media screen and (min-width: @wide_threshold) {
width: 15rem; grid-template-columns: 1fr 1fr;
.preview-section {
grid-column-start: 2;
grid-row: 1/span 3;
}
}
} }
.preview-label { .preview {
place-self: center; /* A4 aspect ratio: √2:1 */
aspect-ratio: 1.4142135623730951;
} }
form { .preview-container .preview {
display: inline-block; width: 100%;
} }
@label-padding: 90px; // this is the form layout row container thingy
.box {
display: grid;
grid-template-columns: min(@label-width, auto) 1fr;
align-items: baseline;
label.for-text { label.for-text {
display: inline-block; display: inline-block;
min-width: @label-padding; justify-self: end;
text-align: right; font-size: 1.1rem;
} }
input[type = "text"], textarea { input[type = "text"], textarea {
width: 300px; justify-self: stretch;
} }
textarea { textarea {
height: 5em; height: 5rem;
vertical-align: top; }
} }
fieldset { // this is the form layout row with buttons in it
.buttons {
display: flex; display: flex;
flex-wrap: wrap; justify-content: flex-end;
align-items: stretch;
}
.box, .buttons {
margin: .5rem 0;
gap: 1ch;
} }
fieldset > div { // these are the fieldsets containing select-like options modeled with radio buttons
.select {
display: flex;
flex-wrap: wrap;
gap: 2 * @option_border;
.option {
display: flex; display: flex;
gap: 0.5rem;
flex-direction: column; flex-direction: column;
gap: .5rem;
.preview {
width: 15rem;
cursor: pointer;
} }
.imageselect > div { .preview-label {
place-self: center;
}
img {
width: 10rem; width: 10rem;
display: flex; background-color: #fff;
gap: 0.5rem;
} }
fieldset label { .option-border {
flex-grow: 1; border: @option_border solid var(--fg-dark);
border-radius: 3 * @option_border;
// iframe's behave nicely
&.preview {
padding: @option_border;
} }
.imageselect img { // label>img doesn't
width: 100%; & > img {
background-color: #fff; border: @option_border solid var(--bg);
border-radius: 2 * @option_border;
object-fit: contain;
}
} }
fieldset input { input[type = "radio"] {
display: none; display: none;
&:checked + .option-border {
border-color: var(--accent2);
}
} }
fieldset img, label {
fieldset iframe, flex-grow: 1;
.preview-small { // firefox hat hier lack gesoffen und erfindet 5px wenn das hier block oder
border: 3px solid lightgray; // inline ist
border-radius: 10px; display: flex;
}
} }
input[type="radio"]:checked { input[type = "radio"] {
& + label > img, display: none;
& + iframe {
border:3px solid red;
} }
} }
import './main.less'; import './main.less';
console.log("Hello World");
function onInputHandler(event: Event) { function onInputHandler(event: Event) {
const preview = document.getElementById('preview') as HTMLIFrameElement; const preview = document.getElementById('preview') as HTMLIFrameElement;
const previewDoc = preview.contentDocument as Document; const previewDoc = preview.contentDocument as Document;
...@@ -12,9 +10,30 @@ function onInputHandler(event: Event) { ...@@ -12,9 +10,30 @@ function onInputHandler(event: Event) {
window.addEventListener("load", () => { window.addEventListener("load", () => {
if (document.getElementById('preview')) { if (document.getElementById('preview')) {
for (let el of document.getElementsByClassName('input-dispatch')) { for (const el of document.getElementsByClassName('input-dispatch')) {
console.log(el); console.log(el);
el.addEventListener('input', onInputHandler); el.addEventListener('input', onInputHandler);
} }
for (const op of document.querySelectorAll('.option .preview')) {
console.log(op);
const input_id = (op as HTMLElement).dataset.for;
if (!input_id) {
console.error("Missing data-for attribute for", op);
continue;
}
const input = document.getElementById(input_id);
if (!input || input === null) {
console.error("Unable to find input for", op);
continue;
}
const handler = (_: Event) => {
console.log("clicked");
(input as HTMLInputElement).checked = true;
};
op.addEventListener('click', handler);
(op as HTMLIFrameElement).contentDocument?.addEventListener('click', handler);
}
} }
}); });
...@@ -28,7 +28,8 @@ ...@@ -28,7 +28,8 @@
{%- endblock title %} {%- endblock title %}
{% block main -%} {% block main -%}
<section> <div class="section-container">
<div class="section">
{%- with messages = get_flashed_messages() -%} {%- with messages = get_flashed_messages() -%}
{%- if messages -%} {%- if messages -%}
<ul class="flashes"> <ul class="flashes">
...@@ -38,19 +39,19 @@ ...@@ -38,19 +39,19 @@
</ul> </ul>
{%- endif -%} {%- endif -%}
{%- endwith -%} {%- endwith -%}
</section> </div>
<section> <div class="section">
<form method="post" action=""> <form method="post" action="">
{{ form.csrf_token }} {{ form.csrf_token }}
{{ render_field(form.title, "input-dispatch") }} {{ render_field(form.title, "input-dispatch") }}
{{ render_field(form.text, "input-dispatch") }} {{ render_field(form.text, "input-dispatch") }}
<fieldset class="templateselect"> <fieldset class="select templateselect">
<legend>Vorlage</legend> <legend>Vorlage</legend>
{%- for t in form.template.choices -%} {%- for t in form.template.choices -%}
<div> <div class="option">
<input <input
type="radio" type="radio"
name="template" name="template"
...@@ -61,9 +62,10 @@ ...@@ -61,9 +62,10 @@
{%- endif -%} {%- endif -%}
/> />
<iframe <iframe
class="preview preview-small" class="preview option-border"
src="{{ url_for('instance.sample_html', template=t.name) }}" src="{{ url_for('instance.sample_html', template=t.name) }}"
id="template-preview:{{ t.name }}" id="template-preview:{{ t.name }}"
data-for="template:{{ t.name }}"
> >
</iframe> </iframe>
<label for="template:{{ t.name }}" class="preview-label"> <label for="template:{{ t.name }}" class="preview-label">
...@@ -73,10 +75,10 @@ ...@@ -73,10 +75,10 @@
{% endfor %} {% endfor %}
</fieldset> </fieldset>
<fieldset class="imageselect"> <fieldset class="select imageselect">
<legend>Bild</legend> <legend>Bild</legend>
{%- for img in form.image.choices -%} {%- for img in form.image.choices -%}
<div> <div class="option">
<input <input
type="radio" type="radio"
name="image" name="image"
...@@ -86,14 +88,14 @@ ...@@ -86,14 +88,14 @@
checked checked
{%- endif -%} {%- endif -%}
/> />
<label for="img:{{ img }}"> <label for="img:{{ img }}" class="option-border">
<img src="{{ url_for('instance.static', filename='img/'+img) }}" title="{{ img }}" /> <img src="{{ url_for('instance.static', filename='img/'+img) }}" title="{{ img }}" />
</label> </label>
</div> </div>
{%- endfor -%} {%- endfor -%}
</fieldset> </fieldset>
<div class="box"> <div class="buttons">
{%- if schild -%} {%- if schild -%}
<input type="submit" value="Speichern" /> <input type="submit" value="Speichern" />
<input <input
...@@ -106,25 +108,25 @@ ...@@ -106,25 +108,25 @@
{%- endif -%} {%- endif -%}
</div> </div>
</form> </form>
</section>
{%- if schild %}
<div>
<a href="{{ url_for('instance.schild_pdf', ident=schild.ident) }}">
Als PDF anzeigen
</a>
</div> </div>
<section><form method="post" action="{{ url_for('.print', ident=schild.ident) }}"> {%- if schild %}
<div class="section">
<form method="post" action="{{ url_for('.print', ident=schild.ident) }}">
{%- for field in printform -%} {%- for field in printform -%}
{{ render_field(field) }} {{ render_field(field) }}
{%- endfor -%} {%- endfor -%}
<div class="buttons">
<a class="button" href="{{ url_for('instance.schild_pdf', ident=schild.ident) }}">
Als PDF anzeigen
</a>
<input type="submit" value="Drucken" /> <input type="submit" value="Drucken" />
</form></section> </div>
</form>
</div>
<div> <div class="section preview-section">
<h2>Vorschau</h2> <h2>Vorschau</h2>
<div class="preview-container" id="preview-container"> <div class="preview-container" id="preview-container">
<iframe <iframe
...@@ -135,4 +137,5 @@ ...@@ -135,4 +137,5 @@
</div> </div>
</div> </div>
{% endif %} {% endif %}
</div>
{% endblock main %} {% endblock main %}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment