Alignment with Carbon version 10.30 (#559)

* feat(toolbar): forward "clear" event in ToolbarSearch

* docs(search): add on:clear example

* fix(ui-shell): set aria-hidden in SideNav

Ref c2b4f1f00

* chore(deps-dev): upgrade carbon-components to v10.30.0

* fix(text-input): use bx--text-input class for TextInputSkeleton

* fix(radio-button): only render span if labelText is truthy

* docs(password-input): add custom tooltip example

* feat(button): add isSelected prop for icon-only, ghost buttons

* feat(radio-button): add legendText prop to RadioButtonGroup

* docs(tag): add filterable (disabled) variant

* feat(tag): add interactive prop

* chore(number-input): deprecate the mobile variant

Mobile variant styles will no longer work.

* feat(button): set aria-pressed attribute if icon-only, ghost button is selected

* fix(multi-select): type dispatched select event

* fix(button): remove redundant "button" role

* feat(icon): deprecate Icon, IconSkeleton

* feat(ui-shell): make SideNavMenuItem text slottable

* fix(list-box): update styles for ListBoxSelection

* fix(list-box): temporarily apply override styles to ListBoxMenuIcon for chevron

* fix(tag): set disabled prop on interactive tag

* docs(button): extract selected, icon-only button example

* feat(tooltip): elevate z-index of tooltip when open

* feat: forward restProps to input element

* fix(types): fix TimePicker test to pass svelte-check

* feat: add ImageLoader component

* test: add ImageLoader

* feat: add LocalStorage component

* test(local-storage): fix invalid file

* chore(docs): use green tag type
This commit is contained in:
Eric Liu 2021-03-13 14:53:37 -08:00 committed by GitHub
commit 1b234ca2e3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
68 changed files with 1079 additions and 217 deletions

View file

@ -1,6 +1,6 @@
# Component Index
> 158 components exported from carbon-components-svelte@0.29.2.
> 160 components exported from carbon-components-svelte@0.29.2.
## Components
@ -61,6 +61,7 @@
- [`HeaderUtilities`](#headerutilities)
- [`Icon`](#icon)
- [`IconSkeleton`](#iconskeleton)
- [`ImageLoader`](#imageloader)
- [`InlineLoading`](#inlineloading)
- [`InlineNotification`](#inlinenotification)
- [`Link`](#link)
@ -72,6 +73,7 @@
- [`ListBoxSelection`](#listboxselection)
- [`ListItem`](#listitem)
- [`Loading`](#loading)
- [`LocalStorage`](#localstorage)
- [`Modal`](#modal)
- [`ModalBody`](#modalbody)
- [`ModalFooter`](#modalfooter)
@ -342,6 +344,7 @@ None.
| hasIconOnly | <code>let</code> | Yes | <code>boolean</code> | <code>false</code> | Set to `true` for the icon-only variant |
| kind | <code>let</code> | No | <code>"primary" &#124; "secondary" &#124; "tertiary" &#124; "ghost" &#124; "danger" &#124; "danger-tertiary" &#124; "danger-ghost"</code> | <code>"primary"</code> | Specify the kind of button |
| size | <code>let</code> | No | <code>"default" &#124; "field" &#124; "small"</code> | <code>"default"</code> | Specify the size of button |
| isSelected | <code>let</code> | No | <code>boolean</code> | <code>false</code> | Set to `true` to enable the selected state for an icon-only, ghost button |
| icon | <code>let</code> | No | <code>typeof import("carbon-icons-svelte").CarbonIcon</code> | -- | Specify the icon from `carbon-icons-svelte` to render |
| iconDescription | <code>let</code> | No | <code>string</code> | -- | Specify the ARIA label for the button icon |
| tooltipAlignment | <code>let</code> | No | <code>"start" &#124; "center" &#124; "end"</code> | <code>"center"</code> | Set the alignment of the tooltip relative to the icon<br />`hasIconOnly` must be set to `true` |
@ -1723,6 +1726,35 @@ None.
| mouseenter | forwarded | -- |
| mouseleave | forwarded | -- |
## `ImageLoader`
### Props
| Prop name | Kind | Reactive | Type | Default value | Description |
| :-------- | :----------------- | :------- | :------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| error | <code>let</code> | Yes | <code>boolean</code> | <code>false</code> | Set to `true` if an error occurs when loading the image |
| loaded | <code>let</code> | Yes | <code>boolean</code> | <code>false</code> | Set to `true` when the image is loaded |
| loading | <code>let</code> | Yes | <code>boolean</code> | <code>false</code> | Set to `true` when `loaded` is `true` and `error` is false |
| src | <code>let</code> | No | <code>string</code> | <code>""</code> | Specify the image source |
| alt | <code>let</code> | No | <code>string</code> | <code>""</code> | Specify the image alt text |
| ratio | <code>let</code> | No | <code>"2x1" &#124; "16x9" &#124; "4x3" &#124; "1x1" &#124; "3x4" &#124; "9x16" &#124; "1x2"</code> | -- | Specify the aspect ratio for the image wrapper |
| fadeIn | <code>let</code> | No | <code>boolean</code> | <code>false</code> | Set to `true` to fade in the image on load<br />The duration uses the `fast-02` value following Carbon guidelines on motion |
| loadImage | <code>const</code> | No | <code>(url?: string) => void</code> | <code>(url) => { if (image != null) image = null; loaded = false; error = false; image = new Image(); image.src = url &#124;&#124; src; image.onload = () => (loaded = true); image.onerror = () => (error = true); }</code> | Method invoked to load the image provided a `src` value |
### Slots
| Slot name | Default | Props | Fallback |
| :-------- | :------ | :---- | :------- |
| error | No | -- | -- |
| loading | No | -- | -- |
### Events
| Event name | Type | Detail |
| :--------- | :--------- | :--------------- |
| load | dispatched | <code>any</code> |
| error | dispatched | <code>any</code> |
## `InlineLoading`
### Props
@ -1957,7 +1989,7 @@ export type ListBoxSelectionTranslationId = "clearAll" | "clearSelection";
| Prop name | Kind | Reactive | Type | Default value | Description |
| :-------------- | :----------------- | :------- | :----------------------------------------------------------------------- | ------------------------------------------------------------------------ | ------------------------------------------------ |
| ref | <code>let</code> | Yes | <code>null &#124; HTMLDivElement</code> | <code>null</code> | Obtain a reference to the top-level HTML element |
| selectionCount | <code>let</code> | No | <code>any</code> | -- | Specify the number of selected items |
| selectionCount | <code>let</code> | No | <code>number</code> | -- | Specify the number of selected items |
| disabled | <code>let</code> | No | <code>boolean</code> | <code>false</code> | Set to `true` to disable the list box selection |
| translationIds | <code>const</code> | No | <code>{ clearAll: "clearAll", clearSelection: "clearSelection", }</code> | <code>{ clearAll: "clearAll", clearSelection: "clearSelection", }</code> | Default translation ids |
| translateWithId | <code>let</code> | No | <code>(id: ListBoxSelectionTranslationId) => string</code> | <code>(id) => defaultTranslations[id]</code> | Override the default translation ids |
@ -2013,6 +2045,26 @@ None.
None.
## `LocalStorage`
### Props
| Prop name | Kind | Reactive | Type | Default value | Description |
| :-------- | :--------------- | :------- | :------------------ | -------------------------------- | ----------------------------- |
| value | <code>let</code> | Yes | <code>any</code> | <code>""</code> | Provide a value to persist |
| key | <code>let</code> | No | <code>string</code> | <code>"local-storage-key"</code> | Specify the local storage key |
### Slots
None.
### Events
| Event name | Type | Detail |
| :--------- | :--------- | :------------------------------------------- |
| save | dispatched | <code>any</code> |
| update | dispatched | <code>{ prevValue: any; value: any; }</code> |
## `Modal`
### Props
@ -2184,12 +2236,12 @@ None.
### Events
| Event name | Type | Detail |
| :--------- | :--------- | :----- |
| :--------- | :--------- | :-------------------------------------------------------------------------------------------------- |
| select | dispatched | <code>{ selectedIds: string[]; selected: MultiSelectItem[]; unselected: MultiSelectItem[]; }</code> |
| clear | forwarded | -- |
| keydown | forwarded | -- |
| focus | forwarded | -- |
| blur | forwarded | -- |
| select | dispatched | -- |
## `NotificationActionButton`
@ -2694,6 +2746,7 @@ None.
| :------------ | :--------------- | :------- | :------------------------------------------ | ------------------------- | -------------------------------------------- |
| selected | <code>let</code> | Yes | <code>string</code> | -- | Set the selected radio button value |
| disabled | <code>let</code> | No | <code>boolean</code> | <code>false</code> | Set to `true` to disable the radio buttons |
| legendText | <code>let</code> | No | <code>string</code> | <code>""</code> | Specify the legend text |
| labelPosition | <code>let</code> | No | <code>"right" &#124; "left"</code> | <code>"right"</code> | Specify the label position |
| orientation | <code>let</code> | No | <code>"horizontal" &#124; "vertical"</code> | <code>"horizontal"</code> | Specify the orientation of the radio buttons |
| id | <code>let</code> | No | <code>string</code> | -- | Set an id for the container div element |
@ -2701,8 +2754,9 @@ None.
### Slots
| Slot name | Default | Props | Fallback |
| :-------- | :------ | :---- | :------- |
| :--------- | :------ | :---- | :------------------------ |
| -- | Yes | -- | -- |
| legendText | No | -- | <code>{legendText}</code> |
### Events
@ -3083,7 +3137,9 @@ None.
### Slots
None.
| Slot name | Default | Props | Fallback |
| :-------- | :------ | :---- | :------------------ |
| -- | Yes | -- | <code>{text}</code> |
### Events
@ -3648,11 +3704,12 @@ None.
### Props
| Prop name | Kind | Reactive | Type | Default value | Description |
| :-------- | :--------------- | :------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------ | ------------------------------------------------------ |
| :---------- | :--------------- | :------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------ | ------------------------------------------------------------- |
| type | <code>let</code> | No | <code>"red" &#124; "magenta" &#124; "purple" &#124; "blue" &#124; "cyan" &#124; "teal" &#124; "green" &#124; "gray" &#124; "cool-gray" &#124; "warm-gray" &#124; "high-contrast"</code> | -- | Specify the type of tag |
| size | <code>let</code> | No | <code>"sm" &#124; "default"</code> | <code>"default"</code> | -- |
| filter | <code>let</code> | No | <code>boolean</code> | <code>false</code> | Set to `true` to use filterable variant |
| disabled | <code>let</code> | No | <code>boolean</code> | <code>false</code> | Set to `true` to disable a filterable tag |
| interactive | <code>let</code> | No | <code>boolean</code> | <code>false</code> | Set to `true` to render a `button` element instead of a `div` |
| skeleton | <code>let</code> | No | <code>boolean</code> | <code>false</code> | Set to `true` to display the skeleton state |
| title | <code>let</code> | No | <code>string</code> | <code>"Clear filter"</code> | Set the title for the close button in a filterable tag |
| icon | <code>let</code> | No | <code>typeof import("carbon-icons-svelte").CarbonIcon</code> | -- | Specify the icon from `carbon-icons-svelte` to render |
@ -4183,6 +4240,7 @@ None.
| Event name | Type | Detail |
| :--------- | :-------- | :----- |
| clear | forwarded | -- |
| change | forwarded | -- |
| input | forwarded | -- |
| focus | forwarded | -- |

View file

@ -11,7 +11,7 @@
"devDependencies": {
"@sveltech/routify": "^1.9.9",
"autoprefixer": "^10.2.3",
"carbon-components": "10.29.0",
"carbon-components": "10.30.0",
"carbon-components-svelte": "../",
"clipboard-copy": "^3.1.0",
"mdsvex": "^0.8.8",

View file

@ -1,5 +1,5 @@
{
"total": 158,
"total": 160,
"components": [
{
"moduleName": "Accordion",
@ -368,6 +368,16 @@
"constant": false,
"reactive": false
},
{
"name": "isSelected",
"kind": "let",
"description": "Set to `true` to enable the selected state for an icon-only, ghost button",
"type": "boolean",
"value": "false",
"isFunction": false,
"constant": false,
"reactive": false
},
{
"name": "hasIconOnly",
"kind": "let",
@ -1387,7 +1397,7 @@
"ts": "interface ComboBoxItem { id: string; text: string; }"
}
],
"rest_props": { "type": "Element", "name": "div" }
"rest_props": { "type": "Element", "name": "input" }
},
{
"moduleName": "ComposedModal",
@ -2239,7 +2249,7 @@
{ "type": "forwarded", "name": "blur", "element": "input" }
],
"typedefs": [],
"rest_props": { "type": "Element", "name": "div" }
"rest_props": { "type": "Element", "name": "input" }
},
{
"moduleName": "DatePickerSkeleton",
@ -4042,6 +4052,101 @@
"typedefs": [],
"rest_props": { "type": "Element", "name": "div" }
},
{
"moduleName": "ImageLoader",
"filePath": "src/ImageLoader/ImageLoader.svelte",
"props": [
{
"name": "src",
"kind": "let",
"description": "Specify the image source",
"type": "string",
"value": "\"\"",
"isFunction": false,
"constant": false,
"reactive": false
},
{
"name": "alt",
"kind": "let",
"description": "Specify the image alt text",
"type": "string",
"value": "\"\"",
"isFunction": false,
"constant": false,
"reactive": false
},
{
"name": "ratio",
"kind": "let",
"description": "Specify the aspect ratio for the image wrapper",
"type": "\"2x1\" | \"16x9\" | \"4x3\" | \"1x1\" | \"3x4\" | \"9x16\" | \"1x2\"",
"isFunction": false,
"constant": false,
"reactive": false
},
{
"name": "loading",
"kind": "let",
"description": "Set to `true` when `loaded` is `true` and `error` is false",
"type": "boolean",
"value": "false",
"isFunction": false,
"constant": false,
"reactive": true
},
{
"name": "loaded",
"kind": "let",
"description": "Set to `true` when the image is loaded",
"type": "boolean",
"value": "false",
"isFunction": false,
"constant": false,
"reactive": true
},
{
"name": "error",
"kind": "let",
"description": "Set to `true` if an error occurs when loading the image",
"type": "boolean",
"value": "false",
"isFunction": false,
"constant": false,
"reactive": true
},
{
"name": "fadeIn",
"kind": "let",
"description": "Set to `true` to fade in the image on load\nThe duration uses the `fast-02` value following Carbon guidelines on motion",
"type": "boolean",
"value": "false",
"isFunction": false,
"constant": false,
"reactive": false
},
{
"name": "loadImage",
"kind": "const",
"description": "Method invoked to load the image provided a `src` value",
"type": "(url?: string) => void",
"value": "(url) => { if (image != null) image = null; loaded = false; error = false; image = new Image(); image.src = url || src; image.onload = () => (loaded = true); image.onerror = () => (error = true); }",
"isFunction": true,
"constant": true,
"reactive": false
}
],
"slots": [
{ "name": "error", "default": false, "slot_props": "{}" },
{ "name": "loading", "default": false, "slot_props": "{}" }
],
"events": [
{ "type": "dispatched", "name": "load", "detail": "any" },
{ "type": "dispatched", "name": "error", "detail": "any" }
],
"typedefs": [],
"rest_props": { "type": "Element", "name": "img" }
},
{
"moduleName": "InlineLoading",
"filePath": "src/InlineLoading/InlineLoading.svelte",
@ -4585,7 +4690,7 @@
"name": "selectionCount",
"kind": "let",
"description": "Specify the number of selected items",
"type": "any",
"type": "number",
"isFunction": false,
"constant": false,
"reactive": false
@ -4716,6 +4821,42 @@
"typedefs": [],
"rest_props": { "type": "Element", "name": "div" }
},
{
"moduleName": "LocalStorage",
"filePath": "src/LocalStorage/LocalStorage.svelte",
"props": [
{
"name": "key",
"kind": "let",
"description": "Specify the local storage key",
"type": "string",
"value": "\"local-storage-key\"",
"isFunction": false,
"constant": false,
"reactive": false
},
{
"name": "value",
"kind": "let",
"description": "Provide a value to persist",
"type": "any",
"value": "\"\"",
"isFunction": false,
"constant": false,
"reactive": true
}
],
"slots": [],
"events": [
{ "type": "dispatched", "name": "save", "detail": "any" },
{
"type": "dispatched",
"name": "update",
"detail": "{ prevValue: any; value: any; }"
}
],
"typedefs": []
},
{
"moduleName": "Modal",
"filePath": "src/Modal/Modal.svelte",
@ -5393,11 +5534,15 @@
],
"slots": [],
"events": [
{
"type": "dispatched",
"name": "select",
"detail": "{ selectedIds: string[]; selected: MultiSelectItem[]; unselected: MultiSelectItem[]; }"
},
{ "type": "forwarded", "name": "clear", "element": "ListBoxSelection" },
{ "type": "forwarded", "name": "keydown", "element": "input" },
{ "type": "forwarded", "name": "focus", "element": "input" },
{ "type": "forwarded", "name": "blur", "element": "input" },
{ "type": "dispatched", "name": "select" }
{ "type": "forwarded", "name": "blur", "element": "input" }
],
"typedefs": [
{
@ -5416,7 +5561,7 @@
"ts": "interface MultiSelectItem { id: MultiSelectItemId; text: MultiSelectItemText; }"
}
],
"rest_props": { "type": "Element", "name": "div" }
"rest_props": { "type": "Element", "name": "input" }
},
{
"moduleName": "NotificationActionButton",
@ -5827,7 +5972,7 @@
"ts": "type NumberInputTranslationId = \"increment\" | \"decrement\""
}
],
"rest_props": { "type": "Element", "name": "div" }
"rest_props": { "type": "Element", "name": "input" }
},
{
"moduleName": "NumberInputSkeleton",
@ -6950,6 +7095,16 @@
"constant": false,
"reactive": false
},
{
"name": "legendText",
"kind": "let",
"description": "Specify the legend text",
"type": "string",
"value": "\"\"",
"isFunction": false,
"constant": false,
"reactive": false
},
{
"name": "labelPosition",
"kind": "let",
@ -6980,7 +7135,15 @@
"reactive": false
}
],
"slots": [{ "name": "__default__", "default": true, "slot_props": "{}" }],
"slots": [
{ "name": "__default__", "default": true, "slot_props": "{}" },
{
"name": "legendText",
"default": false,
"fallback": "{legendText}",
"slot_props": "{}"
}
],
"events": [
{ "type": "forwarded", "name": "click", "element": "div" },
{ "type": "forwarded", "name": "mouseover", "element": "div" },
@ -7947,7 +8110,14 @@
"reactive": true
}
],
"slots": [],
"slots": [
{
"name": "__default__",
"default": true,
"fallback": "{text}",
"slot_props": "{}"
}
],
"events": [{ "type": "forwarded", "name": "click", "element": "a" }],
"typedefs": [],
"rest_props": { "type": "Element", "name": "a" }
@ -9032,6 +9202,16 @@
"constant": false,
"reactive": false
},
{
"name": "interactive",
"kind": "let",
"description": "Set to `true` to render a `button` element instead of a `div`",
"type": "boolean",
"value": "false",
"isFunction": false,
"constant": false,
"reactive": false
},
{
"name": "skeleton",
"kind": "let",
@ -9748,7 +9928,7 @@
{ "type": "forwarded", "name": "blur", "element": "input" }
],
"typedefs": [],
"rest_props": { "type": "Element", "name": "div" }
"rest_props": { "type": "Element", "name": "input" }
},
{
"moduleName": "TimePickerSelect",
@ -10372,6 +10552,7 @@
],
"slots": [],
"events": [
{ "type": "forwarded", "name": "clear", "element": "Search" },
{ "type": "forwarded", "name": "change", "element": "Search" },
{ "type": "forwarded", "name": "input", "element": "Search" },
{ "type": "forwarded", "name": "focus", "element": "Search" },

View file

@ -13,11 +13,15 @@
SideNavItems,
SideNavMenu,
SideNavMenuItem,
Tag,
} from "carbon-components-svelte";
import LogoGithub20 from "carbon-icons-svelte/lib/LogoGithub20";
import Theme from "../components/Theme.svelte";
import Footer from "../components/Footer.svelte";
const deprecated = ["ToggleSmall", "Icon"];
const new_components = ["ImageLoader", "LocalStorage"];
let isOpen = false;
let isSideNavOpen = true;
let innerWidth = 2048;
@ -98,16 +102,25 @@
text="{child.title}"
href="{$url(child.path)}"
isSelected="{$isActive($url(child.path))}"
/>
>
{child.title}
{#if deprecated.includes(child.title)}
<Tag size="sm" type="red">Deprecated</Tag>
{/if}
{#if new_components.includes(child.title)}
<Tag size="sm" type="green">New</Tag>
{/if}
</SideNavMenuItem>
{/each}
</SideNavMenu>
<SideNavMenu expanded="{$isActive($url('/recipes'))}" text="Recipes">
{#each recipes.children as child, i (child.path)}
<SideNavMenuItem
text="{child.title}"
href="{$url(child.path)}"
isSelected="{$isActive($url(child.path))}"
/>
>
{child.title}
</SideNavMenuItem>
{/each}
</SideNavMenu>
</SideNavItems>

View file

@ -5,7 +5,7 @@
The `AspectRatio` component is useful for constraining fluid content within an aspect ratio. To demo this, resize your browser for the examples below.
Supported aspect ratios: `"2x1"`, `"16x9"`, `"4x3"`, `"1x1"`, `"3x4"`, `"9x16"`, `"1x2"`
Supported aspect ratios include `"2x1"`, `"16x9"`, `"4x3"`, `"1x1"`, `"3x4"`, `"9x16"` and `"1x2"`.
### Default (2x1)

View file

@ -2,7 +2,12 @@
import { Button } from "carbon-components-svelte";
import Add16 from "carbon-icons-svelte/lib/Add16";
import TrashCan16 from "carbon-icons-svelte/lib/TrashCan16";
import TextBold16 from "carbon-icons-svelte/lib/TextBold16";
import TextItalic16 from "carbon-icons-svelte/lib/TextItalic16";
import TextUnderline16 from "carbon-icons-svelte/lib/TextUnderline16";
import Preview from "../../components/Preview.svelte";
let index = 1;
</script>
### Primary button
@ -55,6 +60,12 @@ The tooltip position and alignment can be controlled by `tooltipPosition` and `t
<Button tooltipPosition="right" tooltipAlignment="end" iconDescription="Tooltip text" icon={Add16} />
### Selected icon-only, ghost button
Set `isSelected` to `true` to enable the selected state for an icon-only, ghost button.
<FileSource src="/framed/Button/SelectedIconOnlyButton" />
### Link button
If an `href` value is specified, the component will render an [anchor element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a) with a "button" role.

View file

@ -1,5 +1,5 @@
<script>
import { Icon } from "carbon-components-svelte";
import { Icon, InlineNotification, OutboundLink } from "carbon-components-svelte";
import Add16 from "carbon-icons-svelte/lib/Add16";
import Add20 from "carbon-icons-svelte/lib/Add20";
import Add24 from "carbon-icons-svelte/lib/Add24";
@ -7,6 +7,12 @@
import Preview from "../../components/Preview.svelte";
</script>
<InlineNotification svx-ignore title="Deprecation warning" kind="warning" hideCloseButton>
<div>
This component will be removed in the next major release. Use icons from <OutboundLink href="https://github.com/IBM/carbon-icons-svelte">carbon-icons-svelte</OutboundLink> instead.
</div>
</InlineNotification>
### Default
<Icon render={Add16} />

View file

@ -0,0 +1,46 @@
<script>
import { ImageLoader, Button, InlineLoading } from "carbon-components-svelte";
import Preview from "../../components/Preview.svelte";
let key = 0;
</script>
This utility component uses the [Image API](https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/Image) to programmatically load an image with slottable loading and error states.
### Default
<ImageLoader src="https://upload.wikimedia.org/wikipedia/commons/5/51/IBM_logo.svg" />
### Slots
Use the "loading" and "error" named slots to render an element when the image is loading or has an error.
<ImageLoader src="https://upload.wikimedia.org/wikipedia/commons/5/51/IBM_logo.svg">
<div slot="loading">
<InlineLoading />
</div>
<div slot="error">
An error occurred.
</div>
</ImageLoader>
### With aspect ratio
If `ratio` is set, this component uses the [AspectRatio](/components/AspectRatio) to constrain the image.
Supported aspect ratios include `"2x1"`, `"16x9"`, `"4x3"`, `"1x1"`, `"3x4"`, `"9x16"` and `"1x2"`.
<ImageLoader ratio="16x9" src="https://upload.wikimedia.org/wikipedia/commons/5/51/IBM_logo.svg" />
### Fade in
Set `fadeIn` to `true` to fade in the image if successfully loaded.
<Button kind="ghost" on:click="{() => { key++;}}">Reload image</Button>
{#key key}<ImageLoader fadeIn ratio="16x9" src="https://upload.wikimedia.org/wikipedia/commons/5/51/IBM_logo.svg" />{/key}
### Programmatic usage
In this example, a component reference is obtained to programmatically trigger the `loadImage` method.
<FileSource src="/framed/ImageLoader/ProgrammaticImageLoader" />

View file

@ -0,0 +1,9 @@
<script>
import Preview from "../../components/Preview.svelte";
</script>
This utility component wraps the [Window.localStorage API](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage) and is useful for persisting ephemeral data (e.g., color theme) at the browser level.
### Reactive example
<FileSource src="/framed/LocalStorage/LocalStorage" />

View file

@ -24,6 +24,16 @@ To prevent alphabetical item ordering, pass an empty function to the `sortItem`
sortItem="{() => {}}"
/>
### Filterable
`$$restProps` are spread to the underlying input element.
<MultiSelect spellcheck="false" filterable titleText="Contact" placeholder="Filter contact methods..."
items="{[{id: "0", text: "Slack"},
{id: "1", text: "Email"},
{id: "2", text: "Fax"}]}"
/>
### Initial selected items
To select (or bind) items, pass an array of item ids to `selectedIds`.
@ -93,13 +103,7 @@ Set `direction` to `"top"` for the dropdown menu to appear above the input.
{id: "2", text: "Fax"}]}"
/>
### Filterable
<MultiSelect filterable titleText="Contact" placeholder="Filter contact methods..."
items="{[{id: "0", text: "Slack"},
{id: "1", text: "Email"},
{id: "2", text: "Fax"}]}"
/>
### Invalid state

View file

@ -27,10 +27,6 @@ components: ["NumberInput", "NumberInputSkeleton"]
<NumberInput light label="Clusters" />
### Mobile variant
<NumberInput mobile label="Clusters" />
### Extra-large size
<NumberInput size="xl" label="Clusters" />

View file

@ -7,6 +7,12 @@
<PasswordInput labelText="Password" placeholder="Enter password..." />
### Custom tooltip alignment
Customize the tooltip alignment and position of the visibility toggle through the `tooltipAlignment` and `tooltipPosition` props.
<PasswordInput tooltipAlignment="start" tooltipPosition="left" labelText="Password" placeholder="Enter password..." />
### Password is visible
Set prop `type` to `"text"` to toggle password visibility.

View file

@ -3,19 +3,43 @@ components: ["RadioButtonGroup", "RadioButton", "RadioButtonSkeleton"]
---
<script>
import { FormGroup, RadioButton, RadioButtonSkeleton, RadioButtonGroup } from "carbon-components-svelte";
import { RadioButton, RadioButtonSkeleton, RadioButtonGroup, Tooltip } from "carbon-components-svelte";
import Preview from "../../components/Preview.svelte";
</script>
### Default
<FormGroup legendText="Storage tier (disk)">
<RadioButtonGroup selected="standard">
<RadioButton labelText="Free (1 GB)" value="free" />
<RadioButton labelText="Standard (10 GB)" value="standard" />
<RadioButton labelText="Pro (128 GB)" value="pro" />
</RadioButtonGroup>
</FormGroup>
### With legend text
<RadioButtonGroup legendText="Storage tier (disk)" selected="standard">
<RadioButton labelText="Free (1 GB)" value="free" />
<RadioButton labelText="Standard (10 GB)" value="standard" />
<RadioButton labelText="Pro (128 GB)" value="pro" />
</RadioButtonGroup>
### Legend text slot
Use the named "legendText" slot to customize the legend text.
<RadioButtonGroup selected="standard">
<div slot="legendText" style="display: flex">
Storage tier (disk)
<Tooltip tooltipBodyId="tooltip-body">
<p id="tooltip-body">
Storage tiers may vary based on geolocation.
</p>
</Tooltip>
</div>
<RadioButton labelText="Free (1 GB)" value="free" />
<RadioButton labelText="Standard (10 GB)" value="standard" />
<RadioButton labelText="Pro (128 GB)" value="pro" />
</RadioButtonGroup>
### Programmatic usage
@ -25,40 +49,32 @@ Bind the selected value using the `selected` prop.
### Label text aligned left
<FormGroup legendText="Storage tier (disk)">
<RadioButtonGroup labelPosition="left" selected="standard">
<RadioButtonGroup labelPosition="left" legendText="Storage tier (disk)" selected="standard">
<RadioButton labelText="Free (1 GB)" value="free" />
<RadioButton labelText="Standard (10 GB)" value="standard" />
<RadioButton labelText="Pro (128 GB)" value="pro" />
</RadioButtonGroup>
</FormGroup>
### Vertical orientation
<FormGroup legendText="Storage tier (disk)">
<RadioButtonGroup orientation="vertical" selected="standard">
<RadioButtonGroup orientation="vertical" legendText="Storage tier (disk)" selected="standard">
<RadioButton labelText="Free (1 GB)" value="free" />
<RadioButton labelText="Standard (10 GB)" value="standard" />
<RadioButton labelText="Pro (128 GB)" value="pro" />
</RadioButtonGroup>
</FormGroup>
### Skeleton
<FormGroup legendText="Storage tier (disk)">
<RadioButtonGroup>
<RadioButtonGroup legendText="Storage tier (disk)">
<RadioButtonSkeleton />
<RadioButtonSkeleton />
<RadioButtonSkeleton />
</RadioButtonGroup>
</FormGroup>
### Skeleton (vertical orientation)
<FormGroup legendText="Storage tier (disk)">
<RadioButtonGroup orientation="vertical">
<RadioButtonGroup orientation="vertical" legendText="Storage tier (disk)">
<RadioButtonSkeleton />
<RadioButtonSkeleton />
<RadioButtonSkeleton />
</RadioButtonGroup>
</FormGroup>

View file

@ -17,6 +17,12 @@ The `Search` component size is extra-large by default. There are [large](#large-
<FileSource src="/framed/Search/SearchReactive" />
### on:clear
The "clear" event is dispatched when clicking the "X" button in the search input element.
<Search value="Cloud functions" on:clear={() => console.log('clear')}/>
### Light variant
<Search light />

View file

@ -1,7 +1,6 @@
<script>
import { Tag } from "carbon-components-svelte";
import IbmCloud16 from "carbon-icons-svelte/lib/IbmCloud16";
import Document16 from "carbon-icons-svelte/lib/Document16";
import Preview from "../../components/Preview.svelte";
</script>
@ -31,6 +30,10 @@
<Tag filter on:close>carbon-components</Tag>
### Filterable (disabled)
<Tag filter disabled on:close>carbon-components</Tag>
### Filterable (small)
<Tag size="sm" filter on:close>carbon-components</Tag>
@ -41,6 +44,13 @@ Note: rendering a custom icon cannnot be used with the filterable variant.
<Tag icon={IbmCloud16}>IBM Cloud</Tag>
### Interactive variant
Set `interactive` to `true` to render a `button` element instead of a `div`.
<Tag interactive>Machine learning</Tag>
<Tag interactive disabled>Machine learning</Tag>
### Skeleton
<Tag skeleton />

View file

@ -7,7 +7,7 @@ components: ["ToggleSmall", "ToggleSmallSkeleton"]
import Preview from "../../components/Preview.svelte";
</script>
<InlineNotification svx-ignore title="Deprecation warning:" kind="warning" hideCloseButton>
<InlineNotification svx-ignore title="Deprecation warning" kind="warning" hideCloseButton>
<div>
This component will be removed in the next major release. Use the <Link href="/components/Toggle#small-size">Toggle small variant</Link> instead.
</div>

View file

@ -4,7 +4,9 @@
import Preview from "../../components/Preview.svelte";
</script>
### Default (icon-only, "bottom" direction)
### Default
By default, the tooltip is triggered by an information icon.
<Tooltip tooltipBodyId="tooltip-body">
<p id="tooltip-body">

View file

@ -0,0 +1,30 @@
<script>
import { Button } from "carbon-components-svelte";
import TextBold16 from "carbon-icons-svelte/lib/TextBold16";
import TextItalic16 from "carbon-icons-svelte/lib/TextItalic16";
import TextUnderline16 from "carbon-icons-svelte/lib/TextUnderline16";
let index = 1;
</script>
<Button
isSelected="{index === 0}"
kind="ghost"
iconDescription="Bold"
icon="{TextBold16}"
on:click="{() => (index = 0)}"
/>
<Button
isSelected="{index === 1}"
kind="ghost"
iconDescription="Italicize"
icon="{TextItalic16}"
on:click="{() => (index = 1)}"
/>
<Button
isSelected="{index === 2}"
kind="ghost"
iconDescription="Underline"
icon="{TextUnderline16}"
on:click="{() => (index = 2)}"
/>

View file

@ -0,0 +1,26 @@
<script>
import { ImageLoader, Button } from "carbon-components-svelte";
const src =
"https://upload.wikimedia.org/wikipedia/commons/5/51/IBM_logo.svg";
const srcError = src + "1";
let imageLoader;
let error;
</script>
<Button
kind="ghost"
disabled="{!imageLoader || error}"
on:click="{() => imageLoader.loadImage(srcError)}"
>
Simulate error
</Button>
<ImageLoader bind:this="{imageLoader}" bind:error fadeIn src="{src}">
<div slot="error">
<Button kind="ghost" on:click="{() => imageLoader.loadImage(src)}">
Error. Try again
</Button>
</div>
</ImageLoader>

View file

@ -0,0 +1,29 @@
<script>
import { LocalStorage, Toggle, Button } from "carbon-components-svelte";
let storage;
let toggled = false;
let events = [];
$: document.documentElement.setAttribute("theme", toggled ? "g100" : "white");
</script>
<LocalStorage
bind:this="{storage}"
key="dark-mode"
bind:value="{toggled}"
on:save="{() => {
events = [...events, { event: 'on:save' }];
}}"
on:update="{({ detail }) => {
events = [...events, { event: 'on:update', detail }];
}}"
/>
<Toggle size="sm" labelText="Dark mode" bind:toggled />
<br />
<pre>
{JSON.stringify(events, null, 2)}
</pre>

View file

@ -2,7 +2,6 @@
import {
ButtonSet,
Button,
FormGroup,
RadioButtonGroup,
RadioButton,
} from "carbon-components-svelte";
@ -10,17 +9,17 @@
let plan = "standard";
</script>
<FormGroup legendText="Storage tier (disk)">
<RadioButtonGroup bind:selected="{plan}">
<RadioButtonGroup legendText="Storage tier (disk)" bind:selected="{plan}">
<RadioButton labelText="Free (1 GB)" value="free" />
<RadioButton labelText="Standard (10 GB)" value="standard" />
<RadioButton labelText="Pro (128 GB)" value="pro" />
</RadioButtonGroup>
</FormGroup>
<ButtonSet>
<ButtonSet style="margin-top: var(--cds-layout-03)">
{#each ["free", "standard", "pro"] as value}
<Button
disabled="{plan === value}"
kind="secondary"
on:click="{() => {
plan = value;
}}"

View file

@ -837,15 +837,15 @@ caniuse-lite@^1.0.30001173, caniuse-lite@^1.0.30001178:
integrity sha512-n8JVqXuZMVSPKiPiypjFtDTXc4jWIdjxull0f92WLo7e1MSi3uJ3NvveakSh/aCl1QKFAvIz3vIj0v+0K+FrXw==
carbon-components-svelte@../:
version "0.28.0"
version "0.29.2"
dependencies:
carbon-icons-svelte "^10.21.0"
flatpickr "4.6.9"
carbon-components@10.29.0:
version "10.29.0"
resolved "https://registry.yarnpkg.com/carbon-components/-/carbon-components-10.29.0.tgz#9fd31f1a5cce4cb59a7196222e524d8442fd9026"
integrity sha512-y7BPEfwWxE1URTjrtHz4+rYQwB0u/e7WptlbTH2Lb/iqRYCe6T94u9EVZuq0ZZTpRUNRckbI1irt0AV3J/qlcA==
carbon-components@10.30.0:
version "10.30.0"
resolved "https://registry.yarnpkg.com/carbon-components/-/carbon-components-10.30.0.tgz#c572620361ffdc8f4f67ed84b19ca2e29a912330"
integrity sha512-pHnrPcICl7L8vUHEXks4ZfAtyaGIP01aX7O/szg45/7Po2pQ3hXW1TBppYaUsw3UD+qGOF/CW7ID9Op6IQK4dA==
dependencies:
"@carbon/telemetry" "0.0.0-alpha.6"
flatpickr "4.6.1"

View file

@ -31,7 +31,7 @@
"@rollup/plugin-node-resolve": "^11.1.1",
"@tsconfig/svelte": "^1.0.10",
"autoprefixer": "^10.2.4",
"carbon-components": "10.29.0",
"carbon-components": "10.30.0",
"gh-pages": "^3.1.0",
"husky": "^4.3.8",
"lint-staged": "^10.5.3",

View file

@ -17,6 +17,11 @@
*/
export let size = "default";
/**
* Set to `true` to enable the selected state for an icon-only, ghost button
*/
export let isSelected = false;
/**
* Set to `true` for the icon-only variant
* @deprecated inferred using the $$slots API
@ -85,11 +90,11 @@
}
$: hasIconOnly = icon && !$$slots.default;
$: buttonProps = {
role: "button",
type: href && !disabled ? undefined : type,
tabindex,
disabled,
href,
"aria-pressed": hasIconOnly && kind === "ghost" ? isSelected : undefined,
...$$restProps,
class: [
"bx--btn",
@ -104,6 +109,7 @@
hasIconOnly &&
tooltipAlignment &&
`bx--tooltip--align-${tooltipAlignment}`,
hasIconOnly && isSelected && kind === "ghost" && "bx--btn--selected",
$$restProps.class,
]
.filter(Boolean)

View file

@ -160,7 +160,7 @@
}
}}" />
<div class:bx--list-box__wrapper="{true}" {...$$restProps}>
<div class:bx--list-box__wrapper="{true}">
{#if titleText}
<label
for="{id}"
@ -209,6 +209,11 @@
aria-disabled="{disabled}"
aria-controls="{open ? menuId : undefined}"
aria-owns="{open ? menuId : undefined}"
disabled="{disabled}"
placeholder="{placeholder}"
id="{id}"
value="{inputValue}"
{...$$restProps}
class:bx--text-input="{true}"
class:bx--text-input--light="{light}"
class:bx--text-input--empty="{inputValue === ''}"
@ -246,10 +251,6 @@
ref.focus();
}
}}"
disabled="{disabled}"
placeholder="{placeholder}"
id="{id}"
value="{inputValue}"
/>
{#if invalid}
<WarningFilled16 class="bx--list-box__invalid-icon" />

View file

@ -51,6 +51,7 @@
{...$$restProps}
bind:ref
bind:value
on:clear
on:change
on:input
on:focus

View file

@ -77,7 +77,6 @@
<div
class:bx--date-picker-container="{true}"
class:bx--date-picker--nolabel="{!labelText}"
{...$$restProps}
>
{#if labelText}
<label
@ -97,13 +96,14 @@
<input
bind:this="{ref}"
data-invalid="{invalid || undefined}"
value="{!$range ? $inputValue : undefined}"
id="{id}"
name="{name}"
placeholder="{placeholder}"
type="{type}"
pattern="{pattern}"
disabled="{disabled}"
{...$$restProps}
value="{!$range ? $inputValue : undefined}"
class:bx--date-picker__input="{true}"
class:bx--date-picker__input--invalid="{invalid}"
class="{size && `bx--date-picker__input--${size}`}"

View file

@ -1,4 +1,10 @@
<script>
/**
* @deprecated
* This component will be removed in version 1.0.0.
* Use icons from "carbon-icons-svelte" instead
*/
/**
* @extends {"./IconSkeleton"} IconSkeletonProps
* @restProps {svg}

View file

@ -1,4 +1,9 @@
<script>
/**
* @deprecated
* This component will be removed in version 1.0.0.
*/
/** Set the size of the icon */
export let size = 16;
</script>

View file

@ -0,0 +1,113 @@
<script>
/**
* @event {any} load
* @event {any} error
*/
/**
* Specify the image source
*/
export let src = "";
/**
* Specify the image alt text
*/
export let alt = "";
/**
* Specify the aspect ratio for the image wrapper
* @type {"2x1" | "16x9" | "4x3" | "1x1" | "3x4" | "9x16" | "1x2"}
*/
export let ratio = undefined;
/**
* Set to `true` when `loaded` is `true` and `error` is false
*/
export let loading = false;
/**
* Set to `true` when the image is loaded
*/
export let loaded = false;
/**
* Set to `true` if an error occurs when loading the image
*/
export let error = false;
/**
* Set to `true` to fade in the image on load
* The duration uses the `fast-02` value following Carbon guidelines on motion
*/
export let fadeIn = false;
/**
* Method invoked to load the image provided a `src` value
* @type {(url?: string) => void}
*/
export const loadImage = (url) => {
if (image != null) image = null;
loaded = false;
error = false;
image = new Image();
image.src = url || src;
image.onload = () => (loaded = true);
image.onerror = () => (error = true);
};
import { onMount, createEventDispatcher } from "svelte";
import { fade } from "svelte/transition";
import AspectRatio from "../AspectRatio/AspectRatio.svelte";
const dispatch = createEventDispatcher();
// "fast-02" duration (ms) from Carbon motion recommended for fading micro-interactions
const fast02 = 110;
let image = null;
$: loading = !loaded && !error;
$: if (src) loadImage();
$: if (loaded) dispatch("load");
$: if (error) dispatch("error");
onMount(() => {
return () => (image = null);
});
</script>
{#if ratio === undefined}
{#if loading}
<slot name="loading" />
{/if}
{#if loaded}
<img
{...$$restProps}
style="width: 100%;{$$restProps.style}"
src="{src}"
alt="{alt}"
transition:fade="{{ duration: fadeIn ? fast02 : 0 }}"
/>
{/if}
{#if error}
<slot name="error" />
{/if}
{:else}
<AspectRatio ratio="{ratio}">
{#if loading}
<slot name="loading" />
{/if}
{#if loaded}
<img
{...$$restProps}
style="width: 100%;{$$restProps.style}"
src="{src}"
alt="{alt}"
transition:fade="{{ duration: fadeIn ? fast02 : 0 }}"
/>
{/if}
{#if error}
<slot name="error" />
{/if}
</AspectRatio>
{/if}

1
src/ImageLoader/index.js Normal file
View file

@ -0,0 +1 @@
export { default as ImageLoader } from "./ImageLoader.svelte";

View file

@ -30,6 +30,7 @@
class:bx--list-box__menu-icon--open="{open}"
{...$$restProps}
on:click|preventDefault
style="top: 0; bottom: 0; margin: auto;"
>
<ChevronDown16 aria-label="{description}" title="{description}" />
</div>

View file

@ -5,7 +5,7 @@
/**
* Specify the number of selected items
* @type {any}
* @type {number}
*/
export let selectionCount = undefined;
@ -46,12 +46,45 @@
: translateWithId("clearSelection");
</script>
{#if selectionCount !== undefined}
<div
class:bx--tag="{true}"
class:bx--tag--filter="{true}"
class:bx--tag--high-contrast="{true}"
class:bx--tag--disabled="{disabled}"
>
<span class:bx--tag__label="{true}" title="{selectionCount}">
{selectionCount}
</span>
<div
bind:this="{ref}"
role="button"
aria-label="Clear Selection"
tabindex="{disabled ? '-1' : '0'}"
tabIndex="{disabled ? -1 : 0}"
class:bx--tag__close-icon="{true}"
on:click|preventDefault|stopPropagation="{(e) => {
if (!disabled) {
dispatch('clear', e);
}
}}"
on:keydown|stopPropagation="{(e) => {
if (!disabled && e.key === 'Enter') {
dispatch('clear', e);
}
}}"
disabled="{disabled}"
aria-label="{translationIds.clearAll}"
title="{description}"
>
<Close16 />
</div>
</div>
{:else}
<div
bind:this="{ref}"
role="button"
aria-label="{description}"
title="{description}"
tabindex="{disabled ? '-1' : '0'}"
class:bx--list-box__selection="{true}"
class:bx--tag--filter="{selectionCount}"
class:bx--list-box__selection--multi="{selectionCount}"
@ -67,6 +100,7 @@
}
}}"
>
{#if selectionCount}{selectionCount}{/if}
{#if selectionCount !== undefined}{selectionCount}{/if}
<Close16 />
</div>
{/if}

View file

@ -0,0 +1,55 @@
<script>
/**
* @event {any} save
* @event {{ prevValue: any; value: any; }} update
*/
/**
* Specify the local storage key
*/
export let key = "local-storage-key";
/**
* Provide a value to persist
* @type {any}
*/
export let value = "";
import { onMount, afterUpdate, createEventDispatcher } from "svelte";
const dispatch = createEventDispatcher();
let prevValue = value;
function setItem() {
if (typeof value === "object") {
localStorage.setItem(key, JSON.stringify(value));
} else {
localStorage.setItem(key, value);
}
}
onMount(() => {
const item = localStorage.getItem(key);
if (item != null) {
try {
value = JSON.parse(item);
} catch (e) {
value = item;
}
} else {
setItem(value);
dispatch("save");
}
});
afterUpdate(() => {
if (prevValue !== value) {
setItem(value);
dispatch("update", { prevValue, value });
}
prevValue = value;
});
</script>

View file

@ -0,0 +1 @@
export { default as LocalStorage } from "./LocalStorage.svelte";

View file

@ -121,6 +121,7 @@
* @typedef {string} MultiSelectItemId
* @typedef {string} MultiSelectItemText
* @typedef {{ id: MultiSelectItemId; text: MultiSelectItemText; }} MultiSelectItem
* @event {{ selectedIds: string[]; selected: MultiSelectItem[]; unselected: MultiSelectItem[]; }} select
*/
import { afterUpdate, createEventDispatcher, setContext } from "svelte";
@ -236,7 +237,6 @@
class:bx--multi-select__wrapper--inline="{inline}"
class:bx--list-box__wrapper--inline="{inline}"
class:bx--multi-select__wrapper--inline--invalid="{inline && invalid}"
{...$$restProps}
>
{#if titleText}
<label
@ -347,6 +347,7 @@
{#if filterable}
<input
bind:this="{inputRef}"
{...$$restProps}
role="combobox"
tabindex="0"
autocomplete="off"

View file

@ -37,7 +37,10 @@
/** Set to `true` for the input to be read-only */
export let readonly = false;
/** Set to `true` to enable the mobile variant */
/**
* Set to `true` to enable the mobile variant
* @deprecated
*/
export let mobile = false;
/** Set to `true` to allow for an empty value */
@ -141,7 +144,6 @@
<div
class:bx--form-item="{true}"
{...$$restProps}
on:click
on:mouseover
on:mouseenter
@ -192,10 +194,6 @@
type="number"
pattern="[0-9]*"
aria-label="{label ? undefined : ariaLabel}"
on:input
on:input="{({ target }) => {
inputValue = target.value;
}}"
disabled="{disabled}"
id="{id}"
name="{name}"
@ -204,6 +202,11 @@
step="{step}"
value="{value}"
readonly="{readonly}"
{...$$restProps}
on:input
on:input="{({ target }) => {
inputValue = target.value;
}}"
/>
<button
type="button"
@ -244,10 +247,6 @@
data-invalid="{invalid || undefined}"
aria-invalid="{invalid || undefined}"
aria-label="{label ? undefined : ariaLabel}"
on:input
on:input="{({ target }) => {
inputValue = target.value;
}}"
disabled="{disabled}"
id="{id}"
max="{max}"
@ -255,6 +254,11 @@
step="{step}"
value="{value}"
readonly="{readonly}"
{...$$restProps}
on:input
on:input="{({ target }) => {
inputValue = target.value;
}}"
/>
{#if invalid}
<WarningFilled16 class="bx--number__invalid" />

View file

@ -67,6 +67,8 @@
/>
<label class:bx--radio-button__label="{true}" for="{id}">
<span class:bx--radio-button__appearance="{true}"></span>
{#if labelText}
<span class:bx--visually-hidden="{hideLabel}">{labelText}</span>
{/if}
</label>
</div>

View file

@ -8,6 +8,9 @@
/** Set to `true` to disable the radio buttons */
export let disabled = false;
/** Specify the legend text */
export let legendText = "";
/**
* Specify the label position
* @type {"right" | "left"}
@ -72,12 +75,18 @@
on:mouseenter
on:mouseleave
>
<div
<fieldset
class:bx--radio-button-group="{true}"
class:bx--radio-button-group--vertical="{orientation === 'vertical'}"
class="{labelPosition && `bx--radio-button-group--label-${labelPosition}`}"
class:bx--radio-button-group--label-left="{labelPosition === 'left'}"
class:bx--radio-button-group--label-right="{labelPosition === 'right'}"
disabled="{disabled}"
>
{#if legendText || $$slots.legendText}
<legend class:bx--label="{true}">
<slot name="legendText">{legendText}</slot>
</legend>
{/if}
<slot />
</div>
</fieldset>
</div>

View file

@ -98,7 +98,6 @@
class:bx--search--sm="{size === 'sm' || small}"
class:bx--search--lg="{size === 'lg'}"
class:bx--search--xl="{size === 'xl'}"
{...$$restProps}
>
<Search16 class="bx--search-magnifier" />
<label id="{id}-search" for="{id}" class:bx--label="{true}"
@ -116,7 +115,7 @@
placeholder="{placeholder}"
type="{type}"
value="{value}"
aria-hidden="{$$props['aria-hidden']}"
{...$$restProps}
on:change
on:input
on:input="{({ target }) => {

View file

@ -16,6 +16,9 @@
/** Set to `true` to disable a filterable tag */
export let disabled = false;
/** Set to `true` to render a `button` element instead of a `div` */
export let interactive = false;
/** Set to `true` to display the skeleton state */
export let skeleton = false;
@ -31,11 +34,10 @@
/** Set an id for the filterable tag */
export let id = "ccs-" + Math.random().toString(36);
import { createEventDispatcher } from "svelte";
import Close16 from "carbon-icons-svelte/lib/Close16/Close16.svelte";
import TagSkeleton from "./TagSkeleton.svelte";
import { createEventDispatcher } from "svelte";
const dispatch = createEventDispatcher();
</script>
@ -88,6 +90,42 @@
<Close16 />
</button>
</div>
{:else if interactive}
<button
id="{id}"
disabled="{disabled}"
aria-disabled="{disabled}"
tabindex="{disabled ? '-1' : undefined}"
class:bx--tag="{true}"
class:bx--tag--interactive="{true}"
class:bx--tag--disabled="{disabled}"
class:bx--tag--sm="{size === 'sm'}"
class:bx--tag--red="{type === 'red'}"
class:bx--tag--magenta="{type === 'magenta'}"
class:bx--tag--purple="{type === 'purple'}"
class:bx--tag--blue="{type === 'blue'}"
class:bx--tag--cyan="{type === 'cyan'}"
class:bx--tag--teal="{type === 'teal'}"
class:bx--tag--green="{type === 'green'}"
class:bx--tag--gray="{type === 'gray'}"
class:bx--tag--cool-gray="{type === 'cool-gray'}"
class:bx--tag--warm-gray="{type === 'warm-gray'}"
class:bx--tag--high-contrast="{type === 'high-contrast'}"
{...$$restProps}
on:click
on:mouseover
on:mouseenter
on:mouseleave
>
{#if icon}
<div class:bx--tag__custom-icon="{true}">
<svelte:component this="{icon}" />
</div>
{/if}
<span>
<slot />
</span>
</button>
{:else}
<div
id="{id}"

View file

@ -14,5 +14,5 @@
{#if !hideLabel}
<span class:bx--label="{true}" class:bx--skeleton="{true}"></span>
{/if}
<div class:bx--skeleton="{true}" class:bx--text-area="{true}"></div>
<div class:bx--skeleton="{true}" class:bx--text-input="{true}"></div>
</div>

View file

@ -59,7 +59,6 @@
<div
class:bx--form-item="{true}"
{...$$restProps}
on:click
on:mouseover
on:mouseenter
@ -94,6 +93,7 @@
type="{type}"
value="{value}"
disabled="{disabled}"
{...$$restProps}
class:bx--time-picker__input-field="{true}"
class:bx--text-input="{true}"
class:bx--text-input--light="{light}"

View file

@ -171,7 +171,10 @@
}
}}" />
<div {...$$restProps} style="{$$restProps.style}; position: relative;">
<div
{...$$restProps}
style="{open ? 'z-index: 1;' : ''}{$$restProps.style}; position: relative;"
>
{#if !hideIcon}
<div bind:this="{ref}" id="{triggerId}" class:bx--tooltip__label="{true}">
<slot name="triggerText">{triggerText}</slot>

View file

@ -30,6 +30,7 @@
></div>
{/if}
<nav
aria-hidden="{!isOpen}"
aria-label="{ariaLabel}"
class:bx--side-nav__navigation="{true}"
class:bx--side-nav="{true}"

View file

@ -30,6 +30,6 @@
{...$$restProps}
on:click
>
<span class:bx--side-nav__link-text="{true}">{text}</span>
<span class:bx--side-nav__link-text="{true}"><slot>{text}</slot></span>
</a>
</li>

View file

@ -48,6 +48,7 @@ export { FormItem } from "./FormItem";
export { FormLabel } from "./FormLabel";
export { Grid, Row, Column } from "./Grid";
export { Icon, IconSkeleton } from "./Icon";
export { ImageLoader } from "./ImageLoader";
export { InlineLoading } from "./InlineLoading";
export { Link, OutboundLink } from "./Link";
export {
@ -60,6 +61,7 @@ export {
} from "./ListBox";
export { ListItem } from "./ListItem";
export { Loading } from "./Loading";
export { LocalStorage } from "./LocalStorage";
export { MultiSelect } from "./MultiSelect";
export { Modal } from "./Modal";
export {

View file

@ -0,0 +1,18 @@
<script lang="ts">
import { ImageLoader } from "../types";
let loading = false;
let loaded = false;
let error = false;
</script>
<ImageLoader
bind:loading
bind:loaded
bind:error
fadeIn
ratio="16x9"
src=""
on:load="{() => {}}"
on:error="{() => {}}"
/>

View file

@ -0,0 +1,19 @@
<script lang="ts">
import { LocalStorage } from "../types";
let storage;
let toggled = false;
let events = [];
</script>
<LocalStorage
bind:this="{storage}"
key="dark-mode"
bind:value="{toggled}"
on:save="{() => {
events = [...events, { event: 'on:save' }];
}}"
on:update="{({ detail }) => {
events = [...events, { event: 'on:update', detail }];
}}"
/>

View file

@ -11,6 +11,11 @@
{ id: '1', text: 'Email' },
{ id: '2', text: 'Fax' },
]}"
on:select="{(e) => {
console.log(e.detail.selectedIds);
console.log(e.detail.selected);
console.log(e.detail.unselected);
}}"
/>
<MultiSelect

View file

@ -1,48 +1,25 @@
<script lang="ts">
import {
FormGroup,
RadioButton,
RadioButtonSkeleton,
RadioButtonGroup,
} from "../types";
import { RadioButton, RadioButtonSkeleton, RadioButtonGroup } from "../types";
</script>
<FormGroup legendText="Storage tier (disk)">
<RadioButtonGroup selected="standard">
<RadioButtonGroup legendText="Storage tier (disk)" selected="standard">
<RadioButton labelText="Free (1 GB)" value="free" />
<RadioButton labelText="Standard (10 GB)" value="standard" />
<RadioButton labelText="Pro (128 GB)" value="pro" />
</RadioButtonGroup>
</FormGroup>
<FormGroup legendText="Storage tier (disk)">
<RadioButtonGroup labelPosition="left" selected="standard">
<RadioButtonGroup
legendText="Storage tier (disk)"
labelPosition="left"
selected="standard"
>
<RadioButton labelText="Free (1 GB)" value="free" />
<RadioButton labelText="Standard (10 GB)" value="standard" />
<RadioButton labelText="Pro (128 GB)" value="pro" />
</RadioButtonGroup>
</FormGroup>
<FormGroup legendText="Storage tier (disk)">
<RadioButtonGroup orientation="vertical" selected="standard">
<RadioButton labelText="Free (1 GB)" value="free" />
<RadioButton labelText="Standard (10 GB)" value="standard" />
<RadioButton labelText="Pro (128 GB)" value="pro" />
</RadioButtonGroup>
</FormGroup>
<FormGroup legendText="Storage tier (disk)">
<RadioButtonGroup>
<RadioButtonGroup orientation="vertical" legendText="Storage tier (disk)">
<RadioButtonSkeleton />
<RadioButtonSkeleton />
<RadioButtonSkeleton />
</RadioButtonGroup>
</FormGroup>
<FormGroup legendText="Storage tier (disk)">
<RadioButtonGroup orientation="vertical">
<RadioButtonSkeleton />
<RadioButtonSkeleton />
<RadioButtonSkeleton />
</RadioButtonGroup>
</FormGroup>

View file

@ -31,4 +31,6 @@
<Tag icon="{Add16}">Custom icon</Tag>
<Tag interactive>Text</Tag>
<Tag skeleton />

View file

@ -2,7 +2,7 @@
import { TimePicker, TimePickerSelect, SelectItem } from "../types";
</script>
<TimePicker labelText="Cron job" placeholder="hh:mm">
<TimePicker spellcheck="{false}" labelText="Cron job" placeholder="hh:mm">
<TimePickerSelect value="PM">
<SelectItem value="am" text="AM" />
<SelectItem value="pm" text="PM" />

View file

@ -26,6 +26,12 @@ export interface ButtonProps
*/
size?: "default" | "field" | "small";
/**
* Set to `true` to enable the selected state for an icon-only, ghost button
* @default false
*/
isSelected?: boolean;
/**
* Set to `true` for the icon-only variant
* @default false

View file

@ -7,7 +7,7 @@ export interface ComboBoxItem {
}
export interface ComboBoxProps
extends svelte.JSX.HTMLAttributes<HTMLElementTagNameMap["div"]> {
extends svelte.JSX.HTMLAttributes<HTMLElementTagNameMap["input"]> {
/**
* Set the combobox items
* @default []

View file

@ -42,6 +42,7 @@ export interface ToolbarSearchProps {
export default class ToolbarSearch extends SvelteComponentTyped<
ToolbarSearchProps,
{
clear: WindowEventMap["clear"];
change: WindowEventMap["change"];
input: WindowEventMap["input"];
focus: WindowEventMap["focus"];

View file

@ -2,7 +2,7 @@
import { SvelteComponentTyped } from "svelte";
export interface DatePickerInputProps
extends svelte.JSX.HTMLAttributes<HTMLElementTagNameMap["div"]> {
extends svelte.JSX.HTMLAttributes<HTMLElementTagNameMap["input"]> {
/**
* Set the size of the input
*/

60
types/ImageLoader/ImageLoader.d.ts vendored Normal file
View file

@ -0,0 +1,60 @@
/// <reference types="svelte" />
import { SvelteComponentTyped } from "svelte";
export interface ImageLoaderProps
extends svelte.JSX.HTMLAttributes<HTMLElementTagNameMap["img"]> {
/**
* Specify the image source
* @default ""
*/
src?: string;
/**
* Specify the image alt text
* @default ""
*/
alt?: string;
/**
* Specify the aspect ratio for the image wrapper
*/
ratio?: "2x1" | "16x9" | "4x3" | "1x1" | "3x4" | "9x16" | "1x2";
/**
* Set to `true` when `loaded` is `true` and `error` is false
* @default false
*/
loading?: boolean;
/**
* Set to `true` when the image is loaded
* @default false
*/
loaded?: boolean;
/**
* Set to `true` if an error occurs when loading the image
* @default false
*/
error?: boolean;
/**
* Set to `true` to fade in the image on load
* The duration uses the `fast-02` value following Carbon guidelines on motion
* @default false
*/
fadeIn?: boolean;
/**
* Method invoked to load the image provided a `src` value
* @constant
* @default (url) => { if (image != null) image = null; loaded = false; error = false; image = new Image(); image.src = url || src; image.onload = () => (loaded = true); image.onerror = () => (error = true); }
*/
loadImage?: (url?: string) => void;
}
export default class ImageLoader extends SvelteComponentTyped<
ImageLoaderProps,
{ load: CustomEvent<any>; error: CustomEvent<any> },
{ error: {}; loading: {} }
> {}

View file

@ -8,7 +8,7 @@ export interface ListBoxSelectionProps
/**
* Specify the number of selected items
*/
selectionCount?: any;
selectionCount?: number;
/**
* Set to `true` to disable the list box selection

25
types/LocalStorage/LocalStorage.d.ts vendored Normal file
View file

@ -0,0 +1,25 @@
/// <reference types="svelte" />
import { SvelteComponentTyped } from "svelte";
export interface LocalStorageProps {
/**
* Specify the local storage key
* @default "local-storage-key"
*/
key?: string;
/**
* Provide a value to persist
* @default ""
*/
value?: any;
}
export default class LocalStorage extends SvelteComponentTyped<
LocalStorageProps,
{
save: CustomEvent<any>;
update: CustomEvent<{ prevValue: any; value: any }>;
},
{}
> {}

View file

@ -11,7 +11,7 @@ export interface MultiSelectItem {
}
export interface MultiSelectProps
extends svelte.JSX.HTMLAttributes<HTMLElementTagNameMap["div"]> {
extends svelte.JSX.HTMLAttributes<HTMLElementTagNameMap["input"]> {
/**
* Set the multiselect items
* @default []
@ -179,11 +179,15 @@ export interface MultiSelectProps
export default class MultiSelect extends SvelteComponentTyped<
MultiSelectProps,
{
select: CustomEvent<{
selectedIds: string[];
selected: MultiSelectItem[];
unselected: MultiSelectItem[];
}>;
clear: WindowEventMap["clear"];
keydown: WindowEventMap["keydown"];
focus: WindowEventMap["focus"];
blur: WindowEventMap["blur"];
select: CustomEvent<any>;
},
{}
> {}

View file

@ -4,7 +4,7 @@ import { SvelteComponentTyped } from "svelte";
export type NumberInputTranslationId = "increment" | "decrement";
export interface NumberInputProps
extends svelte.JSX.HTMLAttributes<HTMLElementTagNameMap["div"]> {
extends svelte.JSX.HTMLAttributes<HTMLElementTagNameMap["input"]> {
/**
* Set the size of the input
*/

View file

@ -14,6 +14,12 @@ export interface RadioButtonGroupProps
*/
disabled?: boolean;
/**
* Specify the legend text
* @default ""
*/
legendText?: string;
/**
* Specify the label position
* @default "right"
@ -41,5 +47,5 @@ export default class RadioButtonGroup extends SvelteComponentTyped<
mouseleave: WindowEventMap["mouseleave"];
change: CustomEvent<any>;
},
{ default: {} }
{ default: {}; legendText: {} }
> {}

6
types/Tag/Tag.d.ts vendored
View file

@ -37,6 +37,12 @@ export interface TagProps
*/
disabled?: boolean;
/**
* Set to `true` to render a `button` element instead of a `div`
* @default false
*/
interactive?: boolean;
/**
* Set to `true` to display the skeleton state
* @default false

View file

@ -2,7 +2,7 @@
import { SvelteComponentTyped } from "svelte";
export interface TimePickerProps
extends svelte.JSX.HTMLAttributes<HTMLElementTagNameMap["div"]> {
extends svelte.JSX.HTMLAttributes<HTMLElementTagNameMap["input"]> {
/**
* Specify the size of the input
*/

View file

@ -28,5 +28,5 @@ export interface SideNavMenuItemProps
export default class SideNavMenuItem extends SvelteComponentTyped<
SideNavMenuItemProps,
{ click: WindowEventMap["click"] },
{}
{ default: {} }
> {}

2
types/index.d.ts vendored
View file

@ -57,6 +57,7 @@ export { default as Row } from "./Grid/Row";
export { default as Column } from "./Grid/Column";
export { default as Icon } from "./Icon/Icon";
export { default as IconSkeleton } from "./Icon/IconSkeleton";
export { default as ImageLoader } from "./ImageLoader/ImageLoader";
export { default as InlineLoading } from "./InlineLoading/InlineLoading";
export { default as Link } from "./Link/Link";
export { default as OutboundLink } from "./Link/OutboundLink";
@ -68,6 +69,7 @@ export { default as ListBoxMenuItem } from "./ListBox/ListBoxMenuItem";
export { default as ListBoxSelection } from "./ListBox/ListBoxSelection";
export { default as ListItem } from "./ListItem/ListItem";
export { default as Loading } from "./Loading/Loading";
export { default as LocalStorage } from "./LocalStorage/LocalStorage";
export { default as MultiSelect } from "./MultiSelect/MultiSelect";
export { default as Modal } from "./Modal/Modal";
export { default as ToastNotification } from "./Notification/ToastNotification";

View file

@ -453,10 +453,10 @@ caniuse-lite@^1.0.30001181:
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001183.tgz#7a57ba9d6584119bb5f2bc76d3cc47ba9356b3e2"
integrity sha512-7JkwTEE1hlRKETbCFd8HDZeLiQIUcl8rC6JgNjvHCNaxOeNmQ9V4LvQXRUsKIV2CC73qKxljwVhToaA3kLRqTw==
carbon-components@10.29.0:
version "10.29.0"
resolved "https://registry.yarnpkg.com/carbon-components/-/carbon-components-10.29.0.tgz#9fd31f1a5cce4cb59a7196222e524d8442fd9026"
integrity sha512-y7BPEfwWxE1URTjrtHz4+rYQwB0u/e7WptlbTH2Lb/iqRYCe6T94u9EVZuq0ZZTpRUNRckbI1irt0AV3J/qlcA==
carbon-components@10.30.0:
version "10.30.0"
resolved "https://registry.yarnpkg.com/carbon-components/-/carbon-components-10.30.0.tgz#c572620361ffdc8f4f67ed84b19ca2e29a912330"
integrity sha512-pHnrPcICl7L8vUHEXks4ZfAtyaGIP01aX7O/szg45/7Po2pQ3hXW1TBppYaUsw3UD+qGOF/CW7ID9Op6IQK4dA==
dependencies:
"@carbon/telemetry" "0.0.0-alpha.6"
flatpickr "4.6.1"