Skip to content

Commit

Permalink
Improves pre compiler draft
Browse files Browse the repository at this point in the history
  • Loading branch information
tomasznetcentric committed Aug 16, 2023
1 parent 92ab83e commit 98d50be
Show file tree
Hide file tree
Showing 23 changed files with 1,372 additions and 498 deletions.
2 changes: 1 addition & 1 deletion blocks/columns/columns.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

28 changes: 14 additions & 14 deletions blocks/columns/columns.scss
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
@import '../../styles/common-dependencies';

.columns > div {
flex-direction: column;
display: flex;
flex-direction: column;

@include breakpoint($bp-desktop) {
align-items: center;
flex-direction: unset;
gap: 32px;
}
}

.columns img {
Expand All @@ -9,6 +17,11 @@

.columns > div > div {
order: 1;

@include breakpoint($bp-desktop) {
flex: 1;
order: unset;
}
}

.columns > div > .columns-img-col {
Expand All @@ -18,16 +31,3 @@
.columns > div > .columns-img-col img {
display: block;
}

@media (min-width: 900px) {
.columns > div {
align-items: center;
flex-direction: unset;
gap: 32px;
}

.columns > div > div {
flex: 1;
order: unset;
}
}
1 change: 1 addition & 0 deletions blocks/form/form.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

189 changes: 189 additions & 0 deletions blocks/form/form.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
function createSelect(fd) {
const select = document.createElement('select');
select.id = fd.Field;
if (fd.Placeholder) {
const ph = document.createElement('option');
ph.textContent = fd.Placeholder;
ph.setAttribute('selected', '');
ph.setAttribute('disabled', '');
select.append(ph);
}
fd.Options.split(',').forEach((o) => {
const option = document.createElement('option');
option.textContent = o.trim();
option.value = o.trim();
select.append(option);
});
if (fd.Mandatory === 'x') {
select.setAttribute('required', 'required');
}
return select;
}
function constructPayload(form) {
const payload = {};
[...form.elements].forEach((fe) => {
if (fe.type === 'checkbox') {
if (fe.checked)
payload[fe.id] = fe.value;
}
else if (fe.id) {
payload[fe.id] = fe.value;
}
});
return payload;
}
async function submitForm(form) {
const payload = constructPayload(form);
payload.timestamp = new Date().toJSON();
const resp = await fetch(form.dataset.action, {
method: 'POST',
cache: 'no-cache',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ data: payload }),
});
await resp.text();
return payload;
}
function createButton(fd) {
const button = document.createElement('button');
button.textContent = fd.Label;
button.classList.add('button');
if (fd.Type === 'submit') {
button.addEventListener('click', async (event) => {
const form = button.closest('form');
if (fd.Placeholder)
form.dataset.action = fd.Placeholder;
if (form.checkValidity()) {
event.preventDefault();
button.setAttribute('disabled', '');
await submitForm(form);
const redirectTo = fd.Extra;
window.location.href = redirectTo;
}
});
}
return button;
}
function createHeading(fd, el) {
const heading = document.createElement(el);
heading.textContent = fd.Label;
return heading;
}
function createInput(fd) {
const input = document.createElement('input');
input.type = fd.Type;
input.id = fd.Field;
input.setAttribute('placeholder', fd.Placeholder);
if (fd.Mandatory === 'x') {
input.setAttribute('required', 'required');
}
return input;
}
function createTextArea(fd) {
const input = document.createElement('textarea');
input.id = fd.Field;
input.setAttribute('placeholder', fd.Placeholder);
if (fd.Mandatory === 'x') {
input.setAttribute('required', 'required');
}
return input;
}
function createLabel(fd) {
const label = document.createElement('label');
label.setAttribute('for', fd.Field);
label.textContent = fd.Label;
if (fd.Mandatory === 'x') {
label.classList.add('required');
}
return label;
}
function applyRules(form, rules) {
const payload = constructPayload(form);
rules.forEach((field) => {
const { type, condition: { key, operator, value } } = field.rule;
if (type === 'visible') {
if (operator === 'eq') {
if (payload[key] === value) {
form.querySelector(`.${field.fieldId}`).classList.remove('hidden');
}
else {
form.querySelector(`.${field.fieldId}`).classList.add('hidden');
}
}
}
});
}
function fill(form) {
const { action } = form.dataset;
if (action === '/tools/bot/register-form') {
const loc = new URL(window.location.href);
form.querySelector('#owner').value = loc.searchParams.get('owner') || '';
form.querySelector('#installationId').value = loc.searchParams.get('id') || '';
}
}
async function createForm(formURL) {
console.log('formURL', formURL); // todo: remove before merge!
const { pathname } = new URL(formURL);
const resp = await fetch(pathname);
const json = await resp.json();
const form = document.createElement('form');
const rules = [];
// eslint-disable-next-line prefer-destructuring
form.dataset.action = pathname.split('.json')[0];
json.data.forEach((fd) => {
fd.Type = fd.Type || 'text';
const fieldWrapper = document.createElement('div');
const style = fd.Style ? ` form-${fd.Style}` : '';
const fieldId = `form-${fd.Type}-wrapper${style}`;
fieldWrapper.className = fieldId;
fieldWrapper.classList.add('field-wrapper');
switch (fd.Type) {
case 'select':
fieldWrapper.append(createLabel(fd));
fieldWrapper.append(createSelect(fd));
break;
case 'heading':
fieldWrapper.append(createHeading(fd, 'h3'));
break;
case 'legal':
fieldWrapper.append(createHeading(fd, 'p'));
break;
case 'checkbox':
fieldWrapper.append(createInput(fd));
fieldWrapper.append(createLabel(fd));
break;
case 'text-area':
fieldWrapper.append(createLabel(fd));
fieldWrapper.append(createTextArea(fd));
break;
case 'submit':
fieldWrapper.append(createButton(fd));
break;
default:
fieldWrapper.append(createLabel(fd));
fieldWrapper.append(createInput(fd));
}
if (fd.Rules) {
try {
rules.push({ fieldId, rule: JSON.parse(fd.Rules) });
}
catch (e) {
// eslint-disable-next-line no-console
console.warn(`Invalid Rule ${fd.Rules}: ${e}`);
}
}
form.append(fieldWrapper);
});
form.addEventListener('change', () => applyRules(form, rules));
applyRules(form, rules);
fill(form);
return (form);
}
export default async function decorate(block) {
const form = block.querySelector('a[href$=".json"]');
if (form) {
form.replaceWith(await createForm(form.href));
}
}
122 changes: 122 additions & 0 deletions blocks/form/form.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
main .form {
background-color: var(--color-white);
padding: var(--spacing-s);
border-radius: var(--card-border-radius-l);
filter: var(--image-filter-drop-shadow-small);
border: solid 1px var(--bg-color-grey);
}

