Initial commit

This commit is contained in:
davideraccagni 2022-04-14 18:29:54 +02:00
commit db2d2ad69b
23 changed files with 6936 additions and 1158 deletions

View file

@ -1,6 +1,6 @@
# Component Index # Component Index
> 165 components exported from carbon-components-svelte@0.62.3. > 167 components exported from carbon-components-svelte@0.62.4.
## Components ## Components
@ -8,6 +8,8 @@
- [`AccordionItem`](#accordionitem) - [`AccordionItem`](#accordionitem)
- [`AccordionSkeleton`](#accordionskeleton) - [`AccordionSkeleton`](#accordionskeleton)
- [`AspectRatio`](#aspectratio) - [`AspectRatio`](#aspectratio)
- [`AutoComplete`](#autocomplete)
- [`AutoCompleteSkeleton`](#autocompleteskeleton)
- [`Breadcrumb`](#breadcrumb) - [`Breadcrumb`](#breadcrumb)
- [`BreadcrumbItem`](#breadcrumbitem) - [`BreadcrumbItem`](#breadcrumbitem)
- [`BreadcrumbSkeleton`](#breadcrumbskeleton) - [`BreadcrumbSkeleton`](#breadcrumbskeleton)
@ -269,6 +271,86 @@ None.
None. None.
## `AutoComplete`
### Types
```ts
export type AutoCompleteItemId = any;
export type AutoCompleteItemText = string;
export interface AutoCompleteItem {
id: AutoCompleteItemId;
text: AutoCompleteItemText;
}
```
### Props
| Prop name | Kind | Reactive | Type | Default value | Description |
| :------------ | :--------------- | :------- | :---------------------------------------------- | ----------------------------------------------------- | --------------------------------------------- |
| ref | <code>let</code> | Yes | <code>null &#124; HTMLInputElement</code> | <code>null</code> | Obtain a reference to the button HTML element |
| inline | <code>let</code> | Yes | <code>boolean</code> | <code>false</code> | Set to `true` to use the inline variant |
| open | <code>let</code> | Yes | <code>boolean</code> | <code>false</code> | Set to `true` to open the dropdown |
| selectedId | <code>let</code> | Yes | <code>AutoCompleteItemId</code> | <code>undefined</code> | Specify the selected item id |
| filteredItems | <code>let</code> | Yes | <code>[]</code> | <code>[]</code> | -- |
| items | <code>let</code> | No | <code>AutoCompleteItem[]</code> | <code>[]</code> | Set the dropdown items |
| itemToString | <code>let</code> | No | <code>(item: AutoCompleteItem) => string</code> | <code>(item) => item.text &#124;&#124; item.id</code> | Override the display of a dropdown item |
| type | <code>let</code> | No | <code>"default" &#124; "inline"</code> | <code>"default"</code> | Specify the type of dropdown |
| direction | <code>let</code> | No | <code>"bottom" &#124; "top"</code> | <code>"bottom"</code> | Specify the direction of the dropdown menu |
| size | <code>let</code> | No | <code>"sm" &#124; "lg" &#124; "xl"</code> | <code>undefined</code> | Specify the size of the dropdown field |
| light | <code>let</code> | No | <code>boolean</code> | <code>false</code> | Set to `true` to enable the light variant |
| disabled | <code>let</code> | No | <code>boolean</code> | <code>false</code> | Set to `true` to disable the dropdown |
| titleText | <code>let</code> | No | <code>string</code> | <code>""</code> | Specify the title text |
| invalid | <code>let</code> | No | <code>boolean</code> | <code>false</code> | Set to `true` to indicate an invalid state |
| invalidText | <code>let</code> | No | <code>string</code> | <code>""</code> | Specify the invalid state text |
| warn | <code>let</code> | No | <code>boolean</code> | <code>false</code> | Set to `true` to indicate an warning state |
| warnText | <code>let</code> | No | <code>string</code> | <code>""</code> | Specify the warning state text |
| helperText | <code>let</code> | No | <code>string</code> | <code>""</code> | Specify the helper text |
| hideLabel | <code>let</code> | No | <code>boolean</code> | <code>false</code> | Set to `true` to visually hide the label text |
| id | <code>let</code> | No | <code>string</code> | <code>"ccs-" + Math.random().toString(36)</code> | Set an id for the list box component |
| name | <code>let</code> | No | <code>string</code> | <code>undefined</code> | Specify a name attribute for the list box |
| placeholder | <code>let</code> | No | -- | <code>null</code> | ???? |
### Slots
| Slot name | Default | Props | Fallback |
| :-------- | :------ | :------------------------------------------------------- | :-------------------------------- |
| -- | Yes | <code>{ item: AutoCompleteItem; index: number; } </code> | <code>{itemToString(item)}</code> |
### Events
| Event name | Type | Detail |
| :--------- | :--------- | :------------------------------------------------------------------------------ |
| select | dispatched | <code>{ selectedId: AutoCompleteItemId, selectedItem: AutoCompleteItem }</code> |
| change | forwarded | -- |
| focus | forwarded | -- |
| blur | forwarded | -- |
| input | forwarded | -- |
| clear | dispatched | -- |
## `AutoCompleteSkeleton`
### Props
| Prop name | Kind | Reactive | Type | Default value | Description |
| :-------- | :--------------- | :------- | :------------------- | ------------------ | ------------------------------------ |
| hideLabel | <code>let</code> | No | <code>boolean</code> | <code>false</code> | Set to `true` to hide the label text |
### Slots
None.
### Events
| Event name | Type | Detail |
| :--------- | :-------- | :----- |
| click | forwarded | -- |
| mouseover | forwarded | -- |
| mouseenter | forwarded | -- |
| mouseleave | forwarded | -- |
## `Breadcrumb` ## `Breadcrumb`
### Props ### Props

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1,5 +1,5 @@
{ {
"total": 165, "total": 167,
"components": [ "components": [
{ {
"moduleName": "Accordion", "moduleName": "Accordion",
@ -231,6 +231,315 @@
"typedefs": [], "typedefs": [],
"rest_props": { "type": "Element", "name": "div" } "rest_props": { "type": "Element", "name": "div" }
}, },
{
"moduleName": "AutoComplete",
"filePath": "src/AutoComplete/AutoComplete.svelte",
"props": [
{
"name": "items",
"kind": "let",
"description": "Set the dropdown items",
"type": "AutoCompleteItem[]",
"value": "[]",
"isFunction": false,
"isFunctionDeclaration": false,
"constant": false,
"reactive": false
},
{
"name": "filteredItems",
"kind": "let",
"type": "[]",
"value": "[]",
"isFunction": false,
"isFunctionDeclaration": false,
"constant": false,
"reactive": true
},
{
"name": "itemToString",
"kind": "let",
"description": "Override the display of a dropdown item",
"type": "(item: AutoCompleteItem) => string",
"value": "(item) => item.text || item.id",
"isFunction": true,
"isFunctionDeclaration": false,
"constant": false,
"reactive": false
},
{
"name": "selectedId",
"kind": "let",
"description": "Specify the selected item id",
"type": "AutoCompleteItemId",
"isFunction": false,
"isFunctionDeclaration": false,
"constant": false,
"reactive": true
},
{
"name": "type",
"kind": "let",
"description": "Specify the type of dropdown",
"type": "\"default\" | \"inline\"",
"value": "\"default\"",
"isFunction": false,
"isFunctionDeclaration": false,
"constant": false,
"reactive": false
},
{
"name": "direction",
"kind": "let",
"description": "Specify the direction of the dropdown menu",
"type": "\"bottom\" | \"top\"",
"value": "\"bottom\"",
"isFunction": false,
"isFunctionDeclaration": false,
"constant": false,
"reactive": false
},
{
"name": "size",
"kind": "let",
"description": "Specify the size of the dropdown field",
"type": "\"sm\" | \"lg\" | \"xl\"",
"isFunction": false,
"isFunctionDeclaration": false,
"constant": false,
"reactive": false
},
{
"name": "open",
"kind": "let",
"description": "Set to `true` to open the dropdown",
"type": "boolean",
"value": "false",
"isFunction": false,
"isFunctionDeclaration": false,
"constant": false,
"reactive": true
},
{
"name": "inline",
"kind": "let",
"description": "Set to `true` to use the inline variant",
"type": "boolean",
"value": "false",
"isFunction": false,
"isFunctionDeclaration": false,
"constant": false,
"reactive": true
},
{
"name": "light",
"kind": "let",
"description": "Set to `true` to enable the light variant",
"type": "boolean",
"value": "false",
"isFunction": false,
"isFunctionDeclaration": false,
"constant": false,
"reactive": false
},
{
"name": "disabled",
"kind": "let",
"description": "Set to `true` to disable the dropdown",
"type": "boolean",
"value": "false",
"isFunction": false,
"isFunctionDeclaration": false,
"constant": false,
"reactive": false
},
{
"name": "titleText",
"kind": "let",
"description": "Specify the title text",
"type": "string",
"value": "\"\"",
"isFunction": false,
"isFunctionDeclaration": false,
"constant": false,
"reactive": false
},
{
"name": "invalid",
"kind": "let",
"description": "Set to `true` to indicate an invalid state",
"type": "boolean",
"value": "false",
"isFunction": false,
"isFunctionDeclaration": false,
"constant": false,
"reactive": false
},
{
"name": "invalidText",
"kind": "let",
"description": "Specify the invalid state text",
"type": "string",
"value": "\"\"",
"isFunction": false,
"isFunctionDeclaration": false,
"constant": false,
"reactive": false
},
{
"name": "warn",
"kind": "let",
"description": "Set to `true` to indicate an warning state",
"type": "boolean",
"value": "false",
"isFunction": false,
"isFunctionDeclaration": false,
"constant": false,
"reactive": false
},
{
"name": "warnText",
"kind": "let",
"description": "Specify the warning state text",
"type": "string",
"value": "\"\"",
"isFunction": false,
"isFunctionDeclaration": false,
"constant": false,
"reactive": false
},
{
"name": "helperText",
"kind": "let",
"description": "Specify the helper text",
"type": "string",
"value": "\"\"",
"isFunction": false,
"isFunctionDeclaration": false,
"constant": false,
"reactive": false
},
{
"name": "hideLabel",
"kind": "let",
"description": "Set to `true` to visually hide the label text",
"type": "boolean",
"value": "false",
"isFunction": false,
"isFunctionDeclaration": false,
"constant": false,
"reactive": false
},
{
"name": "id",
"kind": "let",
"description": "Set an id for the list box component",
"type": "string",
"value": "\"ccs-\" + Math.random().toString(36)",
"isFunction": false,
"isFunctionDeclaration": false,
"constant": false,
"reactive": false
},
{
"name": "name",
"kind": "let",
"description": "Specify a name attribute for the list box",
"type": "string",
"isFunction": false,
"isFunctionDeclaration": false,
"constant": false,
"reactive": false
},
{
"name": "ref",
"kind": "let",
"description": "Obtain a reference to the button HTML element",
"type": "null | HTMLInputElement",
"value": "null",
"isFunction": false,
"isFunctionDeclaration": false,
"constant": false,
"reactive": true
},
{
"name": "placeholder",
"kind": "let",
"description": "????",
"value": "null",
"isFunction": false,
"isFunctionDeclaration": false,
"constant": false,
"reactive": false
}
],
"moduleExports": [],
"slots": [
{
"name": "__default__",
"default": true,
"fallback": "{itemToString(item)}",
"slot_props": "{ item: AutoCompleteItem; index: number; }"
}
],
"events": [
{
"type": "dispatched",
"name": "select",
"detail": "{ selectedId: AutoCompleteItemId, selectedItem: AutoCompleteItem }"
},
{ "type": "forwarded", "name": "change", "element": "input" },
{ "type": "forwarded", "name": "focus", "element": "input" },
{ "type": "forwarded", "name": "blur", "element": "input" },
{ "type": "forwarded", "name": "input", "element": "input" },
{ "type": "dispatched", "name": "clear" }
],
"typedefs": [
{
"type": "any",
"name": "AutoCompleteItemId",
"ts": "type AutoCompleteItemId = any"
},
{
"type": "string",
"name": "AutoCompleteItemText",
"ts": "type AutoCompleteItemText = string"
},
{
"type": "{ id: AutoCompleteItemId; text: AutoCompleteItemText; }",
"name": "AutoCompleteItem",
"ts": "interface AutoCompleteItem { id: AutoCompleteItemId; text: AutoCompleteItemText; }"
}
],
"rest_props": { "type": "Element", "name": "div" }
},
{
"moduleName": "AutoCompleteSkeleton",
"filePath": "src/AutoComplete/AutoCompleteSkeleton.svelte",
"props": [
{
"name": "hideLabel",
"kind": "let",
"description": "Set to `true` to hide the label text",
"type": "boolean",
"value": "false",
"isFunction": false,
"isFunctionDeclaration": false,
"constant": false,
"reactive": false
}
],
"moduleExports": [],
"slots": [],
"events": [
{ "type": "forwarded", "name": "click", "element": "div" },
{ "type": "forwarded", "name": "mouseover", "element": "div" },
{ "type": "forwarded", "name": "mouseenter", "element": "div" },
{ "type": "forwarded", "name": "mouseleave", "element": "div" }
],
"typedefs": [],
"rest_props": { "type": "Element", "name": "div" }
},
{ {
"moduleName": "Breadcrumb", "moduleName": "Breadcrumb",
"filePath": "src/Breadcrumb/Breadcrumb.svelte", "filePath": "src/Breadcrumb/Breadcrumb.svelte",

View file

@ -0,0 +1,101 @@
---
components: ["AutoComplete", "AutoCompleteSkeleton"]
---
<script>
import { AutoComplete, AutoCompleteSkeleton, InlineNotification } from "carbon-components-svelte";
import Preview from "../../components/Preview.svelte";
</script>
`AutoComplete` is keyed for performance reasons.
<InlineNotification svx-ignore lowContrast title="Note:" kind="info" hideCloseButton>
<div class="body-short-01">Every <code>items</code> object must have a unique "id" property.</div>
</InlineNotification>
### Default
<AutoComplete titleText="Contact" selectedId="0" items="{[{id: "0", text: "Slack"},
{id: "11", text: "Email1"},
{id: "12", text: "Email2"},
{id: "2", text: "Fax"}]}" />
### Custom slot
Override the default slot to customize the display of each item. Access the item and index through the `let:` directive.
<FileSource src="/framed/AutoComplete/AutoCompleteSlot" />
### Hidden label
<AutoComplete hideLabel titleText="Contact" selectedId="0" items="{[{id: "0", text: "Slack"},
{id: "1", text: "Email"},
{id: "2", text: "Fax"}]}" />
### Format item display text
Use the `itemToString` prop to format the display of individual items.
<AutoComplete itemToString={item => {
return item.text + ' (' + item.id +')'
}} titleText="Contact" selectedId="0" items="{[{id: "0", text: "Slack"},
{id: "1", text: "Email"},
{id: "2", text: "Fax"}]}" />
### Multiple dropdowns
<FileSource src="/framed/AutoComplete/MultipleAutoComplete" />
### Top direction
Set `direction` to `"top"` for the dropdown menu to appear above the input.
<AutoComplete direction="top" titleText="Contact" selectedId="0" items="{[{id: "0", text: "Slack"},
{id: "1", text: "Email"},
{id: "2", text: "Fax"}]}" />
### Light variant
<AutoComplete light titleText="Contact" selectedId="0" items="{[{id: "0", text: "Slack"},
{id: "1", text: "Email"},
{id: "2", text: "Fax"}]}" />
### Inline variant
<AutoComplete type="inline" titleText="Contact" selectedId="0" items="{[{id: "0", text: "Slack"},
{id: "1", text: "Email"},
{id: "2", text: "Fax"}]}" />
### Extra-large size
<AutoComplete size="xl" titleText="Contact" selectedId="0" items="{[{id: "0", text: "Slack"},
{id: "1", text: "Email"},
{id: "2", text: "Fax"}]}" />
### Small size
<AutoComplete size="sm" titleText="Contact" selectedId="0" items="{[{id: "0", text: "Slack"},
{id: "1", text: "Email"},
{id: "2", text: "Fax"}]}" />
### Invalid state
<AutoComplete invalid invalidText="Secondary contact method must be different from the primary contact" titleText="Contact" selectedId="0" items="{[{id: "0", text: "Slack"},
{id: "1", text: "Email"},
{id: "2", text: "Fax"}]}" />
### Warning state
<AutoComplete warn warnText="This contact method is not associated with your account" titleText="Contact" selectedId="0" items="{[{id: "0", text: "Slack"},
{id: "1", text: "Email"},
{id: "2", text: "Fax"}]}" />
### Disabled state
<AutoComplete disabled titleText="Contact" selectedId="0" items="{[{id: "0", text: "Slack"},
{id: "1", text: "Email"},
{id: "2", text: "Fax"}]}" />
### Skeleton
<AutoCompleteSkeleton />

View file

@ -0,0 +1,29 @@
<script>
import { AutoComplete } from "carbon-components-svelte";
</script>
<AutoComplete
titleText="Contact"
selectedId="0"
items="{[
{ id: '0', text: 'Slack' },
{ id: '1', text: 'Email' },
{ id: '2', text: 'Fax' },
]}"
let:item
let:index
>
<div>
<strong>{item.text}</strong>
</div>
<div>
id: {item.id} - index:
{index}
</div>
</AutoComplete>
<style>
:global(.bx--list-box__menu-item, .bx--list-box__menu-item__option) {
height: auto;
}
</style>

View file

@ -0,0 +1,42 @@
<script>
import { AutoComplete } from "carbon-components-svelte";
const items = [
{ id: "0", text: "Slack" },
{ id: "1", text: "Email" },
{ id: "2", text: "Fax" },
];
let auto_complete1_selectedId = "0";
let auto_complete2_selectedId = "1";
const formatSelected = (id) =>
items.find((item) => item.id === id)?.text ?? "N/A";
$: primary = formatSelected(auto_complete1_selectedId);
$: secondary = formatSelected(auto_complete2_selectedId);
</script>
<AutoComplete
titleText="Primary contact"
bind:selectedId="{auto_complete1_selectedId}"
items="{items}"
/>
<div>Primary: {primary}</div>
<AutoComplete
invalid="{auto_complete1_selectedId === auto_complete2_selectedId}"
invalidText="Secondary contact method must be different from the primary contact"
titleText="Secondary contact"
bind:selectedId="{auto_complete2_selectedId}"
items="{items}"
/>
<div>Secondary: {secondary}</div>
<style>
div {
margin: var(--cds-layout-01) 0 var(--cds-layout-03);
}
</style>

View file

@ -1,5 +1,16 @@
<script> <script>
import { Button } from "carbon-components-svelte"; import { AutoComplete, Button } from "carbon-components-svelte";
</script> </script>
<AutoComplete
titleText="Contact"
selectedId="0"
items="{[
{ id: '0', text: 'Slack' },
{ id: '11', text: 'Email1' },
{ id: '12', text: 'Email2' },
{ id: '2', text: 'Fax' },
]}"
/>
<Button>Primary button</Button> <Button>Primary button</Button>

4554
package-lock.json generated Normal file

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,6 @@
{ {
"name": "carbon-components-svelte", "name": "carbon-components-svelte",
"version": "0.62.3", "version": "0.62.4",
"license": "Apache-2.0", "license": "Apache-2.0",
"description": "Svelte implementation of the Carbon Design System", "description": "Svelte implementation of the Carbon Design System",
"svelte": "./src/index.js", "svelte": "./src/index.js",
@ -20,6 +20,7 @@
"prepare": "husky install" "prepare": "husky install"
}, },
"dependencies": { "dependencies": {
"carbon-preprocess-svelte": "^0.8.2",
"flatpickr": "4.6.9" "flatpickr": "4.6.9"
}, },
"devDependencies": { "devDependencies": {

View file

@ -0,0 +1,335 @@
<script>
/**
* @typedef {any} AutoCompleteItemId
* @typedef {string} AutoCompleteItemText
* @typedef {{ id: AutoCompleteItemId; text: AutoCompleteItemText; }} AutoCompleteItem
* @event {{ selectedId: AutoCompleteItemId, selectedItem: AutoCompleteItem }} select
* @slot {{ item: AutoCompleteItem; index: number; }}
*/
/**
* Set the dropdown items
* @type {AutoCompleteItem[]}
*/
export let items = [];
export let filteredItems = [];
/**
* Override the display of a dropdown item
* @type {(item: AutoCompleteItem) => string}
*/
export let itemToString = (item) => item.text || item.id;
/**
* Specify the selected item id
* @type {AutoCompleteItemId}
*/
export let selectedId = undefined;
/**
* Specify the type of dropdown
* @type {"default" | "inline"}
*/
export let type = "default";
/**
* Specify the direction of the dropdown menu
* @type {"bottom" | "top"}
*/
export let direction = "bottom";
/**
* Specify the size of the dropdown field
* @type {"sm" | "lg" | "xl"}
*/
export let size = undefined;
/** Set to `true` to open the dropdown */
export let open = false;
/** Set to `true` to use the inline variant */
export let inline = false;
/** Set to `true` to enable the light variant */
export let light = false;
/** Set to `true` to disable the dropdown */
export let disabled = false;
/** Specify the title text */
export let titleText = "";
/** Set to `true` to indicate an invalid state */
export let invalid = false;
/** Specify the invalid state text */
export let invalidText = "";
/** Set to `true` to indicate an warning state */
export let warn = false;
/** Specify the warning state text */
export let warnText = "";
/** Specify the helper text */
export let helperText = "";
/** Set to `true` to visually hide the label text */
export let hideLabel = false;
/** Set an id for the list box component */
export let id = "ccs-" + Math.random().toString(36);
/**
* Specify a name attribute for the list box
* @type {string}
*/
export let name = undefined;
/** Obtain a reference to the button HTML element */
export let ref = null;
/** ???? */
export let placeholder = null;
import { createEventDispatcher } from "svelte";
import WarningFilled from "../icons/WarningFilled.svelte";
import WarningAltFilled from "../icons/WarningAltFilled.svelte";
import { ListBox, ListBoxMenu, ListBoxMenuItem } from "../ListBox";
const dispatch = createEventDispatcher();
let highlightedIndex = -1;
let innerValue = undefined;
function change(dir) {
let index = highlightedIndex + dir;
if (index < 0) {
index = filteredItems.length - 1;
} else if (index >= filteredItems.length) {
index = 0;
}
highlightedIndex = index;
}
function onKeydown(event) {
let key = event.key;
console.log(key);
if (["Enter", "ArrowDown", "ArrowUp"].includes(key)) {
event.preventDefault();
}
if (key === "Enter") {
open = !open;
if (
highlightedIndex > -1 &&
filteredItems[highlightedIndex].id !== selectedId
) {
selectedId = filteredItems[highlightedIndex].id;
innerValue = filteredItems[highlightedIndex].text;
open = false;
}
} else if (key === "Backspace") {
selectedId = undefined;
open = innerValue.length > 0 && filteredItems.length > 0;
} else if (key === "Tab") {
open = false;
ref.blur();
} else if (key === "ArrowDown") {
change(1);
} else if (key === "ArrowUp") {
change(-1);
} else if (key === "Escape") {
innerValue = "";
dispatch("clear");
open = false;
} else {
if (!open) open = filteredItems.length > 0;
}
}
$: if (selectedId !== undefined) {
dispatch("select", { selectedId, selectedItem });
}
$: filteredItems = items.filter(
(item) => innerValue?.length > 0 && item.text.startsWith(innerValue)
);
$: inline = type === "inline";
$: selectedItem = filteredItems.find((item) => item.id === selectedId);
$: if (!open) {
highlightedIndex = -1;
}
</script>
<svelte:window
on:click="{({ target }) => {
if (open && ref && !ref.contains(target)) {
open = false;
}
}}"
/>
<div
class:bx--auto-complete__wrapper="{true}"
class:bx--list-box__wrapper="{true}"
class:bx--auto-complete__wrapper--inline="{inline}"
class:bx--list-box__wrapper--inline="{inline}"
class:bx--auto-complete__wrapper--inline--invalid="{inline && invalid}"
{...$$restProps}
>
{#if titleText}
<label
for="{id}"
class:bx--label="{true}"
class:bx--label--disabled="{disabled}"
class:bx--visually-hidden="{hideLabel}"
>
{titleText}
</label>
{/if}
<ListBox
type="{type}"
size="{size}"
id="{id}"
name="{name}"
aria-label="{$$props['aria-label']}"
class="bx--dropdown {direction === 'top' && 'bx--list-box--up'} {invalid &&
'bx--dropdown--invalid'} {!invalid &&
warn &&
'bx--dropdown--warning'} {open && 'bx--dropdown--open'}
{size === 'sm' && 'bx--dropdown--sm'}
{size === 'xl' && 'bx--dropdown--xl'}
{inline && 'bx--dropdown--inline'}
{disabled && 'bx--dropdown--disabled'}
{light && 'bx--dropdown--light'}"
on:click="{({ target }) => {
if (disabled) return;
open = ref.contains(target) ? !open : false;
}}"
disabled="{disabled}"
open="{open}"
invalid="{invalid}"
invalidText="{invalidText}"
light="{light}"
warn="{warn}"
warnText="{warnText}"
>
{#if invalid}
<WarningFilled class="bx--text-input__invalid-icon" />
{/if}
{#if !invalid && warn}
<WarningAltFilled
class="bx--text-input__invalid-icon
bx--text-input__invalid-icon--warning"
/>
{/if}
<input
bind:this="{ref}"
bind:value="{innerValue}"
type="text"
role="searchbox"
class="
bx--auto-complete__input
{light && 'bx--auto-complete__input--light'}
{invalid && 'bx--auto-complete__input--invalid'}
{warn && 'bx--auto-complete__input--warn'}
{size === 'sm' && 'bx--auto-complete__input--sm'}
{size === 'xl' && 'bx--auto-complete__input--xl'}
"
autocomplete="false"
disabled="{disabled}"
id="{id}"
name="{name}"
placeholder="{placeholder}"
{...$$restProps}
on:change
on:focus
on:blur
on:input
on:keydown="{onKeydown}"
/>
{#if open}
<ListBoxMenu aria-labelledby="{id}" id="{id}">
{#each filteredItems as item, i (item.id)}
<ListBoxMenuItem
id="{item.id}"
active="{selectedId === item.id}"
highlighted="{highlightedIndex === i || selectedId === item.id}"
on:click="{() => {
selectedId = item.id;
innerValue = item.text;
ref.focus();
}}"
on:mouseenter="{() => {
highlightedIndex = i;
}}"
>
<slot item="{item}" index="{i}">
{itemToString(item)}
</slot>
</ListBoxMenuItem>
{/each}
</ListBoxMenu>
{/if}
</ListBox>
{#if !inline && !invalid && !warn && helperText}
<div
class:bx--form__helper-text="{true}"
class:bx--form__helper-text--disabled="{disabled}"
>
{helperText}
</div>
{/if}
</div>
<style>
.bx--auto-complete__input {
font-size: var(--cds-body-short-01-font-size, 0.875rem);
font-weight: var(--cds-body-short-01-font-weight, 400);
line-height: var(--cds-body-short-01-line-height, 1.28572);
letter-spacing: var(--cds-body-short-01-letter-spacing, 0.16px);
outline: 2px solid transparent;
outline-offset: -2px;
width: 100%;
height: 2.5rem;
padding: 0 1rem;
border: none;
border-bottom-color: currentcolor;
border-bottom-style: none;
border-bottom-width: medium;
border-bottom: 1px solid var(--cds-ui-04, #8d8d8d);
background-color: var(--cds-field-01, #f4f4f4);
color: var(--cds-text-01, #161616);
transition: background-color 70ms cubic-bezier(0.2, 0, 0.38, 0.9),
outline 70ms cubic-bezier(0.2, 0, 0.38, 0.9);
}
.bx--auto-complete__input:focus {
outline: 2px solid var(--cds-focus, #0f62fe);
outline-offset: -2px;
}
.bx--auto-complete__input--sm {
height: 2rem;
}
.bx--auto-complete__input--xl,
.bx--auto-complete__input--lg {
height: 3rem;
}
.bx--auto-complete__input:disabled {
outline: 2px solid transparent;
outline-offset: -2px;
border-bottom: 1px solid transparent;
background-color: var(--cds-field, #f4f4f4);
color: var(--cds-text-disabled, #c6c6c6);
cursor: not-allowed;
-webkit-text-fill-color: var(--cds-disabled-02, #c6c6c6);
}
</style>

View file

@ -0,0 +1,19 @@
<script>
/** Set to `true` to hide the label text */
export let hideLabel = false;
</script>
<!-- svelte-ignore a11y-mouse-events-have-key-events -->
<div
class:bx--form-item="{true}"
{...$$restProps}
on:click
on:mouseover
on:mouseenter
on:mouseleave
>
{#if !hideLabel}
<span class:bx--label="{true}" class:bx--skeleton="{true}"></span>
{/if}
<div class:bx--skeleton="{true}" class:bx--text-input="{true}"></div>
</div>

View file

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

View file

@ -1,5 +1,6 @@
export { Accordion, AccordionItem, AccordionSkeleton } from "./Accordion"; export { Accordion, AccordionItem, AccordionSkeleton } from "./Accordion";
export { AspectRatio } from "./AspectRatio"; export { AspectRatio } from "./AspectRatio";
export { AutoComplete, AutoCompleteSkeleton } from "./AutoComplete";
export { Breadcrumb, BreadcrumbItem, BreadcrumbSkeleton } from "./Breadcrumb"; export { Breadcrumb, BreadcrumbItem, BreadcrumbSkeleton } from "./Breadcrumb";
export { Breakpoint } from "./Breakpoint"; export { Breakpoint } from "./Breakpoint";
export { default as breakpointObserver } from "./Breakpoint/breakpointObserver"; export { default as breakpointObserver } from "./Breakpoint/breakpointObserver";

92
tests/AutoComplete.svelte Normal file
View file

@ -0,0 +1,92 @@
<script lang="ts">
import { AutoComplete, AutoCompleteSkeleton } from "../types";
</script>
<AutoComplete
direction="top"
titleText="Contact"
selectedId="0"
items="{[
{ id: 0, text: 'Slack' },
{ id: '1', text: 'Email' },
{ id: '2', text: 'Fax' },
]}"
on:select="{(e) => {
console.log(e.detail.selectedId);
}}"
let:item
let:index
>
{item.id}
{index}
</AutoComplete>
<AutoComplete
itemToString="{(item) => {
return item.text + ' (' + item.id + ')';
}}"
titleText="Contact"
selectedId="0"
items="{[
{ id: '0', text: 'Slack' },
{ id: '1', text: 'Email' },
{ id: '2', text: 'Fax' },
]}"
/>
<AutoComplete
light
titleText="Contact"
selectedId="0"
items="{[
{ id: '0', text: 'Slack' },
{ id: '1', text: 'Email' },
{ id: '2', text: 'Fax' },
]}"
/>
<AutoComplete
type="inline"
titleText="Contact"
selectedId="0"
items="{[
{ id: '0', text: 'Slack' },
{ id: '1', text: 'Email' },
{ id: '2', text: 'Fax' },
]}"
/>
<AutoComplete
size="xl"
titleText="Contact"
selectedId="0"
items="{[
{ id: '0', text: 'Slack' },
{ id: '1', text: 'Email' },
{ id: '2', text: 'Fax' },
]}"
/>
<AutoComplete
size="sm"
titleText="Contact"
selectedId="0"
items="{[
{ id: '0', text: 'Slack' },
{ id: '1', text: 'Email' },
{ id: '2', text: 'Fax' },
]}"
/>
<AutoComplete
disabled
titleText="Contact"
selectedId="0"
items="{[
{ id: '0', text: 'Slack' },
{ id: '1', text: 'Email' },
{ id: '2', text: 'Fax' },
]}"
/>
<AutoCompleteSkeleton />

View file

@ -0,0 +1,161 @@
/// <reference types="svelte" />
import type { SvelteComponentTyped } from "svelte";
export type AutoCompleteItemId = any;
export type AutoCompleteItemText = string;
export interface AutoCompleteItem {
id: AutoCompleteItemId;
text: AutoCompleteItemText;
}
export interface AutoCompleteProps
extends svelte.JSX.HTMLAttributes<HTMLElementTagNameMap["div"]> {
/**
* Set the dropdown items
* @default []
*/
items?: AutoCompleteItem[];
/**
* @default []
*/
filteredItems?: [];
/**
* Override the display of a dropdown item
* @default (item) => item.text || item.id
*/
itemToString?: (item: AutoCompleteItem) => string;
/**
* Specify the selected item id
* @default undefined
*/
selectedId?: AutoCompleteItemId;
/**
* Specify the type of dropdown
* @default "default"
*/
type?: "default" | "inline";
/**
* Specify the direction of the dropdown menu
* @default "bottom"
*/
direction?: "bottom" | "top";
/**
* Specify the size of the dropdown field
* @default undefined
*/
size?: "sm" | "lg" | "xl";
/**
* Set to `true` to open the dropdown
* @default false
*/
open?: boolean;
/**
* Set to `true` to use the inline variant
* @default false
*/
inline?: boolean;
/**
* Set to `true` to enable the light variant
* @default false
*/
light?: boolean;
/**
* Set to `true` to disable the dropdown
* @default false
*/
disabled?: boolean;
/**
* Specify the title text
* @default ""
*/
titleText?: string;
/**
* Set to `true` to indicate an invalid state
* @default false
*/
invalid?: boolean;
/**
* Specify the invalid state text
* @default ""
*/
invalidText?: string;
/**
* Set to `true` to indicate an warning state
* @default false
*/
warn?: boolean;
/**
* Specify the warning state text
* @default ""
*/
warnText?: string;
/**
* Specify the helper text
* @default ""
*/
helperText?: string;
/**
* Set to `true` to visually hide the label text
* @default false
*/
hideLabel?: boolean;
/**
* Set an id for the list box component
* @default "ccs-" + Math.random().toString(36)
*/
id?: string;
/**
* Specify a name attribute for the list box
* @default undefined
*/
name?: string;
/**
* Obtain a reference to the button HTML element
* @default null
*/
ref?: null | HTMLInputElement;
/**
* ????
* @default null
*/
placeholder?: undefined;
}
export default class AutoComplete extends SvelteComponentTyped<
AutoCompleteProps,
{
select: CustomEvent<{
selectedId: AutoCompleteItemId;
selectedItem: AutoCompleteItem;
}>;
change: WindowEventMap["change"];
focus: WindowEventMap["focus"];
blur: WindowEventMap["blur"];
input: WindowEventMap["input"];
clear: CustomEvent<any>;
},
{ default: { item: AutoCompleteItem; index: number } }
> {}

