Skip to content

Commit

Permalink
un-repeatable event materials basic structures built
Browse files Browse the repository at this point in the history
  • Loading branch information
qiyundai committed May 8, 2024
1 parent c82c614 commit 7167ebb
Show file tree
Hide file tree
Showing 7 changed files with 209 additions and 8 deletions.
96 changes: 96 additions & 0 deletions blocks/event-materials-component/event-materials-component.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
.event-materials-component > div {
margin-bottom: 32px;
}

.event-materials-component .image-dropzones {
display: grid;
gap: 16px;
margin-bottom: 24px;
}

.event-materials-component sp-textfield {
width: 100%;
}

.event-materials-component .material-file-input-wrapper {
border: 2px dashed var(--color-gray-400);
border-radius: 8px;
height: 124px;
width: 124px;
display: flex;
flex-direction: column;
justify-content: center;
text-align: center;
align-items: center;
}

.event-materials-component .material-file-input-wrapper .preview-wrapper {
width: 100%;
height: 100%;
position: relative;
z-index: 1;
}

.event-materials-component .material-file-input-wrapper .preview-wrapper .icon-delete {
position: absolute;
top: 8px;
right: 8px;
cursor: pointer;
}

.event-materials-component .material-file-input-wrapper .preview-material-placeholder {
height: 100%;
overflow: hidden;
border-radius: 8px;

}

.event-materials-component .material-file-input-wrapper .preview-material-placeholder img {
height: 100%;
width: 100%;
object-fit: cover;
}

.event-materials-component .material-file-input-wrapper label {
border-radius: 8px;
display: flex;
flex-direction: column;
box-sizing: border-box;
align-items: center;
padding: 16px;
height: 100%;
width: 100%;
line-height: var(--type-body-xxs-lh);
}

.event-materials-component .material-file-input-wrapper label:hover {
background-color: var(--color-gray-100);
}

.event-materials-component .material-file-input-wrapper label input.material-file-input {
display: none;
}

.event-materials-component .material-file-input-wrapper label .icon {
width: 40px;
opacity: 0.5;
}

.event-materials-component .material-file-input-wrapper label p {
margin: 0;
font-size: var(--type-body-xs-size);;
}

.event-materials-component .material-file-input-wrapper .hidden {
display: none;
}

.event-materials-component .attr-text {
text-align: right;
}

@media (min-width: 900px) {
.event-materials-component .file-dropzones {
grid-template-columns: 1fr 1fr 1fr;
}
}
88 changes: 88 additions & 0 deletions blocks/event-materials-component/event-materials-component.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import { getLibs } from '../../scripts/utils.js';
import { getIcon, generateToolTip } from '../../utils/utils.js';

const { createTag } = await import(`${getLibs()}/utils/utils.js`);

async function decorateSWCTextField(row, id, extraOptions) {
const miloLibs = getLibs();
await Promise.all([
import(`${miloLibs}/deps/lit-all.min.js`),
import(`${miloLibs}/features/spectrum-web-components/dist/textfield.js`),
]);

row.classList.add('text-field-row');

const existingFileInput = document.querySelectorAll('.material-file-input');
const cols = row.querySelectorAll(':scope > div');
if (!cols.length) return;
const [placeholderCol, maxLengthCol] = cols;
const text = placeholderCol.textContent.trim();

let maxCharNum, attrTextEl;
if (maxLengthCol) {
attrTextEl = createTag('div', { class: 'attr-text' }, maxLengthCol.textContent.trim());
maxCharNum = maxLengthCol.querySelector('strong')?.textContent.trim();
}

const isRequired = attrTextEl?.textContent.trim().endsWith('*');

const input = createTag('sp-textfield', {
id, class: 'text-input', placeholder: text, ...extraOptions
});

if (isRequired) input.required = true;

if (maxCharNum) input.setAttribute('maxlength', maxCharNum);

const wrapper = createTag('div', { class: 'info-field-wrapper' });
row.innerHTML = '';
wrapper.append(input);
if (attrTextEl) wrapper.append(attrTextEl);
row.append(wrapper);
}

