feat(data-table): add ToolbarMenu

Requires menuRef from OverflowMenu to be exported.
This commit is contained in:
Eric Liu 2020-10-26 07:43:54 -07:00
commit c39427670a
10 changed files with 305 additions and 72 deletions

View file

@ -1,6 +1,6 @@
# Component Index # Component Index
> 152 components exported from carbon-components-svelte 0.20.0 > 154 components exported from carbon-components-svelte 0.20.0
- Accordion - Accordion
- [Accordion](#accordion) - [Accordion](#accordion)
@ -44,6 +44,8 @@
- [Toolbar](#toolbar) - [Toolbar](#toolbar)
- [ToolbarBatchActions](#toolbarbatchactions) - [ToolbarBatchActions](#toolbarbatchactions)
- [ToolbarContent](#toolbarcontent) - [ToolbarContent](#toolbarcontent)
- [ToolbarMenu](#toolbarmenu)
- [ToolbarMenuItem](#toolbarmenuitem)
- [ToolbarSearch](#toolbarsearch) - [ToolbarSearch](#toolbarsearch)
- [DataTableSkeleton](#datatableskeleton) - [DataTableSkeleton](#datatableskeleton)
- DatePicker - DatePicker
@ -796,6 +798,7 @@ interface ComboBoxItem {
| id | <code>string</code> | -- | Set an id for the list box component. | | id | <code>string</code> | -- | Set an id for the list box component. |
| name | <code>string</code> | -- | Specify a name attribute for the input. | | name | <code>string</code> | -- | Specify a name attribute for the input. |
| ref | <code>null &#124; HTMLInputElement</code> | `null` | Obtain a reference to the input HTML element. | | ref | <code>null &#124; HTMLInputElement</code> | `null` | Obtain a reference to the input HTML element. |
| listRef | <code>null &#124; HTMLDivElement</code> | `null` | Obtain a reference to the list HTML element. |
### Slots ### Slots
@ -807,6 +810,7 @@ No slots.
- `on:focus` - `on:focus`
- `on:blur` - `on:blur`
- `on:clear` - `on:clear`
- `on:scroll`
### Dispatched events ### Dispatched events
@ -2363,7 +2367,7 @@ import { ListBoxMenu } from "carbon-components-svelte";
### Forwarded events ### Forwarded events
No forwarded events. - `on:scroll`
### Dispatched events ### Dispatched events
@ -3019,6 +3023,8 @@ import { OverflowMenu } from "carbon-components-svelte";
| iconClass | <code>string</code> | -- | Specify the icon class. | | iconClass | <code>string</code> | -- | Specify the icon class. |
| iconDescription | <code>string</code> | `"Open and close list of options"` | Specify the ARIA label for the icon. | | iconDescription | <code>string</code> | `"Open and close list of options"` | Specify the ARIA label for the icon. |
| id | <code>string</code> | -- | Set an id for the button element. | | id | <code>string</code> | -- | Set an id for the button element. |
| buttonRef | <code>null &#124; HTMLButtonElement</code> | `null` | Obtain a reference to the trigger button element. |
| menuRef | <code>null &#124; HTMLUListElement</code> | `null` | Obtain a reference to the overflow menu element. |
### Slots ### Slots
@ -5322,6 +5328,58 @@ No dispatched events.
--- ---
## ToolbarMenu
### Import path
```js
import { ToolbarMenu } from "carbon-components-svelte";
```
### Props
No exported props.
### Slots
- **default**: `<div>...</div>`
### Forwarded events
No forwarded events.
### Dispatched events
No dispatched events.
---
## ToolbarMenuItem
### Import path
```js
import { ToolbarMenuItem } from "carbon-components-svelte";
```
### Props
No exported props.
### Slots
- **default**: `<div>...</div>`
### Forwarded events
No forwarded events.
### Dispatched events
No dispatched events.
---
## ToolbarSearch ## ToolbarSearch
### Import path ### Import path

View file

@ -1950,6 +1950,15 @@
"type": "null | HTMLInputElement", "type": "null | HTMLInputElement",
"description": "Obtain a reference to the input HTML element" "description": "Obtain a reference to the input HTML element"
} }
],
[
"listRef",
{
"kind": "let",
"value": "null",
"type": "null | HTMLDivElement",
"description": "Obtain a reference to the list HTML element"
}
] ]
], ],
"slots": [], "slots": [],
@ -1957,8 +1966,8 @@
[ [
"keydown", "keydown",
{ {
"start": 5481, "start": 5616,
"end": 5491, "end": 5626,
"type": "EventHandler", "type": "EventHandler",
"name": "keydown", "name": "keydown",
"modifiers": [], "modifiers": [],
@ -1968,8 +1977,8 @@
[ [
"focus", "focus",
{ {
"start": 6068, "start": 6203,
"end": 6076, "end": 6211,
"type": "EventHandler", "type": "EventHandler",
"name": "focus", "name": "focus",
"modifiers": [], "modifiers": [],
@ -1979,8 +1988,8 @@
[ [
"blur", "blur",
{ {
"start": 6085, "start": 6220,
"end": 6092, "end": 6227,
"type": "EventHandler", "type": "EventHandler",
"name": "blur", "name": "blur",
"modifiers": [], "modifiers": [],
@ -1990,13 +1999,24 @@
[ [
"clear", "clear",
{ {
"start": 6543, "start": 6678,
"end": 6551, "end": 6686,
"type": "EventHandler", "type": "EventHandler",
"name": "clear", "name": "clear",
"modifiers": [], "modifiers": [],
"expression": null "expression": null
} }
],
[
"scroll",
{
"start": 7220,
"end": 7229,
"type": "EventHandler",
"name": "scroll",
"modifiers": [],
"expression": null
}
] ]
], ],
"dispatched_events": [ "dispatched_events": [
@ -6967,7 +6987,19 @@
} }
] ]
], ],
"forwarded_events": [], "forwarded_events": [
[
"scroll",
{
"start": 403,
"end": 412,
"type": "EventHandler",
"name": "scroll",
"modifiers": [],
"expression": null
}
]
],
"dispatched_events": [] "dispatched_events": []
}, },
"ListBoxMenuIcon": { "ListBoxMenuIcon": {
@ -8800,6 +8832,24 @@
"type": "string", "type": "string",
"description": "Set an id for the button element" "description": "Set an id for the button element"
} }
],
[
"buttonRef",
{
"kind": "let",
"value": "null",
"type": "null | HTMLButtonElement",
"description": "Obtain a reference to the trigger button element"
}
],
[
"menuRef",
{
"kind": "let",
"value": "null",
"type": "null | HTMLUListElement",
"description": "Obtain a reference to the overflow menu element"
}
] ]
], ],
"slots": [ "slots": [
@ -8808,14 +8858,14 @@
{ {
"attributes": [ "attributes": [
{ {
"start": 4567, "start": 4805,
"end": 4578, "end": 4816,
"type": "Attribute", "type": "Attribute",
"name": "name", "name": "name",
"value": [ "value": [
{ {
"start": 4573, "start": 4811,
"end": 4577, "end": 4815,
"type": "Text", "type": "Text",
"raw": "menu", "raw": "menu",
"data": "menu" "data": "menu"
@ -8825,39 +8875,39 @@
], ],
"children": [ "children": [
{ {
"start": 4579, "start": 4817,
"end": 4584, "end": 4822,
"type": "Text", "type": "Text",
"raw": "\n ", "raw": "\n ",
"data": "\n " "data": "\n "
}, },
{ {
"start": 4584, "start": 4822,
"end": 4747, "end": 4985,
"type": "InlineComponent", "type": "InlineComponent",
"name": "svelte:component", "name": "svelte:component",
"attributes": [ "attributes": [
{ {
"start": 4628, "start": 4866,
"end": 4658, "end": 4896,
"type": "Attribute", "type": "Attribute",
"name": "aria-label", "name": "aria-label",
"value": [ "value": [
{ {
"start": 4640, "start": 4878,
"end": 4657, "end": 4895,
"type": "MustacheTag", "type": "MustacheTag",
"expression": { "expression": {
"type": "Identifier", "type": "Identifier",
"start": 4641, "start": 4879,
"end": 4656, "end": 4894,
"loc": { "loc": {
"start": { "start": {
"line": 196, "line": 206,
"column": 19 "column": 19
}, },
"end": { "end": {
"line": 196, "line": 206,
"column": 34 "column": 34
} }
}, },
@ -8867,26 +8917,26 @@
] ]
}, },
{ {
"start": 4665, "start": 4903,
"end": 4690, "end": 4928,
"type": "Attribute", "type": "Attribute",
"name": "title", "name": "title",
"value": [ "value": [
{ {
"start": 4672, "start": 4910,
"end": 4689, "end": 4927,
"type": "MustacheTag", "type": "MustacheTag",
"expression": { "expression": {
"type": "Identifier", "type": "Identifier",
"start": 4673, "start": 4911,
"end": 4688, "end": 4926,
"loc": { "loc": {
"start": { "start": {
"line": 197, "line": 207,
"column": 14 "column": 14
}, },
"end": { "end": {
"line": 197, "line": 207,
"column": 29 "column": 29
} }
}, },
@ -8896,33 +8946,33 @@
] ]
}, },
{ {
"start": 4697, "start": 4935,
"end": 4740, "end": 4978,
"type": "Attribute", "type": "Attribute",
"name": "class", "name": "class",
"value": [ "value": [
{ {
"start": 4704, "start": 4942,
"end": 4729, "end": 4967,
"type": "Text", "type": "Text",
"raw": "bx--overflow-menu__icon ", "raw": "bx--overflow-menu__icon ",
"data": "bx--overflow-menu__icon " "data": "bx--overflow-menu__icon "
}, },
{ {
"start": 4728, "start": 4966,
"end": 4739, "end": 4977,
"type": "MustacheTag", "type": "MustacheTag",
"expression": { "expression": {
"type": "Identifier", "type": "Identifier",
"start": 4729, "start": 4967,
"end": 4738, "end": 4976,
"loc": { "loc": {
"start": { "start": {
"line": 198, "line": 208,
"column": 38 "column": 38
}, },
"end": { "end": {
"line": 198, "line": 208,
"column": 47 "column": 47
} }
}, },
@ -8935,15 +8985,15 @@
"children": [], "children": [],
"expression": { "expression": {
"type": "Identifier", "type": "Identifier",
"start": 4615, "start": 4853,
"end": 4619, "end": 4857,
"loc": { "loc": {
"start": { "start": {
"line": 195, "line": 205,
"column": 13 "column": 13
}, },
"end": { "end": {
"line": 195, "line": 205,
"column": 17 "column": 17
} }
}, },
@ -8951,8 +9001,8 @@
} }
}, },
{ {
"start": 4747, "start": 4985,
"end": 4750, "end": 4988,
"type": "Text", "type": "Text",
"raw": "\n ", "raw": "\n ",
"data": "\n " "data": "\n "
@ -8976,8 +9026,8 @@
[ [
"click", "click",
{ {
"start": 4089, "start": 4327,
"end": 4097, "end": 4335,
"type": "EventHandler", "type": "EventHandler",
"name": "click", "name": "click",
"modifiers": [], "modifiers": [],
@ -8987,8 +9037,8 @@
[ [
"mouseover", "mouseover",
{ {
"start": 4213, "start": 4451,
"end": 4225, "end": 4463,
"type": "EventHandler", "type": "EventHandler",
"name": "mouseover", "name": "mouseover",
"modifiers": [], "modifiers": [],
@ -8998,8 +9048,8 @@
[ [
"mouseenter", "mouseenter",
{ {
"start": 4228, "start": 4466,
"end": 4241, "end": 4479,
"type": "EventHandler", "type": "EventHandler",
"name": "mouseenter", "name": "mouseenter",
"modifiers": [], "modifiers": [],
@ -9009,8 +9059,8 @@
[ [
"mouseleave", "mouseleave",
{ {
"start": 4244, "start": 4482,
"end": 4257, "end": 4495,
"type": "EventHandler", "type": "EventHandler",
"name": "mouseleave", "name": "mouseleave",
"modifiers": [], "modifiers": [],
@ -9020,8 +9070,8 @@
[ [
"keydown", "keydown",
{ {
"start": 4260, "start": 4498,
"end": 4270, "end": 4508,
"type": "EventHandler", "type": "EventHandler",
"name": "keydown", "name": "keydown",
"modifiers": [], "modifiers": [],
@ -15563,6 +15613,40 @@
"forwarded_events": [], "forwarded_events": [],
"dispatched_events": [] "dispatched_events": []
}, },
"ToolbarMenu": {
"moduleName": "ToolbarMenu",
"props": [],
"slots": [
[
"default",
{
"attributes": [],
"children": [],
"default": true,
"default_value": ""
}
]
],
"forwarded_events": [],
"dispatched_events": []
},
"ToolbarMenuItem": {
"moduleName": "ToolbarMenuItem",
"props": [],
"slots": [
[
"default",
{
"attributes": [],
"children": [],
"default": true,
"default_value": ""
}
]
],
"forwarded_events": [],
"dispatched_events": []
},
"ToolbarSearch": { "ToolbarSearch": {
"moduleName": "ToolbarSearch", "moduleName": "ToolbarSearch",
"props": [ "props": [

View file

@ -111,7 +111,7 @@
* Obtain a reference to the list HTML element * Obtain a reference to the list HTML element
* @type {null | HTMLDivElement} [ref=null] * @type {null | HTMLDivElement} [ref=null]
*/ */
export let listRef = null export let listRef = null;
/** /**
* @typedef {{ id: string; text: string; }} ComboBoxItem * @typedef {{ id: string; text: string; }} ComboBoxItem
@ -290,7 +290,12 @@
/> />
</ListBoxField> </ListBoxField>
{#if open} {#if open}
<ListBoxMenu aria-label="{ariaLabel}" id="{id}" on:scroll bind:ref={listRef}> <ListBoxMenu
aria-label="{ariaLabel}"
id="{id}"
on:scroll
bind:ref="{listRef}"
>
{#each filteredItems as item, i (item.id)} {#each filteredItems as item, i (item.id)}
<ListBoxMenuItem <ListBoxMenuItem
id="{item.id}" id="{item.id}"

View file

@ -4,9 +4,26 @@
* @type {"sm" | "default"} [size="default"] * @type {"sm" | "default"} [size="default"]
*/ */
export let size = "default"; export let size = "default";
import { setContext } from "svelte";
let ref = null;
setContext("Toolbar", {
setOverflow: (toggled) => {
if (ref) {
if (toggled) {
ref.style.overflow = "visible";
} else {
ref.removeAttribute("style");
}
}
},
});
</script> </script>
<section <section
bind:this="{ref}"
aria-label="data table toolbar" aria-label="data table toolbar"
class:bx--table-toolbar="{true}" class:bx--table-toolbar="{true}"
class:bx--table-toolbar--small="{size === 'sm'}" class:bx--table-toolbar--small="{size === 'sm'}"

View file

@ -0,0 +1,22 @@
<script>
import { getContext } from "svelte";
import Settings16 from "carbon-icons-svelte/lib/Settings16";
import { OverflowMenu } from "../OverflowMenu";
const ctx = getContext("Toolbar");
let menuRef = null;
$: ctx.setOverflow(menuRef != null);
$: if (menuRef) menuRef.style.top = "100%";
</script>
<OverflowMenu
bind:menuRef
icon="{Settings16}"
{...$$restProps}
class="bx--toolbar-action bx--overflow-menu {$$restProps.class}"
flipped
>
<slot />
</OverflowMenu>

View file

@ -0,0 +1,7 @@
<script>
import { OverflowMenuItem } from "../OverflowMenu";
</script>
<OverflowMenuItem {...$$restProps}>
<slot />
</OverflowMenuItem>

View file

@ -10,3 +10,5 @@ export { default as Toolbar } from "./Toolbar.svelte";
export { default as ToolbarContent } from "./ToolbarContent.svelte"; export { default as ToolbarContent } from "./ToolbarContent.svelte";
export { default as ToolbarSearch } from "./ToolbarSearch.svelte"; export { default as ToolbarSearch } from "./ToolbarSearch.svelte";
export { default as ToolbarBatchActions } from "./ToolbarBatchActions.svelte"; export { default as ToolbarBatchActions } from "./ToolbarBatchActions.svelte";
export { default as ToolbarMenu } from "./ToolbarMenu.svelte";
export { default as ToolbarMenuItem } from "./ToolbarMenuItem.svelte";

View file

@ -53,6 +53,18 @@
*/ */
export let id = "ccs-" + Math.random().toString(36); export let id = "ccs-" + Math.random().toString(36);
/**
* Obtain a reference to the trigger button element
* @type {null | HTMLButtonElement} [ref=null]
*/
export let buttonRef = null;
/**
* Obtain a reference to the overflow menu element
* @type {null | HTMLUListElement} [ref=null]
*/
export let menuRef = null;
import { createEventDispatcher, setContext, afterUpdate } from "svelte"; import { createEventDispatcher, setContext, afterUpdate } from "svelte";
import { writable } from "svelte/store"; import { writable } from "svelte/store";
import OverflowMenuVertical16 from "carbon-icons-svelte/lib/OverflowMenuVertical16"; import OverflowMenuVertical16 from "carbon-icons-svelte/lib/OverflowMenuVertical16";
@ -64,10 +76,8 @@
const focusedId = writable(undefined); const focusedId = writable(undefined);
const currentIndex = writable(-1); const currentIndex = writable(-1);
$: buttonRef = undefined; let buttonWidth = undefined;
$: buttonWidth = undefined; let didOpen = false;
$: menuRef = undefined;
$: didOpen = false;
setContext("OverflowMenu", { setContext("OverflowMenu", {
focusedId, focusedId,

View file

@ -27,6 +27,8 @@ export {
ToolbarContent, ToolbarContent,
ToolbarSearch, ToolbarSearch,
ToolbarBatchActions, ToolbarBatchActions,
ToolbarMenu,
ToolbarMenuItem,
} from "./DataTable"; } from "./DataTable";
export { DataTableSkeleton } from "./DataTableSkeleton"; export { DataTableSkeleton } from "./DataTableSkeleton";
export { DatePicker, DatePickerInput, DatePickerSkeleton } from "./DatePicker"; export { DatePicker, DatePickerInput, DatePickerSkeleton } from "./DatePicker";

26
types/index.d.ts vendored
View file

@ -662,6 +662,12 @@ export class ComboBox extends CarbonSvelteComponent {
* @default null * @default null
*/ */
ref?: null | HTMLInputElement; ref?: null | HTMLInputElement;
/**
* Obtain a reference to the list HTML element
* @default null
*/
listRef?: null | HTMLDivElement;
}; };
} }
@ -2929,6 +2935,18 @@ export class OverflowMenu extends CarbonSvelteComponent {
* Set an id for the button element * Set an id for the button element
*/ */
id?: string; id?: string;
/**
* Obtain a reference to the trigger button element
* @default null
*/
buttonRef?: null | HTMLButtonElement;
/**
* Obtain a reference to the overflow menu element
* @default null
*/
menuRef?: null | HTMLUListElement;
}; };
$$slot_def: { menu: {}; default: {} }; $$slot_def: { menu: {}; default: {} };
@ -5124,6 +5142,14 @@ export class ToolbarContent extends CarbonSvelteComponent {
$$slot_def: { default: {} }; $$slot_def: { default: {} };
} }
export class ToolbarMenu extends CarbonSvelteComponent {
$$slot_def: { default: {} };
}
export class ToolbarMenuItem extends CarbonSvelteComponent {
$$slot_def: { default: {} };
}
export class ToolbarSearch extends CarbonSvelteComponent { export class ToolbarSearch extends CarbonSvelteComponent {
$$prop_def: { $$prop_def: {
/** /**