View file

@ -0,0 +1,22 @@
/// <reference types="svelte" />
import type { SvelteComponentTyped } from "svelte";
export interface AutoCompleteSkeletonProps
extends svelte.JSX.HTMLAttributes<HTMLElementTagNameMap["div"]> {
/**
* Set to `true` to hide the label text
* @default false
*/
hideLabel?: boolean;
}
export default class AutoCompleteSkeleton extends SvelteComponentTyped<
AutoCompleteSkeletonProps,
{
click: WindowEventMap["click"];
mouseover: WindowEventMap["mouseover"];
mouseenter: WindowEventMap["mouseenter"];
mouseleave: WindowEventMap["mouseleave"];
},
{}
> {}

2
types/index.d.ts vendored
View file

@ -2,6 +2,8 @@ export { default as Accordion } from "./Accordion/Accordion.svelte";
export { default as AccordionItem } from "./Accordion/AccordionItem.svelte"; export { default as AccordionItem } from "./Accordion/AccordionItem.svelte";
export { default as AccordionSkeleton } from "./Accordion/AccordionSkeleton.svelte"; export { default as AccordionSkeleton } from "./Accordion/AccordionSkeleton.svelte";
export { default as AspectRatio } from "./AspectRatio/AspectRatio.svelte"; export { default as AspectRatio } from "./AspectRatio/AspectRatio.svelte";
export { default as AutoComplete } from "./AutoComplete/AutoComplete.svelte";
export { default as AutoCompleteSkeleton } from "./AutoComplete/AutoCompleteSkeleton.svelte";
export { default as Breadcrumb } from "./Breadcrumb/Breadcrumb.svelte"; export { default as Breadcrumb } from "./Breadcrumb/Breadcrumb.svelte";
export { default as BreadcrumbItem } from "./Breadcrumb/BreadcrumbItem.svelte"; export { default as BreadcrumbItem } from "./Breadcrumb/BreadcrumbItem.svelte";
export { default as BreadcrumbSkeleton } from "./Breadcrumb/BreadcrumbSkeleton.svelte"; export { default as BreadcrumbSkeleton } from "./Breadcrumb/BreadcrumbSkeleton.svelte";

2311
yarn.lock

File diff suppressed because it is too large Load diff