/* =========================
File Upload & File Attachment
Figma: Attached File.
API kept compatible with gnexus-ui-kit.
========================= */
@use "../kit-deps" as *;
$file-attachment-size: 240px;
.file-upload-panel {
width: 100%;
max-width: 680px;
}
.file-upload-form {
display: flex;
flex-direction: column;
gap: $space-4;
}
.file-upload-header {
display: flex;
align-items: flex-start;
justify-content: space-between;
gap: $space-3;
}
.file-upload-heading {
display: flex;
flex-direction: column;
gap: $space-1;
}
.file-upload-title {
margin: 0;
color: $neutral-900;
font-family: $font-family-base;
font-size: 18px;
font-weight: $font-weight-bold;
line-height: 1.3;
}
.file-upload-description {
margin: 0;
color: $neutral-600;
font-family: $font-family-base;
font-size: 14px;
line-height: 1.4;
}
.file-upload-dropzone {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: $space-3;
width: 100%;
padding: $space-8 $space-6;
border: 2px dashed $border-color-muted;
border-radius: $radius-lg;
background: $surface-panel-muted;
color: $neutral-700;
text-align: center;
cursor: pointer;
transition: border-color $motion-base $motion-ease, background-color $motion-base $motion-ease;
&:hover,
&.is-hover {
border-color: $mint-600;
background: rgba($mint-300, 0.24);
}
input[type="file"] {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border: 0;
}
}
.file-upload-icon {
display: inline-flex;
align-items: center;
justify-content: center;
width: 48px;
height: 48px;
border-radius: $radius-full;
background: $neutral-0;
color: $mint-700;
font-size: 24px;
}
.file-upload-body {
display: flex;
flex-direction: column;
gap: $space-1;
}
.file-upload-primary {
color: $neutral-900;
font-family: $font-family-base;
font-size: 15px;
font-weight: $font-weight-semibold;
}
.file-upload-secondary {
color: $neutral-600;
font-family: $font-family-base;
font-size: 13px;
}
.file-upload-preview {
display: grid;
grid-template-columns: repeat(auto-fill, minmax($file-attachment-size, 1fr));
gap: $space-4;
}
.file-upload-preview-item,
.file-attachment {
position: relative;
display: flex;
flex-direction: column;
justify-content: space-between;
width: 100%;
max-width: $file-attachment-size;
aspect-ratio: 1 / 1;
padding: $space-4;
border: $border-width-base $border-style-base $border-color-muted;
border-radius: $radius-xl;
background: $neutral-0;
color: $neutral-900;
box-sizing: border-box;
overflow: hidden;
}
.file-upload-preview-remove,
.file-attachment-remove {
position: absolute;
top: $space-3;
right: $space-3;
display: inline-flex;
align-items: center;
justify-content: center;
width: 28px;
height: 28px;
padding: 0;
border: 0;
border-radius: $radius-full;
background: transparent;
color: $neutral-700;
font-size: $icon-size-md;
cursor: pointer;
transition: color $motion-base $motion-ease, background-color $motion-base $motion-ease;
&:hover,
&.is-hover {
color: $neutral-900;
background: $neutral-100;
}
&:focus-visible {
@include focus_ring;
}
}
.file-upload-preview-visual,
.file-attachment-visual {
position: absolute;
inset: 0;
display: flex;
align-items: center;
justify-content: center;
background: transparent;
img {
width: 100%;
height: 100%;
object-fit: cover;
}
}
.file-upload-preview-type,
.file-attachment-type {
display: inline-flex;
align-items: center;
justify-content: center;
width: 72px;
height: 72px;
border-radius: $radius-lg;
background: $neutral-100;
color: $neutral-600;
font-family: $font-family-base;
font-size: 14px;
font-weight: $font-weight-bold;
text-transform: uppercase;
}
.file-upload-preview-name,
.file-attachment-name {
position: relative;
z-index: 1;
display: block;
margin-top: auto;
color: $neutral-900;
font-family: $font-family-base;
font-size: 16px;
font-weight: $font-weight-semibold;
line-height: 1.3;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.file-upload-preview-meta,
.file-attachment-meta {
position: relative;
z-index: 1;
display: block;
margin-top: $space-1;
color: $neutral-600;
font-family: $font-family-base;
font-size: 12px;
line-height: 1.3;
}
.file-attachment-header {
position: relative;
z-index: 1;
display: flex;
align-items: flex-start;
justify-content: space-between;
gap: $space-2;
}
.file-attachment-format {
display: inline-flex;
align-items: center;
padding: $space-1 $space-2;
border-radius: $radius-sm;
background: $neutral-100;
color: $neutral-700;
font-family: $font-family-base;
font-size: 12px;
font-weight: $font-weight-semibold;
text-transform: uppercase;
}
// State variants
.file-attachment.is-placeholder,
.file-upload-preview-item.is-placeholder {
.file-attachment-visual,
.file-upload-preview-visual {
background: repeating-conic-gradient($neutral-200 0% 25%, $neutral-25 0% 50%) 50% / 50px 50px;
}
}
.file-attachment.is-error,
.file-upload-preview-item.is-error,
.file-attachment.is-retry,
.file-upload-preview-item.is-retry {
background: $neutral-100;
.file-attachment-visual,
.file-upload-preview-visual {
color: $danger-text;
font-size: 48px;
&::before {
content: "";
position: absolute;
width: 96px;
height: 96px;
border-radius: $radius-full;
background: $neutral-0;
z-index: -1;
}
}
}
.file-attachment.is-empty,
.file-upload-preview-item.is-empty {
.file-attachment-visual,
.file-upload-preview-visual {
display: none;
}
}
.file-upload-actions {
display: flex;
flex-wrap: wrap;
gap: $space-2;
}