mirror of
https://github.com/carbon-design-system/carbon-components-svelte.git
synced 2025-09-14 18:01:06 +00:00
parent
422ac528a7
commit
94dceae1fb
11 changed files with 309 additions and 2 deletions
|
@ -28,9 +28,16 @@ Currently, the following components are supported:
|
|||
- CopyButton
|
||||
- DataTableSkeleton
|
||||
- InlineLoading
|
||||
- Loading
|
||||
- Link
|
||||
- ListItem
|
||||
- Loading
|
||||
- Notification
|
||||
- ToastNotification
|
||||
- InlineNotification
|
||||
- NotificationActionButton
|
||||
- NotificationButton
|
||||
- NotificationIcon
|
||||
- NotificationTextDetails
|
||||
- OrderedList
|
||||
- RadioButton
|
||||
- RadioButtonSkeleton
|
||||
|
|
54
src/components/Notification/InlineNotification.svelte
Normal file
54
src/components/Notification/InlineNotification.svelte
Normal file
|
@ -0,0 +1,54 @@
|
|||
<script>
|
||||
let className = undefined;
|
||||
export { className as class };
|
||||
export let kind = 'error';
|
||||
export let title = 'provide a title';
|
||||
export let subtitle = ''; // TODO: support subtitle slot?
|
||||
export let role = 'alert';
|
||||
export let notificationType = 'inline';
|
||||
export let iconDescription = 'closes notification';
|
||||
export let hideCloseButton = false;
|
||||
export let lowContrast = false;
|
||||
export let style = undefined;
|
||||
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
import NotificationIcon from './NotificationIcon.svelte';
|
||||
import NotificationTextDetails from './NotificationTextDetails.svelte';
|
||||
import NotificationButton from './NotificationButton.svelte';
|
||||
import { cx } from '../../lib';
|
||||
|
||||
const dispatch = createEventDispatcher();
|
||||
const _class = cx(
|
||||
'--inline-notification',
|
||||
lowContrast && '--inline-notification--low-contrast',
|
||||
kind && `--inline-notification--${kind}`,
|
||||
hideCloseButton && '--inline-notification--hide-close-button',
|
||||
className
|
||||
);
|
||||
|
||||
let open = true;
|
||||
|
||||
$: if (!open) {
|
||||
dispatch('close');
|
||||
}
|
||||
</script>
|
||||
|
||||
{#if open}
|
||||
<div on:click on:mouseover on:mouseenter on:mouseleave class={_class} {style} {role} {kind}>
|
||||
<div class={cx('--inline-notification__details')}>
|
||||
<NotificationIcon {notificationType} {kind} {iconDescription} />
|
||||
<NotificationTextDetails {title} {subtitle} {notificationType}>
|
||||
<slot />
|
||||
</NotificationTextDetails>
|
||||
</div>
|
||||
<slot name="actions" />
|
||||
{#if !hideCloseButton}
|
||||
<NotificationButton
|
||||
{iconDescription}
|
||||
{notificationType}
|
||||
on:click={() => {
|
||||
open = false;
|
||||
}} />
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
20
src/components/Notification/Notification.Story.svelte
Normal file
20
src/components/Notification/Notification.Story.svelte
Normal file
|
@ -0,0 +1,20 @@
|
|||
<script>
|
||||
export let story = undefined;
|
||||
|
||||
import Layout from '../../internal/ui/Layout.svelte';
|
||||
import InlineNotification from './InlineNotification.svelte';
|
||||
import ToastNotification from './ToastNotification.svelte';
|
||||
import NotificationActionButton from './NotificationActionButton.svelte';
|
||||
</script>
|
||||
|
||||
<Layout>
|
||||
{#if story === 'inline'}
|
||||
<InlineNotification {...$$props}>
|
||||
<div slot="actions">
|
||||
<NotificationActionButton>{$$props.action}</NotificationActionButton>
|
||||
</div>
|
||||
</InlineNotification>
|
||||
{:else if story === 'toast'}
|
||||
<ToastNotification {...$$props} style="min-width: 30rem; margin-bottom: .5rem" />
|
||||
{/if}
|
||||
</Layout>
|
42
src/components/Notification/Notification.stories.js
Normal file
42
src/components/Notification/Notification.stories.js
Normal file
|
@ -0,0 +1,42 @@
|
|||
import { withKnobs, select, boolean, text } from '@storybook/addon-knobs';
|
||||
import Component from './Notification.Story.svelte';
|
||||
|
||||
export default { title: 'Notification', decorators: [withKnobs] };
|
||||
|
||||
const kinds = {
|
||||
'Error (error)': 'error',
|
||||
'Info (info)': 'info',
|
||||
'Success (success)': 'success',
|
||||
'Warning (warning)': 'warning'
|
||||
};
|
||||
|
||||
export const Toast = () => ({
|
||||
Component,
|
||||
props: {
|
||||
story: 'toast',
|
||||
kind: select('The notification kind (kind)', kinds, 'info'),
|
||||
lowContrast: boolean('Use low contrast variant (lowContrast)', false),
|
||||
role: text('ARIA role (role)', 'alert'),
|
||||
title: text('Title (title)', 'Notification title'),
|
||||
subtitle: text('Subtitle (subtitle)', 'Subtitle text goes here.'),
|
||||
caption: text('Caption (caption)', 'Time stamp [00:00:00]'),
|
||||
iconDescription: text('Icon description (iconDescription)', 'describes the close button'),
|
||||
hideCloseButton: boolean('Hide close button (hideCloseButton)', false)
|
||||
}
|
||||
});
|
||||
|
||||
export const Inline = () => ({
|
||||
Component,
|
||||
props: {
|
||||
story: 'inline',
|
||||
kind: select('The notification kind (kind)', kinds, 'info'),
|
||||
lowContrast: boolean('Use low contrast variant (lowContrast)', false),
|
||||
role: text('ARIA role (role)', 'alert'),
|
||||
title: text('Title (title)', 'Notification title'),
|
||||
subtitle: text('Subtitle (subtitle)', 'Subtitle text goes here.'),
|
||||
caption: text('Caption (caption)', 'Time stamp [00:00:00]'),
|
||||
iconDescription: text('Icon description (iconDescription)', 'describes the close button'),
|
||||
hideCloseButton: boolean('Hide close button (hideCloseButton)', false),
|
||||
action: text('Action (NotificationActionButton > $$slot#action)', 'Action')
|
||||
}
|
||||
});
|
22
src/components/Notification/NotificationActionButton.svelte
Normal file
22
src/components/Notification/NotificationActionButton.svelte
Normal file
|
@ -0,0 +1,22 @@
|
|||
<script>
|
||||
let className = undefined;
|
||||
export { className as class };
|
||||
export let style = undefined;
|
||||
|
||||
import Button from '../Button';
|
||||
import { cx } from '../../lib';
|
||||
|
||||
const _class = cx('--inline-notification__action-button', className);
|
||||
</script>
|
||||
|
||||
<Button
|
||||
kind="ghost"
|
||||
size="small"
|
||||
on:click
|
||||
on:mouseover
|
||||
on:mouseenter
|
||||
on:mouseleave
|
||||
class={_class}
|
||||
{style}>
|
||||
<slot />
|
||||
</Button>
|
36
src/components/Notification/NotificationButton.svelte
Normal file
36
src/components/Notification/NotificationButton.svelte
Normal file
|
@ -0,0 +1,36 @@
|
|||
<script>
|
||||
let className = undefined;
|
||||
export { className as class };
|
||||
export let notificationType = 'toast';
|
||||
export let type = 'button';
|
||||
export let iconDescription = 'close icon';
|
||||
export let renderIcon = Close20;
|
||||
export let title = undefined;
|
||||
export let style = undefined;
|
||||
|
||||
import Close20 from 'carbon-icons-svelte/lib/Close20';
|
||||
import { cx } from '../../lib';
|
||||
|
||||
const _class = cx(
|
||||
notificationType === 'toast' && '--toast-notification__close-button',
|
||||
notificationType === 'inline' && '--inline-notification__close-button',
|
||||
className
|
||||
);
|
||||
const _iconClass = cx(
|
||||
notificationType === 'toast' && '--toast-notification__close-icon',
|
||||
notificationType === 'inline' && '--inline-notification__close-icon'
|
||||
);
|
||||
</script>
|
||||
|
||||
<button
|
||||
on:click
|
||||
on:mouseover
|
||||
on:mouseenter
|
||||
on:mouseleave
|
||||
aria-label={iconDescription}
|
||||
title={iconDescription}
|
||||
class={_class}
|
||||
{style}
|
||||
{type}>
|
||||
<svelte:component this={renderIcon} class={_iconClass} {title} />
|
||||
</button>
|
21
src/components/Notification/NotificationIcon.svelte
Normal file
21
src/components/Notification/NotificationIcon.svelte
Normal file
|
@ -0,0 +1,21 @@
|
|||
<script>
|
||||
export let kind = 'error';
|
||||
export let notificationType = 'toast';
|
||||
export let iconDescription = 'closes notification';
|
||||
|
||||
import ErrorFilled20 from 'carbon-icons-svelte/lib/ErrorFilled20';
|
||||
import CheckmarkFilled20 from 'carbon-icons-svelte/lib/CheckmarkFilled20';
|
||||
import WarningFilled20 from 'carbon-icons-svelte/lib/WarningFilled20';
|
||||
import { cx } from '../../lib';
|
||||
|
||||
const icons = {
|
||||
error: ErrorFilled20,
|
||||
success: CheckmarkFilled20,
|
||||
warning: WarningFilled20
|
||||
};
|
||||
</script>
|
||||
|
||||
<svelte:component
|
||||
this={icons[kind]}
|
||||
class={cx(`--${notificationType}-notification__icon`)}
|
||||
title={iconDescription} />
|
25
src/components/Notification/NotificationTextDetails.svelte
Normal file
25
src/components/Notification/NotificationTextDetails.svelte
Normal file
|
@ -0,0 +1,25 @@
|
|||
<script>
|
||||
export let title = 'title';
|
||||
export let subtitle = '';
|
||||
export let caption = 'caption';
|
||||
export let notificationType = 'toast';
|
||||
|
||||
import { cx } from '../../lib';
|
||||
</script>
|
||||
|
||||
{#if notificationType === 'toast'}
|
||||
<div class={cx('--toast-notification__details')}>
|
||||
<h3 class={cx('--toast-notification__title')}>{title}</h3>
|
||||
<div class={cx('--toast-notification__subtitle')}>{subtitle}</div>
|
||||
<div class={cx('--toast-notification__caption')}>{caption}</div>
|
||||
<slot />
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{#if notificationType === 'inline'}
|
||||
<div class={cx('--inline-notification__text-wrapper')}>
|
||||
<p class={cx('--inline-notification__title')}>{title}</p>
|
||||
<div class={cx('--inline-notification__subtitle')}>{subtitle}</div>
|
||||
<slot />
|
||||
</div>
|
||||
{/if}
|
60
src/components/Notification/ToastNotification.svelte
Normal file
60
src/components/Notification/ToastNotification.svelte
Normal file
|
@ -0,0 +1,60 @@
|
|||
<script>
|
||||
let className = undefined;
|
||||
export { className as class };
|
||||
export let kind = 'error';
|
||||
export let title = 'provide a title';
|
||||
export let subtitle = ''; // TODO: support subtitle slot?
|
||||
export let caption = 'provide a caption';
|
||||
export let role = 'alert';
|
||||
export let notificationType = 'toast';
|
||||
export let iconDescription = 'closes notification';
|
||||
export let hideCloseButton = false;
|
||||
export let lowContrast = false;
|
||||
export let timeout = 0;
|
||||
export let style = undefined;
|
||||
|
||||
import { createEventDispatcher, onMount } from 'svelte';
|
||||
import NotificationIcon from './NotificationIcon.svelte';
|
||||
import NotificationTextDetails from './NotificationTextDetails.svelte';
|
||||
import NotificationButton from './NotificationButton.svelte';
|
||||
import { cx } from '../../lib';
|
||||
|
||||
const dispatch = createEventDispatcher();
|
||||
const _class = cx(
|
||||
'--toast-notification',
|
||||
lowContrast && '--toast-notification--low-contrast',
|
||||
kind && `--toast-notification--${kind}`,
|
||||
className
|
||||
);
|
||||
|
||||
let open = true;
|
||||
|
||||
onMount(() => {
|
||||
if (timeout) {
|
||||
window.setTimeout(() => {
|
||||
open = false;
|
||||
}, timeout);
|
||||
}
|
||||
});
|
||||
|
||||
$: if (!open) {
|
||||
dispatch('close');
|
||||
}
|
||||
</script>
|
||||
|
||||
{#if open}
|
||||
<div on:click on:mouseover on:mouseenter on:mouseleave class={_class} {style} {role} {kind}>
|
||||
<NotificationIcon {notificationType} {kind} {iconDescription} />
|
||||
<NotificationTextDetails {title} {subtitle} {caption} {notificationType}>
|
||||
<slot />
|
||||
</NotificationTextDetails>
|
||||
{#if !hideCloseButton}
|
||||
<NotificationButton
|
||||
{iconDescription}
|
||||
{notificationType}
|
||||
on:click={() => {
|
||||
open = false;
|
||||
}} />
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
6
src/components/Notification/index.js
Normal file
6
src/components/Notification/index.js
Normal file
|
@ -0,0 +1,6 @@
|
|||
export { default as ToastNotification } from './ToastNotification.svelte';
|
||||
export { default as InlineNotification } from './InlineNotification.svelte';
|
||||
export { default as NotificationActionButton } from './NotificationActionButton.svelte';
|
||||
export { default as NotificationButton } from './NotificationButton.svelte';
|
||||
export { default as NotificationIcon } from './NotificationIcon.svelte';
|
||||
export { default as NotificationTextDetails } from './NotificationTextDetails.svelte';
|
16
src/index.js
16
src/index.js
|
@ -8,9 +8,17 @@ import CopyButton from './components/CopyButton';
|
|||
import CodeSnippet, { CodeSnippetSkeleton } from './components/CodeSnippet';
|
||||
import DataTableSkeleton from './components/DataTableSkeleton';
|
||||
import InlineLoading from './components/InlineLoading';
|
||||
import Loading from './components/Loading';
|
||||
import Link from './components/Link';
|
||||
import ListItem from './components/ListItem';
|
||||
import Loading from './components/Loading';
|
||||
import {
|
||||
ToastNotification,
|
||||
InlineNotification,
|
||||
NotificationActionButton,
|
||||
NotificationButton,
|
||||
NotificationIcon,
|
||||
NotificationTextDetails
|
||||
} from './components/Notification';
|
||||
import OrderedList from './components/OrderedList';
|
||||
import RadioButton, { RadioButtonSkeleton } from './components/RadioButton';
|
||||
import Search, { SearchSkeleton } from './components/Search';
|
||||
|
@ -53,9 +61,14 @@ export {
|
|||
DataTableSkeleton,
|
||||
ExpandableTile,
|
||||
InlineLoading,
|
||||
InlineNotification,
|
||||
Link,
|
||||
ListItem,
|
||||
Loading,
|
||||
NotificationActionButton,
|
||||
NotificationButton,
|
||||
NotificationIcon,
|
||||
NotificationTextDetails,
|
||||
OrderedList,
|
||||
PasswordInput,
|
||||
RadioButton,
|
||||
|
@ -76,6 +89,7 @@ export {
|
|||
TileAboveTheFoldContent,
|
||||
TileBelowTheFoldContent,
|
||||
TileGroup,
|
||||
ToastNotification,
|
||||
Toggle,
|
||||
ToggleSkeleton,
|
||||
ToggleSmall,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue