@use 'sprucecss/scss/spruce' as *;
.file-group-container {
container: file-group-container / inline-size;
}
.file-group {
$this: &;
@include generate-variables($form-control, $include: ('border-width', 'border-radius'));
align-items: center;
border: config('border-width', $form-control) solid color('border', 'form');
border-radius: config('border-radius', $form-control);
display: flex;
gap: spacer('m');
overflow: hidden;
padding: spacer('s');
@container file-group-container (inline-size < 30rem) {
flex-direction: column;
}
&:has([style*='background-image']) {
#{$this}__remove {
display: inline-flex;
}
#{$this}__input {
display: none;
}
}
&__preview {
align-items: center;
aspect-ratio: 1;
background-color: color('primary-50');
background-position: center;
background-size: cover;
border-radius: config('border-radius', $form-control);
display: flex;
flex-shrink: 0;
flex-wrap: wrap;
inline-size: 9rem;
justify-content: center;
@container file-group-container (inline-size < 30rem) {
aspect-ratio: 16 / 9;
inline-size: 100%;
}
&[style*='background-image'] #{$this}__icon {
display: none;
}
}
&__body {
display: flex;
flex-direction: column;
gap: spacer('xxs');
inline-size: 100%;
> * {
margin-block: 0;
}
}
&__icon {
--size: 2rem;
block-size: var(--size);
color: color('primary');
inline-size: var(--size);
}
&__title {
color: color('heading');
font-weight: 700;
}
&__meta {
list-style: none;
padding-inline-start: 0;
> * + * {
margin-block-start: 0;
}
}
&__action {
display: flex;
flex-wrap: wrap;
gap: spacer('xs');
margin-block-start: spacer('xs');
}
&__remove {
display: none;
}
&__input {
flex: 1;
}
}
<div class="form-group">
<label class="form-label" for="product-image">Product Image</label>
<div class="file-group-container">
<div class="file-group">
<div class="file-group__preview">
<svg class="file-group__icon" aria-hidden="true" focusable="false" fill="none" height="24" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" stroke="currentColor" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
<rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect>
<circle cx="8.5" cy="8.5" r="1.5"></circle>
<polyline points="21 15 16 10 5 21"></polyline>
</svg>
</div>
<div class="file-group__body">
<p class="file-group__title">Upload a product image</p>
<ul class="file-group__meta">
<li>Accepted formats: JPG, PNG</li>
<li>Maximum upload limit: 5 MB</li>
</ul>
<div class="file-group__action">
<button class="btn btn--delete btn--icon file-group__remove" aria-label="Remove file">
<svg class="btn__icon" aria-hidden="true" fill="none" focusable="false" height="24" stroke-linecap="round" stroke-linejoin="round" stroke-width="3.5" stroke="currentColor" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
<line x1="18" y1="6" x2="6" y2="18"></line>
<line x1="6" y1="6" x2="18" y2="18"></line>
</svg>
</button>
<input class="form-file file-group__input" id="product-image" type="file" accept="image/png, image/jpeg"/>
</div>
</div>
</div>
</div>
</div>
<div class="form-group">
<label class="form-label" for="product-image-has-image">Product Image (has image)</label>
<div class="file-group-container">
<div class="file-group">
<div class="file-group__preview" style="background-image: url('/img/post/gallery/kyle-johnson-Aq7id0ZjEW4-unsplash.jpg')">
<svg class="file-group__icon" aria-hidden="true" focusable="false" fill="none" height="24" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" stroke="currentColor" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
<rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect>
<circle cx="8.5" cy="8.5" r="1.5"></circle>
<polyline points="21 15 16 10 5 21"></polyline>
</svg>
</div>
<div class="file-group__body">
<p class="file-group__title">Upload a product image</p>
<ul class="file-group__meta">
<li>Accepted formats: JPG, PNG</li>
<li>Maximum upload limit: 5 MB</li>
</ul>
<div class="file-group__action">
<button class="btn btn--delete file-group__remove" aria-label="Remove file">
<svg class="btn__icon" aria-hidden="true" fill="none" focusable="false" height="24" stroke-linecap="round" stroke-linejoin="round" stroke-width="3.5" stroke="currentColor" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
<line x1="18" y1="6" x2="6" y2="18"></line>
<line x1="6" y1="6" x2="18" y2="18"></line>
</svg>
Remove selected image
</button>
<input class="form-file file-group__input" id="product-image-has-image" type="file" accept="image/png, image/jpeg"/>
</div>
</div>
</div>
</div>
</div>