mirror of
https://github.com/carbon-design-system/carbon-components-svelte.git
synced 2025-09-14 18:01:06 +00:00
* feat(theme): add g80 theme * docs(data-table): use link with icon variant * feat(search): support expandable variant * fix(file-uploaded): use semantic p element instead of strong * feat(side-nav): dispatch open, close, click:overlay events * refactor(ui-shell): remove usage of deprecated Icon component * feat(ui-shell): allow custom hamburger menu icons * feat(button): support xl size * fix(code-snippet): wrap code element with pre * refactor(button): use button specific tooltip class for icon-only variant * feat(password-input): support warning, inline props * feat(data-table): support medium size
124 lines
2.9 KiB
Svelte
124 lines
2.9 KiB
Svelte
<script>
|
|
/**
|
|
* @event {File[]} add
|
|
* @event {File[]} remove
|
|
*/
|
|
|
|
/**
|
|
* Specify the file uploader status
|
|
* @type {"uploading" | "edit" | "complete"}
|
|
*/
|
|
export let status = "uploading";
|
|
|
|
/**
|
|
* Specify the accepted file types
|
|
* @type {string[]}
|
|
*/
|
|
export let accept = [];
|
|
|
|
/**
|
|
* Obtain the uploaded file names
|
|
* @type {File[]}
|
|
*/
|
|
export let files = [];
|
|
|
|
/** Set to `true` to allow multiple files */
|
|
export let multiple = false;
|
|
|
|
/**
|
|
* Override the default behavior of clearing the array of uploaded files
|
|
* @type {() => void}
|
|
*/
|
|
export const clearFiles = () => {
|
|
files = [];
|
|
};
|
|
|
|
/** Specify the label description */
|
|
export let labelDescription = "";
|
|
|
|
/** Specify the label title */
|
|
export let labelTitle = "";
|
|
|
|
/**
|
|
* Specify the kind of file uploader button
|
|
* @type {"primary" | "secondary" | "tertiary" | "ghost" | "danger"}
|
|
*/
|
|
export let kind = "primary";
|
|
|
|
/** Specify the button label */
|
|
export let buttonLabel = "";
|
|
|
|
/** Specify the ARIA label used for the status icons */
|
|
export let iconDescription = "Provide icon description";
|
|
|
|
/** Specify a name attribute for the file button uploader input */
|
|
export let name = "";
|
|
|
|
import { createEventDispatcher, afterUpdate } from "svelte";
|
|
import Filename from "./Filename.svelte";
|
|
import FileUploaderButton from "./FileUploaderButton.svelte";
|
|
|
|
const dispatch = createEventDispatcher();
|
|
|
|
$: prevFiles = [];
|
|
|
|
afterUpdate(() => {
|
|
if (files.length > prevFiles.length) {
|
|
dispatch("add", files);
|
|
} else {
|
|
dispatch(
|
|
"remove",
|
|
prevFiles.filter((_) => !files.includes(_))
|
|
);
|
|
}
|
|
|
|
prevFiles = [...files];
|
|
});
|
|
</script>
|
|
|
|
<div
|
|
class:bx--form-item="{true}"
|
|
{...$$restProps}
|
|
on:click
|
|
on:mouseover
|
|
on:mouseenter
|
|
on:mouseleave
|
|
>
|
|
<p class:bx--file--label="{true}">{labelTitle}</p>
|
|
<p class:bx--label-description="{true}">{labelDescription}</p>
|
|
<FileUploaderButton
|
|
disableLabelChanges
|
|
labelText="{buttonLabel}"
|
|
accept="{accept}"
|
|
name="{name}"
|
|
multiple="{multiple}"
|
|
kind="{kind}"
|
|
on:change
|
|
on:change="{({ target }) => {
|
|
files = [...target.files];
|
|
}}"
|
|
/>
|
|
<div class:bx--file-container="{true}">
|
|
{#each files as { name }, i (name)}
|
|
<span class:bx--file__selected-file="{true}">
|
|
<p class:bx--file-filename="{true}">{name}</p>
|
|
<span class:bx--file__state-container="{true}">
|
|
<Filename
|
|
iconDescription="{iconDescription}"
|
|
status="{status}"
|
|
on:keydown
|
|
on:keydown="{({ key }) => {
|
|
if (key === ' ' || key === 'Enter') {
|
|
files = files.filter((_, index) => index !== i);
|
|
}
|
|
}}"
|
|
on:click
|
|
on:click="{() => {
|
|
files = files.filter((_, index) => index !== i);
|
|
}}"
|
|
/>
|
|
</span>
|
|
</span>
|
|
{/each}
|
|
</div>
|
|
</div>
|