main .form h2 {
padding: var(--spacing-s) 0;
font-size: var(--type-heading-l-lh);
}

main .form h3 {
padding-top: var(--spacing-s);
font-size: var(--type-heading-m-size);
}

main .form input,
main .form textarea,
main .form select {
border: solid 1px var(--bg-color-grey);
padding: var(--spacing-xxs) var(--spacing-xs);
width: 100%;
max-width: 50rem;
box-sizing: border-box;
border-radius: var(--input-border-radius);
font-size: var(--type-body-s-size);
line-height: var(--type-body-s-lh);
font-family: var(--body-font-family);
}

main .form textarea {
min-height: 100px;
}

main .form input:hover,
main .form select:hover {
border-color: var(--color-font-grey);
}

main .form label {
display: block;
padding-bottom: var(--spacing-xxs);
box-sizing: border-box;
font-size: var(--type-body-s-size);
line-height: var(--type-body-s-lh);
}

main .form label.required::after {
content: "*";
color: var(--color-black);
padding-left: var(--spacing-xxxs);
}

main .form .field-wrapper {
margin-bottom: var(--spacing-m);
}

main .form .form-checkbox-wrapper {
display: flex;
align-items: center;
margin: var(--spacing-xs) 0;
}

main .form .form-checkbox-wrapper input[type='checkbox'] {
appearance: none;
height: 20px;
width: 20px;
position: relative;
border: unset;
padding: unset;
margin-right: var(--spacing-xxs);
margin-left: 0;
}

main .form .form-checkbox-wrapper input[type='checkbox']::after {
display: block;
position: absolute;
top: 0;
left: 0;
height: 20px;
width: 20px;
content: ' ';
background-size: contain;
}

main .form .form-checkbox-wrapper input[type='checkbox']:checked::after {
background-size: contain;
content: ' ';
}

main .form .form-checkbox-wrapper label {
display: block;
font-size: var(--type-body-xxs-size);
line-height: var(--type-body-xxs-lh);
padding-bottom: 0;
}

main .form-legal-wrapper p {
font-size: var(--type-body-xxs-size);
line-height: var(--type-body-xxs-lh);
font-style: italic;
}

main .form button {
font-family: var(--body-font-family);
}

@media screen and (min-width: 900px) {
main .form {
padding: var(--spacing-ml);
}

main .form .field-wrapper {
display: flex;
}

main .form label {
width: 72%;
}
}
Loading

0 comments on commit 98d50be

Please sign in to comment.