function decorateFileDropzone(row) {
row.classList.add('file-dropzones');
const cols = row.querySelectorAll(':scope > div');
const dropzones = [];

cols.forEach((c, i) => {
c.classList.add('file-dropzone');
const text = c.textContent.trim();
const existingFileInputs = document.querySelectorAll('.material-file-input');
const inputId = `material-file-input-${existingFileInputs.length + i + 1}`;
const fileInput = createTag('input', { id: inputId, type: 'file', class: 'material-file-input' });
const inputWrapper = createTag('div', { class: 'material-file-input-wrapper' });
const inputLabel = createTag('label', { class: 'material-file-input-label' });

const previewWrapper = createTag('div', { class: 'preview-wrapper hidden' });
const previewImg = createTag('div', { class: 'preview-img-placeholder' });
const previewDeleteButton = getIcon('delete');

previewWrapper.append(previewImg, previewDeleteButton);

inputWrapper.append(previewWrapper, inputLabel);
inputLabel.append(fileInput, getIcon('upload-cloud'), text);
dropzones.push(inputWrapper);
})

row.innerHTML = '';
dropzones.forEach((dz) => {
row.append(dz);
});
}

export default function init(el) {
const existingFileInputs = document.querySelectorAll('.event-materials-component');
const blockIndex = Array.from(existingFileInputs).findIndex((b) => b === el);

el.classList.add('form-component');
generateToolTip(el);

const rows = el.querySelectorAll(':scope > div');
rows.forEach(async (r, i) => {
if (i === 0) decorateFileDropzone(r);
if (i === 1) await decorateSWCTextField(r, `event-material-url-${blockIndex}`);
if (i === 2) await decorateSWCTextField(r, `event-material-name-${blockIndex}`, { quiet: true, size: 'xl' });
});
}
4 changes: 4 additions & 0 deletions blocks/form-handler/form-handler.css
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,10 @@
box-shadow: 0 3px 6px 0 rgb(0 0 0 / 16%);
}

.form-handler .main-frame .section .content {
max-width: none;
}

.form-handler .fragment.hidden {
display: none;
}
Expand Down
4 changes: 2 additions & 2 deletions blocks/img-upload-component/img-upload-component.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ function decorateImageDropzones(row) {
const uploadName = c.querySelector(':scope > p:first-of-type')?.textContent.trim();
const paragraphs = c.querySelectorAll(':scope > p');
const existingFileInput = document.querySelectorAll('.img-file-input');
const inputId = uploadName ? `${handlize(uploadName)}` : `img-file-input-${existingFileInput.length + i}`;
const fileInput = createTag('input', { id: inputId, type: 'file', class: 'img-file-input' });
const inputId = uploadName ? `${handlize(uploadName)}` : `img-file-input-${existingFileInput.length + i + 1}`;
const fileInput = createTag('input', { id: inputId, type: 'file', class: 'img-file-input', accept: 'image/png, image/jpeg' });
const inputWrapper = createTag('div', { class: 'img-file-input-wrapper' });
const inputLabel = createTag('label', { class: 'img-file-input-label' });

Expand Down
10 changes: 10 additions & 0 deletions icons/cross.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions icons/upload-cloud.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 3 additions & 6 deletions utils/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,10 @@ export function addTooltipToHeading(em, heading) {

export function generateToolTip(formComponent) {
const heading = formComponent.querySelector(':scope > div:first-of-type h2, :scope > div:first-of-type h3');
const em = formComponent.querySelector('p > em');

if (heading) {
const em = formComponent.querySelector('p > em');

if (em) {
addTooltipToHeading(em, heading);
}
if (heading && em) {
addTooltipToHeading(em, heading);
}
}

Expand Down

0 comments on commit 7167ebb

Please sign in to comment.