mirror of
https://github.com/carbon-design-system/carbon-components-svelte.git
synced 2025-09-15 02:11:05 +00:00
Merge pull request #76 from IBM/refactor
refactor: use onMount, afterUpdate methods to manage state
This commit is contained in:
commit
25cd26af24
14 changed files with 97 additions and 88 deletions
|
@ -11,6 +11,7 @@
|
||||||
export let light = false;
|
export let light = false;
|
||||||
export let style = undefined;
|
export let style = undefined;
|
||||||
|
|
||||||
|
import { afterUpdate } from 'svelte';
|
||||||
import ChevronDown16 from 'carbon-icons-svelte/lib/ChevronDown16';
|
import ChevronDown16 from 'carbon-icons-svelte/lib/ChevronDown16';
|
||||||
import { cx } from '../../lib';
|
import { cx } from '../../lib';
|
||||||
import Button from '../Button';
|
import Button from '../Button';
|
||||||
|
@ -22,10 +23,11 @@
|
||||||
let expanded = false;
|
let expanded = false;
|
||||||
let showMoreLess = false;
|
let showMoreLess = false;
|
||||||
|
|
||||||
$: expandText = expanded ? showLessText : showMoreText;
|
afterUpdate(() => {
|
||||||
$: if (codeRef) {
|
|
||||||
showMoreLess = type === 'multi' && codeRef.getBoundingClientRect().height > 255;
|
showMoreLess = type === 'multi' && codeRef.getBoundingClientRect().height > 255;
|
||||||
}
|
});
|
||||||
|
|
||||||
|
$: expandText = expanded ? showLessText : showMoreText;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if type === 'inline'}
|
{#if type === 'inline'}
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
export let size = undefined;
|
export let size = undefined;
|
||||||
export let style = undefined;
|
export let style = undefined;
|
||||||
|
|
||||||
import { createEventDispatcher, setContext, onDestroy } from 'svelte';
|
import { createEventDispatcher, tick, setContext, onMount, afterUpdate } from 'svelte';
|
||||||
import { writable } from 'svelte/store';
|
import { writable } from 'svelte/store';
|
||||||
import { cx } from '../../lib';
|
import { cx } from '../../lib';
|
||||||
|
|
||||||
|
@ -30,10 +30,6 @@
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
onDestroy(() => {
|
|
||||||
document.body.classList.remove(cx('--body--with-modal-open'));
|
|
||||||
});
|
|
||||||
|
|
||||||
function focus(element) {
|
function focus(element) {
|
||||||
if (element.querySelector(selectorPrimaryFocus)) {
|
if (element.querySelector(selectorPrimaryFocus)) {
|
||||||
return focusElement.focus();
|
return focusElement.focus();
|
||||||
|
@ -44,10 +40,18 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$: didOpen = open;
|
onMount(async () => {
|
||||||
$: {
|
await tick();
|
||||||
if (innerModal) {
|
|
||||||
focus(innerModal);
|
focus(innerModal);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
document.body.classList.remove(cx('--body--with-modal-open'));
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
afterUpdate(() => {
|
||||||
|
if (!didOpen) {
|
||||||
|
focus(outerModal);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (open) {
|
if (open) {
|
||||||
|
@ -56,7 +60,9 @@
|
||||||
dispatch('close');
|
dispatch('close');
|
||||||
document.body.classList.remove(cx('--body--with-modal-open'));
|
document.body.classList.remove(cx('--body--with-modal-open'));
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
|
$: didOpen = open;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
|
@ -76,7 +82,6 @@
|
||||||
on:transitionend
|
on:transitionend
|
||||||
on:transitionend={() => {
|
on:transitionend={() => {
|
||||||
if (didOpen) {
|
if (didOpen) {
|
||||||
focus(outerModal);
|
|
||||||
didOpen = false;
|
didOpen = false;
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
|
|
|
@ -6,8 +6,8 @@
|
||||||
export let disabled = false;
|
export let disabled = false;
|
||||||
export let style = undefined;
|
export let style = undefined;
|
||||||
|
|
||||||
|
import { afterUpdate, getContext } from 'svelte';
|
||||||
import { cx } from '../../lib';
|
import { cx } from '../../lib';
|
||||||
import { getContext } from 'svelte';
|
|
||||||
|
|
||||||
const id = Math.random();
|
const id = Math.random();
|
||||||
const { currentId, add, update, change } = getContext('ContentSwitcher');
|
const { currentId, add, update, change } = getContext('ContentSwitcher');
|
||||||
|
@ -16,10 +16,13 @@
|
||||||
|
|
||||||
add({ id, text, selected });
|
add({ id, text, selected });
|
||||||
|
|
||||||
$: selected = $currentId === id;
|
afterUpdate(() => {
|
||||||
$: if (selected && buttonRef) {
|
if (selected) {
|
||||||
buttonRef.focus();
|
buttonRef.focus();
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$: selected = $currentId === id;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
|
@ -36,10 +39,10 @@
|
||||||
on:mouseenter
|
on:mouseenter
|
||||||
on:mouseleave
|
on:mouseleave
|
||||||
on:keydown
|
on:keydown
|
||||||
on:keydown={event => {
|
on:keydown={({ key }) => {
|
||||||
if (event.key === 'ArrowRight') {
|
if (key === 'ArrowRight') {
|
||||||
change(1);
|
change(1);
|
||||||
} else if (event.key === 'ArrowLeft') {
|
} else if (key === 'ArrowLeft') {
|
||||||
change(-1);
|
change(-1);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
|
|
|
@ -11,10 +11,8 @@
|
||||||
let timeoutId = undefined;
|
let timeoutId = undefined;
|
||||||
|
|
||||||
onDestroy(() => {
|
onDestroy(() => {
|
||||||
if (timeoutId !== undefined) {
|
|
||||||
window.clearTimeout(timeoutId);
|
window.clearTimeout(timeoutId);
|
||||||
timeoutId = undefined;
|
timeoutId = undefined;
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
$: showFeedback = timeoutId !== undefined;
|
$: showFeedback = timeoutId !== undefined;
|
||||||
|
|
|
@ -6,18 +6,24 @@
|
||||||
export let feedbackTimeout = 2000;
|
export let feedbackTimeout = 2000;
|
||||||
export let style = undefined;
|
export let style = undefined;
|
||||||
|
|
||||||
import { onDestroy } from 'svelte';
|
import { afterUpdate, onDestroy } from 'svelte';
|
||||||
import Copy16 from 'carbon-icons-svelte/lib/Copy16';
|
import Copy16 from 'carbon-icons-svelte/lib/Copy16';
|
||||||
import { cx } from '../../lib';
|
import { cx } from '../../lib';
|
||||||
|
|
||||||
let animation = undefined;
|
let animation = undefined;
|
||||||
let timeoutId = undefined;
|
let timeoutId = undefined;
|
||||||
|
|
||||||
|
afterUpdate(() => {
|
||||||
|
if (animation === 'fade-in') {
|
||||||
|
timeoutId = window.setTimeout(() => {
|
||||||
|
animation = 'fade-out';
|
||||||
|
}, feedbackTimeout);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
onDestroy(() => {
|
onDestroy(() => {
|
||||||
if (timeoutId !== undefined) {
|
|
||||||
window.clearTimeout(timeoutId);
|
window.clearTimeout(timeoutId);
|
||||||
timeoutId = undefined;
|
timeoutId = undefined;
|
||||||
}
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -30,9 +36,6 @@
|
||||||
on:click
|
on:click
|
||||||
on:click={() => {
|
on:click={() => {
|
||||||
animation = 'fade-in';
|
animation = 'fade-in';
|
||||||
timeoutId = window.setTimeout(() => {
|
|
||||||
animation = 'fade-out';
|
|
||||||
}, feedbackTimeout);
|
|
||||||
}}
|
}}
|
||||||
on:mouseover
|
on:mouseover
|
||||||
on:mouseenter
|
on:mouseenter
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
import FileUploaderDropContainer from './FileUploaderDropContainer.svelte';
|
import FileUploaderDropContainer from './FileUploaderDropContainer.svelte';
|
||||||
import FileUploaderSkeleton from './FileUploader.Skeleton.svelte';
|
import FileUploaderSkeleton from './FileUploader.Skeleton.svelte';
|
||||||
|
|
||||||
|
let fileUploader = undefined;
|
||||||
let files = [];
|
let files = [];
|
||||||
|
|
||||||
$: disabled = files.length === 0;
|
$: disabled = files.length === 0;
|
||||||
|
@ -37,6 +38,7 @@
|
||||||
{:else if story === 'uploader'}
|
{:else if story === 'uploader'}
|
||||||
<div class={cx('--file__container')}>
|
<div class={cx('--file__container')}>
|
||||||
<FileUploader
|
<FileUploader
|
||||||
|
bind:this={fileUploader}
|
||||||
{...$$props}
|
{...$$props}
|
||||||
bind:files
|
bind:files
|
||||||
on:add={({ detail }) => {
|
on:add={({ detail }) => {
|
||||||
|
@ -50,9 +52,7 @@
|
||||||
size="small"
|
size="small"
|
||||||
style="margin-top: 1rem"
|
style="margin-top: 1rem"
|
||||||
{disabled}
|
{disabled}
|
||||||
on:click={() => {
|
on:click={fileUploader.clearFiles}>
|
||||||
files = [];
|
|
||||||
}}>
|
|
||||||
Clear File{files.length === 1 ? '' : 's'}
|
Clear File{files.length === 1 ? '' : 's'}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
let className = undefined;
|
let className = undefined;
|
||||||
export { className as class };
|
export { className as class };
|
||||||
export let files = [];
|
export let files = [];
|
||||||
|
export const clearFiles = () => (files = []);
|
||||||
export let name = '';
|
export let name = '';
|
||||||
export let labelDescription = '';
|
export let labelDescription = '';
|
||||||
export let labelTitle = '';
|
export let labelTitle = '';
|
||||||
|
@ -13,7 +14,7 @@
|
||||||
export let accept = [];
|
export let accept = [];
|
||||||
export let style = undefined;
|
export let style = undefined;
|
||||||
|
|
||||||
import { createEventDispatcher } from 'svelte';
|
import { createEventDispatcher, afterUpdate } from 'svelte';
|
||||||
import { cx } from '../../lib';
|
import { cx } from '../../lib';
|
||||||
import Filename from './Filename.svelte';
|
import Filename from './Filename.svelte';
|
||||||
import FileUploaderButton from './FileUploaderButton.svelte';
|
import FileUploaderButton from './FileUploaderButton.svelte';
|
||||||
|
@ -22,7 +23,7 @@
|
||||||
|
|
||||||
let prevFiles = [];
|
let prevFiles = [];
|
||||||
|
|
||||||
$: {
|
afterUpdate(() => {
|
||||||
if (files.length > prevFiles.length) {
|
if (files.length > prevFiles.length) {
|
||||||
dispatch('add', files);
|
dispatch('add', files);
|
||||||
} else {
|
} else {
|
||||||
|
@ -33,7 +34,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
prevFiles = [...files];
|
prevFiles = [...files];
|
||||||
}
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div on:click on:mouseover on:mouseenter on:mouseleave class={cx('--form-item', className)} {style}>
|
<div on:click on:mouseover on:mouseenter on:mouseleave class={cx('--form-item', className)} {style}>
|
||||||
|
|
|
@ -21,9 +21,6 @@
|
||||||
|
|
||||||
let over = false;
|
let over = false;
|
||||||
let inputRef = undefined;
|
let inputRef = undefined;
|
||||||
|
|
||||||
$: _class = cx('--file__drop-container', over && '--file__drop-container--drag-over', className);
|
|
||||||
$: _labelClass = cx('--file-browse-btn', disabled && '--file-browse-btn--disabled');
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
|
@ -51,7 +48,7 @@
|
||||||
}}
|
}}
|
||||||
{style}>
|
{style}>
|
||||||
<label
|
<label
|
||||||
class={_labelClass}
|
class={cx('--file-browse-btn', disabled && '--file-browse-btn--disabled')}
|
||||||
for={id}
|
for={id}
|
||||||
on:keydown
|
on:keydown
|
||||||
on:keydown={({ key }) => {
|
on:keydown={({ key }) => {
|
||||||
|
@ -60,7 +57,9 @@
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
{tabindex}>
|
{tabindex}>
|
||||||
<div class={_class} {role}>
|
<div
|
||||||
|
class={cx('--file__drop-container', over && '--file__drop-container--drag-over', className)}
|
||||||
|
{role}>
|
||||||
{labelText}
|
{labelText}
|
||||||
<input
|
<input
|
||||||
bind:this={inputRef}
|
bind:this={inputRef}
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
export let successDelay = 1500;
|
export let successDelay = 1500;
|
||||||
export let style = undefined;
|
export let style = undefined;
|
||||||
|
|
||||||
import { createEventDispatcher, onDestroy } from 'svelte';
|
import { createEventDispatcher, afterUpdate, onDestroy } from 'svelte';
|
||||||
import CheckmarkFilled16 from 'carbon-icons-svelte/lib/CheckmarkFilled16';
|
import CheckmarkFilled16 from 'carbon-icons-svelte/lib/CheckmarkFilled16';
|
||||||
import Error20 from 'carbon-icons-svelte/lib/Error20';
|
import Error20 from 'carbon-icons-svelte/lib/Error20';
|
||||||
import { cx } from '../../lib';
|
import { cx } from '../../lib';
|
||||||
|
@ -17,18 +17,18 @@
|
||||||
|
|
||||||
let timeoutId = undefined;
|
let timeoutId = undefined;
|
||||||
|
|
||||||
onDestroy(() => {
|
afterUpdate(() => {
|
||||||
if (timeoutId !== undefined) {
|
if (status === 'finished') {
|
||||||
window.clearTimeout(timeoutId);
|
|
||||||
timeoutId = undefined;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$: if (status === 'finished') {
|
|
||||||
timeoutId = window.setTimeout(() => {
|
timeoutId = window.setTimeout(() => {
|
||||||
dispatch('success');
|
dispatch('success');
|
||||||
}, successDelay);
|
}, successDelay);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
onDestroy(() => {
|
||||||
|
window.clearTimeout(timeoutId);
|
||||||
|
timeoutId = undefined;
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
|
|
|
@ -21,14 +21,20 @@
|
||||||
|
|
||||||
const dispatch = createEventDispatcher();
|
const dispatch = createEventDispatcher();
|
||||||
|
|
||||||
|
let timeoutId = undefined;
|
||||||
let open = true;
|
let open = true;
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
if (timeout) {
|
if (timeout) {
|
||||||
window.setTimeout(() => {
|
timeoutId = window.setTimeout(() => {
|
||||||
open = false;
|
open = false;
|
||||||
}, timeout);
|
}, timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
window.clearTimeout(timeoutId);
|
||||||
|
timeoutId = undefined;
|
||||||
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
$: if (!open) {
|
$: if (!open) {
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
let className = undefined;
|
let className = undefined;
|
||||||
export { className as class };
|
export { className as class };
|
||||||
export let value = '';
|
export let value = '';
|
||||||
|
export let autofocus = false;
|
||||||
export let type = 'text';
|
export let type = 'text';
|
||||||
export let small = false;
|
export let small = false;
|
||||||
export let placeHolderText = '';
|
export let placeHolderText = '';
|
||||||
|
@ -28,6 +29,7 @@
|
||||||
{style}>
|
{style}>
|
||||||
<Search16 class={cx('--search-magnifier')} />
|
<Search16 class={cx('--search-magnifier')} />
|
||||||
<label for={id} class={cx('--label')}>{labelText}</label>
|
<label for={id} class={cx('--label')}>{labelText}</label>
|
||||||
|
<!-- svelte-ignore a11y-autofocus -->
|
||||||
<input
|
<input
|
||||||
bind:this={inputRef}
|
bind:this={inputRef}
|
||||||
role="searchbox"
|
role="searchbox"
|
||||||
|
@ -35,9 +37,10 @@
|
||||||
placeholder={placeHolderText}
|
placeholder={placeHolderText}
|
||||||
on:change
|
on:change
|
||||||
on:input
|
on:input
|
||||||
on:input={event => {
|
on:input={({ target }) => {
|
||||||
value = event.target.value;
|
value = target.value;
|
||||||
}}
|
}}
|
||||||
|
{autofocus}
|
||||||
{type}
|
{type}
|
||||||
{id}
|
{id}
|
||||||
{value} />
|
{value} />
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
export let light = false;
|
export let light = false;
|
||||||
export let style = undefined;
|
export let style = undefined;
|
||||||
|
|
||||||
import { tick } from 'svelte';
|
import { onMount, afterUpdate } from 'svelte';
|
||||||
import ChevronDown16 from 'carbon-icons-svelte/lib/ChevronDown16';
|
import ChevronDown16 from 'carbon-icons-svelte/lib/ChevronDown16';
|
||||||
import { cx, css } from '../../lib';
|
import { cx, css } from '../../lib';
|
||||||
|
|
||||||
|
@ -19,23 +19,20 @@
|
||||||
let tileContent = undefined;
|
let tileContent = undefined;
|
||||||
let aboveTheFold = undefined;
|
let aboveTheFold = undefined;
|
||||||
|
|
||||||
async function setHeight() {
|
onMount(() => {
|
||||||
await tick();
|
|
||||||
tileMaxHeight = expanded
|
|
||||||
? tileContent.getBoundingClientRect().height
|
|
||||||
: aboveTheFold.getBoundingClientRect().height;
|
|
||||||
}
|
|
||||||
|
|
||||||
$: {
|
|
||||||
if (tile) {
|
|
||||||
const style = window.getComputedStyle(tile);
|
const style = window.getComputedStyle(tile);
|
||||||
|
|
||||||
tileMaxHeight = aboveTheFold.getBoundingClientRect().height;
|
tileMaxHeight = aboveTheFold.getBoundingClientRect().height;
|
||||||
tilePadding =
|
tilePadding =
|
||||||
parseInt(style.getPropertyValue('padding-top'), 10) +
|
parseInt(style.getPropertyValue('padding-top'), 10) +
|
||||||
parseInt(style.getPropertyValue('padding-bottom'), 10);
|
parseInt(style.getPropertyValue('padding-bottom'), 10);
|
||||||
}
|
});
|
||||||
}
|
|
||||||
|
afterUpdate(() => {
|
||||||
|
tileMaxHeight = expanded
|
||||||
|
? tileContent.getBoundingClientRect().height
|
||||||
|
: aboveTheFold.getBoundingClientRect().height;
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
|
@ -45,14 +42,12 @@
|
||||||
on:click
|
on:click
|
||||||
on:click={() => {
|
on:click={() => {
|
||||||
expanded = !expanded;
|
expanded = !expanded;
|
||||||
setHeight();
|
|
||||||
}}
|
}}
|
||||||
on:keypress
|
on:keypress
|
||||||
on:keypress={event => {
|
on:keypress={event => {
|
||||||
if (event.key === ' ' || event.key === 'Enter') {
|
if (event.key === ' ' || event.key === 'Enter') {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
expanded = !expanded;
|
expanded = !expanded;
|
||||||
setHeight();
|
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
on:mouseover
|
on:mouseover
|
||||||
|
|
|
@ -9,20 +9,17 @@
|
||||||
export let labelB = 'On';
|
export let labelB = 'On';
|
||||||
export let style = undefined;
|
export let style = undefined;
|
||||||
|
|
||||||
import { createEventDispatcher } from 'svelte';
|
import { createEventDispatcher, afterUpdate } from 'svelte';
|
||||||
import { cx } from '../../lib';
|
import { cx } from '../../lib';
|
||||||
|
|
||||||
const dispatch = createEventDispatcher();
|
const dispatch = createEventDispatcher();
|
||||||
|
|
||||||
let inputRef = undefined;
|
let inputRef = undefined;
|
||||||
|
|
||||||
$: {
|
afterUpdate(() => {
|
||||||
dispatch('toggle', { id, toggled });
|
|
||||||
|
|
||||||
if (inputRef) {
|
|
||||||
inputRef.checked = toggled;
|
inputRef.checked = toggled;
|
||||||
}
|
dispatch('toggle', { id, toggled });
|
||||||
}
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div on:click on:mouseover on:mouseenter on:mouseleave class={cx('--form-item', className)} {style}>
|
<div on:click on:mouseover on:mouseenter on:mouseleave class={cx('--form-item', className)} {style}>
|
||||||
|
|
|
@ -9,20 +9,17 @@
|
||||||
export let labelB = 'On';
|
export let labelB = 'On';
|
||||||
export let style = undefined;
|
export let style = undefined;
|
||||||
|
|
||||||
import { createEventDispatcher } from 'svelte';
|
import { createEventDispatcher, afterUpdate } from 'svelte';
|
||||||
import { cx } from '../../lib';
|
import { cx } from '../../lib';
|
||||||
|
|
||||||
const dispatch = createEventDispatcher();
|
const dispatch = createEventDispatcher();
|
||||||
|
|
||||||
let inputRef = undefined;
|
let inputRef = undefined;
|
||||||
|
|
||||||
$: {
|
afterUpdate(() => {
|
||||||
dispatch('toggle', { id, toggled });
|
|
||||||
|
|
||||||
if (inputRef) {
|
|
||||||
inputRef.checked = toggled;
|
inputRef.checked = toggled;
|
||||||
}
|
dispatch('toggle', { id, toggled });
|
||||||
}
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div on:click on:mouseover on:mouseenter on:mouseleave class={cx('--form-item', className)} {style}>
|
<div on:click on:mouseover on:mouseenter on:mouseleave class={cx('--form-item', className)} {style}>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue