Merge pull request #369 from IBM/datatable

DataTable: add ToolbarMenu, ToolbarMenuItem, fix batch actions selection cancellation
This commit is contained in:
Eric Liu 2020-10-26 10:58:01 -07:00 committed by GitHub
commit 04fc011e7b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 536 additions and 237 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,59 @@ 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
- `on:click`
- `on:keydown`
### Dispatched events
No dispatched events.
---
## ToolbarSearch ## ToolbarSearch
### Import path ### Import path

File diff suppressed because it is too large Load diff

View file

@ -1,9 +1,9 @@
--- ---
components: ["DataTable", "Toolbar", "ToolbarContent", "ToolbarSearch", "ToolbarBatchActions"] components: ["DataTable", "Toolbar", "ToolbarContent", "ToolbarSearch", "ToolbarMenu", "ToolbarMenuItem", "ToolbarBatchActions"]
--- ---
<script> <script>
import { DataTable, DataTableSkeleton, Toolbar, ToolbarContent, ToolbarSearch, Button, Link } from "carbon-components-svelte"; import { DataTable, DataTableSkeleton, Toolbar, ToolbarContent, ToolbarSearch, ToolbarMenu, ToolbarMenuItem, Button, Link } from "carbon-components-svelte";
import Launch16 from "carbon-icons-svelte/lib/Launch16"; import Launch16 from "carbon-icons-svelte/lib/Launch16";
import Preview from "../../components/Preview.svelte"; import Preview from "../../components/Preview.svelte";
</script> </script>
@ -316,7 +316,12 @@ The slot name for the table header cells is `"cell-header"`.
<Toolbar> <Toolbar>
<ToolbarContent> <ToolbarContent>
<ToolbarSearch /> <ToolbarSearch />
<Button>Create</Button> <ToolbarMenu>
<ToolbarMenuItem primaryFocus>Restart all</ToolbarMenuItem>
<ToolbarMenuItem href="https://cloud.ibm.com/docs/loadbalancer-service">API Documentation</ToolbarMenuItem>
<ToolbarMenuItem danger>Stop all</ToolbarMenuItem>
</ToolbarMenu>
<Button>Create balancer</Button>
</ToolbarContent> </ToolbarContent>
</Toolbar> </Toolbar>
</DataTable> </DataTable>
@ -378,7 +383,12 @@ The slot name for the table header cells is `"cell-header"`.
<Toolbar size="sm"> <Toolbar size="sm">
<ToolbarContent> <ToolbarContent>
<ToolbarSearch /> <ToolbarSearch />
<Button>Create</Button> <ToolbarMenu>
<ToolbarMenuItem primaryFocus>Restart all</ToolbarMenuItem>
<ToolbarMenuItem href="https://cloud.ibm.com/docs/loadbalancer-service">API Documentation</ToolbarMenuItem>
<ToolbarMenuItem danger>Stop all</ToolbarMenuItem>
</ToolbarMenu>
<Button>Create balancer</Button>
</ToolbarContent> </ToolbarContent>
</Toolbar> </Toolbar>
</DataTable> </DataTable>

View file

@ -4,6 +4,8 @@
Toolbar, Toolbar,
ToolbarContent, ToolbarContent,
ToolbarSearch, ToolbarSearch,
ToolbarMenu,
ToolbarMenuItem,
ToolbarBatchActions, ToolbarBatchActions,
Button, Button,
} from "carbon-components-svelte"; } from "carbon-components-svelte";
@ -36,7 +38,14 @@
</ToolbarBatchActions> </ToolbarBatchActions>
<ToolbarContent> <ToolbarContent>
<ToolbarSearch /> <ToolbarSearch />
<Button>Create</Button> <ToolbarMenu>
<ToolbarMenuItem primaryFocus>Restart all</ToolbarMenuItem>
<ToolbarMenuItem href="https://cloud.ibm.com/docs/loadbalancer-service">
API Documentation
</ToolbarMenuItem>
<ToolbarMenuItem danger>Stop all</ToolbarMenuItem>
</ToolbarMenu>
<Button>Create balancer</Button>
</ToolbarContent> </ToolbarContent>
</Toolbar> </Toolbar>
</DataTable> </DataTable>

View file

@ -22,9 +22,16 @@
* @type {string} [id] * @type {string} [id]
*/ */
export let id = "ccs-" + Math.random().toString(36); export let id = "ccs-" + Math.random().toString(36);
/**
* Obtain a reference to the input HTML element
* @type {null | HTMLInputElement} [ref=null]
*/
export let ref = null;
</script> </script>
<input <input
bind:this="{ref}"
type="checkbox" type="checkbox"
class:bx--checkbox="{true}" class:bx--checkbox="{true}"
checked="{indeterminate ? false : checked}" checked="{indeterminate ? false : checked}"

View file

@ -107,11 +107,11 @@
*/ */
export let ref = null; export let ref = null;
/** /**
* 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

@ -131,7 +131,9 @@
tableSortable, tableSortable,
batchSelectedIds, batchSelectedIds,
resetSelectedRowIds: () => { resetSelectedRowIds: () => {
selectAll = false;
selectedRowIds = []; selectedRowIds = [];
if (refSelectAll) refSelectAll.checked = false;
}, },
add: (id) => { add: (id) => {
headerItems.update((_) => [..._, id]); headerItems.update((_) => [..._, id]);
@ -147,6 +149,8 @@
); );
let selectAll = false; let selectAll = false;
let refSelectAll = null;
$: batchSelectedIds.set(selectedRowIds); $: batchSelectedIds.set(selectedRowIds);
$: indeterminate = $: indeterminate =
selectedRowIds.length > 0 && selectedRowIds.length < rows.length; selectedRowIds.length > 0 && selectedRowIds.length < rows.length;
@ -221,6 +225,7 @@
{#if batchSelection && !radio} {#if batchSelection && !radio}
<th scope="col" class:bx--table-column-checkbox="{true}"> <th scope="col" class:bx--table-column-checkbox="{true}">
<InlineCheckbox <InlineCheckbox
bind:ref="{refSelectAll}"
aria-label="Select all rows" aria-label="Select all rows"
checked="{selectAll}" checked="{selectAll}"
indeterminate="{indeterminate}" indeterminate="{indeterminate}"

View file

@ -4,16 +4,30 @@
* @type {"sm" | "default"} [size="default"] * @type {"sm" | "default"} [size="default"]
*/ */
export let size = "default"; export let size = "default";
import { setContext } from "svelte";
import { writable } from "svelte/store";
let ref = null;
const overflowVisible = writable(false);
setContext("Toolbar", {
overflowVisible,
setOverflowVisible: (visible) => {
overflowVisible.set(visible);
if (ref) ref.style.overflow = visible ? "visible" : "inherit";
},
});
</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'}"
class:bx--table-toolbar--normal="{size === 'default'}" class:bx--table-toolbar--normal="{size === 'default'}"
{...$$restProps} {...$$restProps}
> >
<div class:bx--toolbar-content="{true}"> <slot />
<slot />
</div>
</section> </section>

View file

@ -18,27 +18,41 @@
batchSelectedIds = value; batchSelectedIds = value;
}); });
onMount(() => unsubscribe); let overflowVisible = false;
const ctxToolbar = getContext("Toolbar");
const unsubscribeOverflow = ctxToolbar.overflowVisible.subscribe((value) => {
overflowVisible = value;
});
onMount(() => {
return () => {
unsubscribe();
unsubscribeOverflow();
};
});
</script> </script>
<div {#if !overflowVisible}
class:bx--batch-actions="{true}" <div
class:bx--batch-actions--active="{showActions}" class:bx--batch-actions="{true}"
{...$$restProps} class:bx--batch-actions--active="{showActions}"
> {...$$restProps}
<div class:bx--batch-summary="{true}"> >
<p class:bx--batch-summary__para="{true}"> <div class:bx--batch-summary="{true}">
<span> {formatTotalSelected(batchSelectedIds.length)} </span> <p class:bx--batch-summary__para="{true}">
</p> <span> {formatTotalSelected(batchSelectedIds.length)} </span>
</p>
</div>
<div class:bx--action-list="{true}">
<slot />
<Button
class="bx--batch-summary__cancel"
tabindex="{showActions ? '0' : '-1'}"
on:click="{ctx.resetSelectedRowIds}"
>
Cancel
</Button>
</div>
</div> </div>
<div class:bx--action-list="{true}"> {/if}
<slot />
<Button
class="bx--batch-summary__cancel"
tabindex="{showActions ? '0' : '-1'}"
on:click="{ctx.resetSelectedRowIds}"
>
Cancel
</Button>
</div>
</div>

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.setOverflowVisible(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} on:click on:keydown>
<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: {
/** /**