From 5fad0cb3c777113cadfea82cba7d973acea1ee02 Mon Sep 17 00:00:00 2001 From: Eric Liu Date: Sat, 20 Mar 2021 10:39:14 -0700 Subject: [PATCH] Alignment with Carbon version 10.31 (#571) * chore(deps-dev): upgrade carbon-components to v10.31.0 * fix(slider): use CSS to hide input if hideTextInput is true * docs(slider): add hidden text input, invalid, disabled examples * feat(tabs): support "container" type for TabsSkeleton * chore(list-box): remove hotfix inline style to center dropdown chevron * fix(number-input): use add, subtract icons and update markup * feat(select): add warning state * docs(select): add invalid state example * docs(select): add helper text example * fix(structured-list): add "rowgroup" role to StructuredListBody * docs: release code snippet max-width * docs(select): add skeleton hidden label example * feat(popover): add Popover component * feat(pagination): dispatch button click events to be consistent with PaginationNav * fix(multi-select): type clear as a custom event * docs(radio-button): add disabled buttons example * chore(tabs): use absolute icon import * fix(link): remove line breaks within anchor link * docs(radio-button): adjust section copy verbiage * chore(deps-dev): upgrade carbon-icons-svelte to v10.27 v10.27 uses the SvelteComponentTyped interface * docs(accordion): adjust section title verbiage * test(types): fix warnings from svelte-check * fix(search): only set autofocus attribute if equals true * feat(popover): add closeOnOutsideClick prop * docs: style [data-outline] as relative positioned * feat(context-menu): add initial ContextMenu * feat(context-menu): annotate props, generate types * feat(context-menu): add initial focus logic * fix(context-menu): correctly tab in/out of nested menus * chore(context-menu): update types * fix(context-menu): obtain radio id from node directly * docs(context-menu): add examples and test * fix(context-menu): prevent default keydown behavior --- COMPONENT_INDEX.md | 164 +++++++- docs/package.json | 2 +- docs/src/COMPONENT_API.json | 362 +++++++++++++++++- docs/src/components/Preview.svelte | 4 + docs/src/layouts/ComponentLayout.svelte | 7 +- docs/src/pages/_layout.svelte | 14 +- docs/src/pages/components/Accordion.svx | 4 +- docs/src/pages/components/ContextMenu.svx | 17 + docs/src/pages/components/Popover.svx | 77 ++++ docs/src/pages/components/RadioButton.svx | 12 +- docs/src/pages/components/Select.svx | 35 +- docs/src/pages/components/Slider.svx | 12 + docs/src/pages/components/Tabs.svx | 8 +- .../framed/ContextMenu/ContextMenu.svelte | 45 +++ .../ContextMenu/ContextMenuGroups.svelte | 23 ++ docs/yarn.lock | 10 +- package.json | 4 +- src/ContextMenu/ContextMenu.svelte | 130 +++++++ src/ContextMenu/ContextMenuDivider.svelte | 1 + src/ContextMenu/ContextMenuGroup.svelte | 36 ++ src/ContextMenu/ContextMenuOption.svelte | 263 +++++++++++++ src/ContextMenu/ContextMenuRadioGroup.svelte | 34 ++ src/ContextMenu/index.js | 5 + src/Link/Link.svelte | 5 +- src/ListBox/ListBoxMenuIcon.svelte | 1 - src/MultiSelect/MultiSelect.svelte | 15 +- src/NumberInput/NumberInput.svelte | 44 +-- src/Pagination/Pagination.svelte | 4 + src/Popover/Popover.svelte | 68 ++++ src/Popover/index.js | 1 + src/Search/Search.svelte | 2 +- src/Select/Select.svelte | 18 + src/Slider/Slider.svelte | 38 +- src/StructuredList/StructuredListBody.svelte | 1 + src/Tabs/Tabs.svelte | 2 +- src/Tabs/TabsSkeleton.svelte | 24 +- src/index.js | 8 + tests/ContextMenu.test.svelte | 58 +++ tests/LocalStorage.test.svelte | 2 +- tests/Popover.test.svelte | 20 + types/ContextMenu/ContextMenu.d.ts | 41 ++ types/ContextMenu/ContextMenuDivider.d.ts | 10 + types/ContextMenu/ContextMenuGroup.d.ts | 21 + types/ContextMenu/ContextMenuOption.d.ts | 74 ++++ types/ContextMenu/ContextMenuRadioGroup.d.ts | 22 ++ types/MultiSelect/MultiSelect.d.ts | 2 +- types/Pagination/Pagination.d.ts | 6 +- types/Popover/Popover.d.ts | 65 ++++ types/Select/Select.d.ts | 12 + types/Tabs/TabsSkeleton.d.ts | 6 + types/index.d.ts | 6 + yarn.lock | 16 +- 52 files changed, 1758 insertions(+), 103 deletions(-) create mode 100644 docs/src/pages/components/ContextMenu.svx create mode 100644 docs/src/pages/components/Popover.svx create mode 100644 docs/src/pages/framed/ContextMenu/ContextMenu.svelte create mode 100644 docs/src/pages/framed/ContextMenu/ContextMenuGroups.svelte create mode 100644 src/ContextMenu/ContextMenu.svelte create mode 100644 src/ContextMenu/ContextMenuDivider.svelte create mode 100644 src/ContextMenu/ContextMenuGroup.svelte create mode 100644 src/ContextMenu/ContextMenuOption.svelte create mode 100644 src/ContextMenu/ContextMenuRadioGroup.svelte create mode 100644 src/ContextMenu/index.js create mode 100644 src/Popover/Popover.svelte create mode 100644 src/Popover/index.js create mode 100644 tests/ContextMenu.test.svelte create mode 100644 tests/Popover.test.svelte create mode 100644 types/ContextMenu/ContextMenu.d.ts create mode 100644 types/ContextMenu/ContextMenuDivider.d.ts create mode 100644 types/ContextMenu/ContextMenuGroup.d.ts create mode 100644 types/ContextMenu/ContextMenuOption.d.ts create mode 100644 types/ContextMenu/ContextMenuRadioGroup.d.ts create mode 100644 types/Popover/Popover.d.ts diff --git a/COMPONENT_INDEX.md b/COMPONENT_INDEX.md index 3543cdfd..370a62ae 100644 --- a/COMPONENT_INDEX.md +++ b/COMPONENT_INDEX.md @@ -1,6 +1,6 @@ # Component Index -> 160 components exported from carbon-components-svelte@0.30.0. +> 166 components exported from carbon-components-svelte@0.30.0. ## Components @@ -24,6 +24,11 @@ - [`ComposedModal`](#composedmodal) - [`Content`](#content) - [`ContentSwitcher`](#contentswitcher) +- [`ContextMenu`](#contextmenu) +- [`ContextMenuDivider`](#contextmenudivider) +- [`ContextMenuGroup`](#contextmenugroup) +- [`ContextMenuOption`](#contextmenuoption) +- [`ContextMenuRadioGroup`](#contextmenuradiogroup) - [`Copy`](#copy) - [`CopyButton`](#copybutton) - [`DataTable`](#datatable) @@ -93,6 +98,7 @@ - [`PaginationNav`](#paginationnav) - [`PaginationSkeleton`](#paginationskeleton) - [`PasswordInput`](#passwordinput) +- [`Popover`](#popover) - [`ProgressIndicator`](#progressindicator) - [`ProgressIndicatorSkeleton`](#progressindicatorskeleton) - [`ProgressStep`](#progressstep) @@ -722,6 +728,117 @@ None. | mouseenter | forwarded | -- | | mouseleave | forwarded | -- | +## `ContextMenu` + +### Props + +| Prop name | Kind | Reactive | Type | Default value | Description | +| :-------- | :--------------- | :------- | :---------------------------------------- | ------------------ | -------------------------------------------------------------------------------- | +| ref | let | Yes | null | HTMLUListElement | null | Obtain a reference to the unordered list HTML element | +| y | let | Yes | number | 0 | Specify the vertical offset of the menu position | +| x | let | Yes | number | 0 | Specify the horizontal offset of the menu position | +| open | let | Yes | boolean | false | Set to `true` to open the menu
Either `x` and `y` must be greater than zero | + +### Slots + +| Slot name | Default | Props | Fallback | +| :-------- | :------ | :---- | :------- | +| -- | Yes | -- | -- | + +### Events + +| Event name | Type | Detail | +| :--------- | :--------- | :----- | +| click | forwarded | -- | +| keydown | forwarded | -- | +| open | dispatched | -- | +| close | dispatched | -- | + +## `ContextMenuDivider` + +### Props + +None. + +### Slots + +None. + +### Events + +None. + +## `ContextMenuGroup` + +### Props + +| Prop name | Kind | Reactive | Type | Default value | Description | +| :---------- | :--------------- | :------- | :-------------------- | --------------- | ---------------------- | +| selectedIds | let | Yes | string[] | [] | -- | +| labelText | let | No | string | "" | Specify the label text | + +### Slots + +| Slot name | Default | Props | Fallback | +| :-------- | :------ | :---- | :------- | +| -- | Yes | -- | -- | + +### Events + +None. + +## `ContextMenuOption` + +### Props + +| Prop name | Kind | Reactive | Type | Default value | Description | +| :----------- | :--------------- | :------- | :----------------------------------------------------------- | ------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------- | +| ref | let | Yes | null | HTMLLIElement | null | Obtain a reference to the list item HTML element | +| selectable | let | Yes | boolean | false | Set to `true` to enable the selectable variant
Automatically set to `true` if `selected` is `true` | +| selected | let | Yes | boolean | false | Set to `true` to use the selected variant | +| icon | let | Yes | typeof import("carbon-icons-svelte").CarbonIcon | -- | Specify the icon from `carbon-icons-svelte` to render
Icon is rendered to the left of the label text | +| indented | let | Yes | boolean | false | Set to `true` to indent the label | +| disabled | let | No | boolean | false | Set to `true` to enable the disabled state | +| labelText | let | No | string | "" | Specify the label text
Alternatively, use the "labelText" slot (e.g., <span slot="labelText">...</span>) | +| shortcutText | let | No | string | "" | Specify the shortcut text
Alternatively, use the "shortcutText" slot (e.g., <span slot="shortcutText">...</span>) | +| id | let | No | string | "ccs-" + Math.random().toString(36) | Specify the id
It's recommended to provide an id as a value to bind to within a selectable/radio menu group | + +### Slots + +| Slot name | Default | Props | Fallback | +| :----------- | :------ | :---- | :-------------------------- | +| -- | Yes | -- | -- | +| labelText | No | -- | {labelText} | +| shortcutText | No | -- | {shortcutText} | + +### Events + +| Event name | Type | Detail | +| :--------- | :--------- | :----- | +| keydown | forwarded | -- | +| mouseenter | forwarded | -- | +| mouseleave | forwarded | -- | +| click | dispatched | -- | + +## `ContextMenuRadioGroup` + +### Props + +| Prop name | Kind | Reactive | Type | Default value | Description | +| :--------- | :--------------- | :------- | :------------------ | --------------- | ------------------------------- | +| selectedId | let | Yes | string | "" | Set the selected radio group id | +| labelText | let | No | string | "" | Specify the label text | + +### Slots + +| Slot name | Default | Props | Fallback | +| :-------- | :------ | :---- | :------- | +| -- | Yes | -- | -- | + +### Events + +None. + ## `Copy` ### Props @@ -2238,7 +2355,7 @@ None. | Event name | Type | Detail | | :--------- | :--------- | :-------------------------------------------------------------------------------------------------- | | select | dispatched | { selectedIds: string[]; selected: MultiSelectItem[]; unselected: MultiSelectItem[]; } | -| clear | forwarded | -- | +| clear | dispatched | any | | keydown | forwarded | -- | | focus | forwarded | -- | | blur | forwarded | -- | @@ -2541,9 +2658,11 @@ None. ### Events -| Event name | Type | Detail | -| :--------- | :--------- | :----------------------------------------------- | -| update | dispatched | { pageSize: number; page: number; } | +| Event name | Type | Detail | +| :--------------------- | :--------- | :----------------------------------------------- | +| update | dispatched | { pageSize: number; page: number; } | +| click:button--previous | dispatched | { page: number; } | +| click:button--next | dispatched | { page: number; } | ## `PaginationNav` @@ -2632,6 +2751,32 @@ None. | focus | forwarded | -- | | blur | forwarded | -- | +## `Popover` + +### Props + +| Prop name | Kind | Reactive | Type | Default value | Description | +| :------------------ | :--------------- | :------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------ | ------------------------------------------------------ | +| open | let | Yes | boolean | false | Set to `true` to display the popover | +| closeOnOutsideClick | let | No | boolean | false | Set to `true` to close the popover on an outside click | +| caret | let | No | boolean | false | Set to `true` render a caret | +| align | let | No | "top" | "top-left" | "top-right" | "bottom" | "bottom-left" | "bottom-right" | "left" | "left-bottom" | "left-top" | "right" | "right-bottom" | "right-top" | "top" | Specify the alignment of the caret | +| light | let | No | boolean | false | Set to `true` to enable the light variant | +| highContrast | let | No | boolean | false | Set to `true` to enable the high contrast variant | +| relative | let | No | boolean | false | Set to `true` to use a relative position | + +### Slots + +| Slot name | Default | Props | Fallback | +| :-------- | :------ | :---- | :------- | +| -- | Yes | -- | -- | + +### Events + +| Event name | Type | Detail | +| :------------ | :--------- | :----- | +| click:outside | dispatched | -- | + ## `ProgressIndicator` ### Props @@ -2920,6 +3065,8 @@ None. | name | let | No | string | -- | Specify a name attribute for the select element | | invalid | let | No | boolean | false | Set to `true` to indicate an invalid state | | invalidText | let | No | string | "" | Specify the invalid state text | +| warn | let | No | boolean | false | Set to `true` to indicate an warning state | +| warnText | let | No | string | "" | Specify the warning state text | | helperText | let | No | string | "" | Specify the helper text | | noLabel | let | No | boolean | false | Set to `true` to not render a label | | labelText | let | No | string | "" | Specify the label text | @@ -3682,9 +3829,10 @@ None. ### Props -| Prop name | Kind | Reactive | Type | Default value | Description | -| :-------- | :--------------- | :------- | :------------------ | -------------- | ------------------------------------ | -| count | let | No | number | 4 | Specify the number of tabs to render | +| Prop name | Kind | Reactive | Type | Default value | Description | +| :-------- | :--------------- | :------- | :---------------------------------------- | ---------------------- | ------------------------------------ | +| count | let | No | number | 4 | Specify the number of tabs to render | +| type | let | No | "default" | "container" | "default" | Specify the type of tabs | ### Slots diff --git a/docs/package.json b/docs/package.json index f4d109ec..36b8b1d1 100644 --- a/docs/package.json +++ b/docs/package.json @@ -11,7 +11,7 @@ "devDependencies": { "@sveltech/routify": "^1.9.9", "autoprefixer": "^10.2.3", - "carbon-components": "10.30.0", + "carbon-components": "10.31.0", "carbon-components-svelte": "../", "clipboard-copy": "^3.1.0", "mdsvex": "^0.8.8", diff --git a/docs/src/COMPONENT_API.json b/docs/src/COMPONENT_API.json index aee2c87c..393b36ab 100644 --- a/docs/src/COMPONENT_API.json +++ b/docs/src/COMPONENT_API.json @@ -1,5 +1,5 @@ { - "total": 160, + "total": 166, "components": [ { "moduleName": "Accordion", @@ -1556,6 +1556,244 @@ "typedefs": [], "rest_props": { "type": "Element", "name": "div" } }, + { + "moduleName": "ContextMenu", + "filePath": "src/ContextMenu/ContextMenu.svelte", + "props": [ + { + "name": "open", + "kind": "let", + "description": "Set to `true` to open the menu\nEither `x` and `y` must be greater than zero", + "type": "boolean", + "value": "false", + "isFunction": false, + "constant": false, + "reactive": true + }, + { + "name": "x", + "kind": "let", + "description": "Specify the horizontal offset of the menu position", + "type": "number", + "value": "0", + "isFunction": false, + "constant": false, + "reactive": true + }, + { + "name": "y", + "kind": "let", + "description": "Specify the vertical offset of the menu position", + "type": "number", + "value": "0", + "isFunction": false, + "constant": false, + "reactive": true + }, + { + "name": "ref", + "kind": "let", + "description": "Obtain a reference to the unordered list HTML element", + "type": "null | HTMLUListElement", + "value": "null", + "isFunction": false, + "constant": false, + "reactive": true + } + ], + "slots": [{ "name": "__default__", "default": true, "slot_props": "{}" }], + "events": [ + { "type": "forwarded", "name": "click", "element": "ul" }, + { "type": "forwarded", "name": "keydown", "element": "ul" }, + { "type": "dispatched", "name": "open" }, + { "type": "dispatched", "name": "close" } + ], + "typedefs": [], + "rest_props": { "type": "Element", "name": "ul" } + }, + { + "moduleName": "ContextMenuDivider", + "filePath": "src/ContextMenu/ContextMenuDivider.svelte", + "props": [], + "slots": [], + "events": [], + "typedefs": [] + }, + { + "moduleName": "ContextMenuGroup", + "filePath": "src/ContextMenu/ContextMenuGroup.svelte", + "props": [ + { + "name": "selectedIds", + "kind": "let", + "type": "string[]", + "value": "[]", + "isFunction": false, + "constant": false, + "reactive": true + }, + { + "name": "labelText", + "kind": "let", + "description": "Specify the label text", + "type": "string", + "value": "\"\"", + "isFunction": false, + "constant": false, + "reactive": false + } + ], + "slots": [{ "name": "__default__", "default": true, "slot_props": "{}" }], + "events": [], + "typedefs": [] + }, + { + "moduleName": "ContextMenuOption", + "filePath": "src/ContextMenu/ContextMenuOption.svelte", + "props": [ + { + "name": "disabled", + "kind": "let", + "description": "Set to `true` to enable the disabled state", + "type": "boolean", + "value": "false", + "isFunction": false, + "constant": false, + "reactive": false + }, + { + "name": "indented", + "kind": "let", + "description": "Set to `true` to indent the label", + "type": "boolean", + "value": "false", + "isFunction": false, + "constant": false, + "reactive": true + }, + { + "name": "icon", + "kind": "let", + "description": "Specify the icon from `carbon-icons-svelte` to render\nIcon is rendered to the left of the label text", + "type": "typeof import(\"carbon-icons-svelte\").CarbonIcon", + "isFunction": false, + "constant": false, + "reactive": true + }, + { + "name": "labelText", + "kind": "let", + "description": "Specify the label text\nAlternatively, use the \"labelText\" slot (e.g., ...)", + "type": "string", + "value": "\"\"", + "isFunction": false, + "constant": false, + "reactive": false + }, + { + "name": "selected", + "kind": "let", + "description": "Set to `true` to use the selected variant", + "type": "boolean", + "value": "false", + "isFunction": false, + "constant": false, + "reactive": true + }, + { + "name": "selectable", + "kind": "let", + "description": "Set to `true` to enable the selectable variant\nAutomatically set to `true` if `selected` is `true`", + "type": "boolean", + "value": "false", + "isFunction": false, + "constant": false, + "reactive": true + }, + { + "name": "shortcutText", + "kind": "let", + "description": "Specify the shortcut text\nAlternatively, use the \"shortcutText\" slot (e.g., ...)", + "type": "string", + "value": "\"\"", + "isFunction": false, + "constant": false, + "reactive": false + }, + { + "name": "id", + "kind": "let", + "description": "Specify the id\nIt's recommended to provide an id as a value to bind to within a selectable/radio menu group", + "type": "string", + "value": "\"ccs-\" + Math.random().toString(36)", + "isFunction": false, + "constant": false, + "reactive": false + }, + { + "name": "ref", + "kind": "let", + "description": "Obtain a reference to the list item HTML element", + "type": "null | HTMLLIElement", + "value": "null", + "isFunction": false, + "constant": false, + "reactive": true + } + ], + "slots": [ + { "name": "__default__", "default": true, "slot_props": "{}" }, + { + "name": "labelText", + "default": false, + "fallback": "{labelText}", + "slot_props": "{}" + }, + { + "name": "shortcutText", + "default": false, + "fallback": "{shortcutText}", + "slot_props": "{}" + } + ], + "events": [ + { "type": "forwarded", "name": "keydown", "element": "li" }, + { "type": "forwarded", "name": "mouseenter", "element": "li" }, + { "type": "forwarded", "name": "mouseleave", "element": "li" }, + { "type": "dispatched", "name": "click" } + ], + "typedefs": [], + "rest_props": { "type": "Element", "name": "li" } + }, + { + "moduleName": "ContextMenuRadioGroup", + "filePath": "src/ContextMenu/ContextMenuRadioGroup.svelte", + "props": [ + { + "name": "selectedId", + "kind": "let", + "description": "Set the selected radio group id", + "type": "string", + "value": "\"\"", + "isFunction": false, + "constant": false, + "reactive": true + }, + { + "name": "labelText", + "kind": "let", + "description": "Specify the label text", + "type": "string", + "value": "\"\"", + "isFunction": false, + "constant": false, + "reactive": false + } + ], + "slots": [{ "name": "__default__", "default": true, "slot_props": "{}" }], + "events": [], + "typedefs": [] + }, { "moduleName": "Copy", "filePath": "src/Copy/Copy.svelte", @@ -5539,7 +5777,7 @@ "name": "select", "detail": "{ selectedIds: string[]; selected: MultiSelectItem[]; unselected: MultiSelectItem[]; }" }, - { "type": "forwarded", "name": "clear", "element": "ListBoxSelection" }, + { "type": "dispatched", "name": "clear", "detail": "any" }, { "type": "forwarded", "name": "keydown", "element": "input" }, { "type": "forwarded", "name": "focus", "element": "input" }, { "type": "forwarded", "name": "blur", "element": "input" } @@ -6475,6 +6713,16 @@ "type": "dispatched", "name": "update", "detail": "{ pageSize: number; page: number; }" + }, + { + "type": "dispatched", + "name": "click:button--previous", + "detail": "{ page: number; }" + }, + { + "type": "dispatched", + "name": "click:button--next", + "detail": "{ page: number; }" } ], "typedefs": [], @@ -6778,6 +7026,86 @@ "typedefs": [], "rest_props": { "type": "Element", "name": "input" } }, + { + "moduleName": "Popover", + "filePath": "src/Popover/Popover.svelte", + "props": [ + { + "name": "open", + "kind": "let", + "description": "Set to `true` to display the popover", + "type": "boolean", + "value": "false", + "isFunction": false, + "constant": false, + "reactive": true + }, + { + "name": "closeOnOutsideClick", + "kind": "let", + "description": "Set to `true` to close the popover on an outside click", + "type": "boolean", + "value": "false", + "isFunction": false, + "constant": false, + "reactive": false + }, + { + "name": "caret", + "kind": "let", + "description": "Set to `true` render a caret", + "type": "boolean", + "value": "false", + "isFunction": false, + "constant": false, + "reactive": false + }, + { + "name": "align", + "kind": "let", + "description": "Specify the alignment of the caret", + "type": "\"top\" | \"top-left\" | \"top-right\" | \"bottom\" | \"bottom-left\" | \"bottom-right\" | \"left\" | \"left-bottom\" | \"left-top\" | \"right\" | \"right-bottom\" | \"right-top\"", + "value": "\"top\"", + "isFunction": false, + "constant": false, + "reactive": false + }, + { + "name": "light", + "kind": "let", + "description": "Set to `true` to enable the light variant", + "type": "boolean", + "value": "false", + "isFunction": false, + "constant": false, + "reactive": false + }, + { + "name": "highContrast", + "kind": "let", + "description": "Set to `true` to enable the high contrast variant", + "type": "boolean", + "value": "false", + "isFunction": false, + "constant": false, + "reactive": false + }, + { + "name": "relative", + "kind": "let", + "description": "Set to `true` to use a relative position", + "type": "boolean", + "value": "false", + "isFunction": false, + "constant": false, + "reactive": false + } + ], + "slots": [{ "name": "__default__", "default": true, "slot_props": "{}" }], + "events": [{ "type": "dispatched", "name": "click:outside" }], + "typedefs": [], + "rest_props": { "type": "Element", "name": "div" } + }, { "moduleName": "ProgressIndicator", "filePath": "src/ProgressIndicator/ProgressIndicator.svelte", @@ -7638,6 +7966,26 @@ "constant": false, "reactive": false }, + { + "name": "warn", + "kind": "let", + "description": "Set to `true` to indicate an warning state", + "type": "boolean", + "value": "false", + "isFunction": false, + "constant": false, + "reactive": false + }, + { + "name": "warnText", + "kind": "let", + "description": "Specify the warning state text", + "type": "string", + "value": "\"\"", + "isFunction": false, + "constant": false, + "reactive": false + }, { "name": "helperText", "kind": "let", @@ -9148,6 +9496,16 @@ "isFunction": false, "constant": false, "reactive": false + }, + { + "name": "type", + "kind": "let", + "description": "Specify the type of tabs", + "type": "\"default\" | \"container\"", + "value": "\"default\"", + "isFunction": false, + "constant": false, + "reactive": false } ], "slots": [], diff --git a/docs/src/components/Preview.svelte b/docs/src/components/Preview.svelte index f9fc8d16..481a4f2b 100644 --- a/docs/src/components/Preview.svelte +++ b/docs/src/components/Preview.svelte @@ -55,6 +55,10 @@ max-width: 56rem; } + .code-override .bx--snippet { + max-width: none; + } + .code-override .bx--copy-btn, .code-override .bx--snippet, .code-override button.bx--btn.bx--snippet-btn--expand { diff --git a/docs/src/layouts/ComponentLayout.svelte b/docs/src/layouts/ComponentLayout.svelte index 238f0a52..5ce07727 100644 --- a/docs/src/layouts/ComponentLayout.svelte +++ b/docs/src/layouts/ComponentLayout.svelte @@ -208,7 +208,12 @@ } } - .preview-viewer > .bx--aspect-ratio { + .preview-viewer > .bx--aspect-ratio, + .preview-viewer [data-outline] { outline: 1px solid var(--cds-interactive-04); } + + [data-outline] { + position: relative; + } diff --git a/docs/src/pages/_layout.svelte b/docs/src/pages/_layout.svelte index 3b1a616d..bb4359af 100644 --- a/docs/src/pages/_layout.svelte +++ b/docs/src/pages/_layout.svelte @@ -20,7 +20,7 @@ import Footer from "../components/Footer.svelte"; const deprecated = ["ToggleSmall", "Icon"]; - const new_components = ["ImageLoader", "LocalStorage"]; + const new_components = ["Popover", "ContextMenu"]; let isOpen = false; let isSideNavOpen = true; @@ -105,10 +105,18 @@ > {child.title} {#if deprecated.includes(child.title)} - Deprecated + + Deprecated + {/if} {#if new_components.includes(child.title)} - New + + New + {/if} {/each} diff --git a/docs/src/pages/components/Accordion.svx b/docs/src/pages/components/Accordion.svx index 3db70d63..078fd257 100644 --- a/docs/src/pages/components/Accordion.svx +++ b/docs/src/pages/components/Accordion.svx @@ -27,7 +27,7 @@ See the [ExpandableAccordion recipe](/recipes/ExpandableAccordion) for a togglea -### Chevron aligned left +### Left-aligned chevron @@ -148,7 +148,7 @@ See the [ExpandableAccordion recipe](/recipes/ExpandableAccordion) for a togglea -### Skeleton (chevron aligned left) +### Skeleton (left-aligned chevron) diff --git a/docs/src/pages/components/ContextMenu.svx b/docs/src/pages/components/ContextMenu.svx new file mode 100644 index 00000000..d195fd63 --- /dev/null +++ b/docs/src/pages/components/ContextMenu.svx @@ -0,0 +1,17 @@ +--- +components: ["ContextMenu", "ContextMenuGroup", "ContextMenuRadioGroup", "ContextMenuOption", "ContextMenuDivider"] +--- + + + +In the examples, right click anywhere within the iframe. + +### Default + + + +### Radio groups + + \ No newline at end of file diff --git a/docs/src/pages/components/Popover.svx b/docs/src/pages/components/Popover.svx new file mode 100644 index 00000000..4a27c5f8 --- /dev/null +++ b/docs/src/pages/components/Popover.svx @@ -0,0 +1,77 @@ + + +### Default + +By default, the position of the popover component is absolute. + +
+ Parent + +
Content
+
+
+ +### Relative position + +Set `relative` to `true` to use a relative position. + +
+ Parent + +
Content
+
+
+ +### Close on outside click + +Set `closeOnOutsideClick` to set `open` to `false` when clicking outside of the popover. + +
+ Parent + {console.log('on:click:outside')}}> +
Content
+
+
+ +### With caret + +
+ Parent + +
Content
+
+
+ +### Custom caret alignment + +By default, the caret is aligned "top". + +Possible `align` values include `"top"`, `"top-left"`, `"top-right"`, `"bottom"`, `"bottom-left"`, `"bottom-right"`, `"left"`, `"left-bottom"`, `"left-top"`, `"right"`, `"right-bottom"` or `"right-top"`. + +
+ Parent + +
Content
+
+
+ +### Light variant + +
+ Parent + +
Content
+
+
+ +### High contrast variant + +
+ Parent + +
Content
+
+
\ No newline at end of file diff --git a/docs/src/pages/components/RadioButton.svx b/docs/src/pages/components/RadioButton.svx index 54ec568d..aac4ea1d 100644 --- a/docs/src/pages/components/RadioButton.svx +++ b/docs/src/pages/components/RadioButton.svx @@ -47,7 +47,7 @@ Bind the selected value using the `selected` prop. -### Label text aligned left +### Left-aligned label text @@ -55,6 +55,14 @@ Bind the selected value using the `selected` prop. +### Disabled buttons + + + + + + + ### Vertical orientation @@ -71,7 +79,7 @@ Bind the selected value using the `selected` prop. -### Skeleton (vertical orientation) +### Skeleton (vertical) diff --git a/docs/src/pages/components/Select.svx b/docs/src/pages/components/Select.svx index 40e3aa3e..e28a802e 100644 --- a/docs/src/pages/components/Select.svx +++ b/docs/src/pages/components/Select.svx @@ -16,6 +16,15 @@ components: ["Select", "SelectItem", "SelectItemGroup", "SelectSkeleton"] +### Helper text + + + ### Hidden label -### Disabled +### Invalid state + + + +### Warning state + + + +### Disabled state - {/if} + diff --git a/src/StructuredList/StructuredListBody.svelte b/src/StructuredList/StructuredListBody.svelte index ada53bc7..fea51476 100644 --- a/src/StructuredList/StructuredListBody.svelte +++ b/src/StructuredList/StructuredListBody.svelte @@ -1,5 +1,6 @@
/** Specify the number of tabs to render */ export let count = 4; + + /** + * Specify the type of tabs + * @type {"default" | "container"} + */ + export let type = "default";
-
-
 
- - - -
-
    - {#each Array.from({ length: count }, (_, i) => i) as item, i (item)} -
  • -
     
    +
      + {#each Array.from({ length: count }, (_, i) => i) as item} +
    • +
      + +
    • {/each}
    diff --git a/src/index.js b/src/index.js index b0574d4c..f3a347f4 100644 --- a/src/index.js +++ b/src/index.js @@ -4,6 +4,13 @@ export { Breadcrumb, BreadcrumbItem, BreadcrumbSkeleton } from "./Breadcrumb"; export { Button, ButtonSkeleton, ButtonSet } from "./Button"; export { Checkbox, CheckboxSkeleton } from "./Checkbox"; export { ContentSwitcher, Switch } from "./ContentSwitcher"; +export { + ContextMenu, + ContextMenuDivider, + ContextMenuGroup, + ContextMenuOption, + ContextMenuRadioGroup, +} from "./ContextMenu"; export { Copy } from "./Copy"; export { CopyButton } from "./CopyButton"; export { ComboBox } from "./ComboBox"; @@ -77,6 +84,7 @@ export { OrderedList } from "./OrderedList"; export { OverflowMenu, OverflowMenuItem } from "./OverflowMenu"; export { Pagination, PaginationSkeleton } from "./Pagination"; export { PaginationNav } from "./PaginationNav"; +export { Popover } from "./Popover"; export { ProgressIndicator, ProgressIndicatorSkeleton, diff --git a/tests/ContextMenu.test.svelte b/tests/ContextMenu.test.svelte new file mode 100644 index 00000000..fec21aa5 --- /dev/null +++ b/tests/ContextMenu.test.svelte @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/LocalStorage.test.svelte b/tests/LocalStorage.test.svelte index b9a61635..b3268fd8 100644 --- a/tests/LocalStorage.test.svelte +++ b/tests/LocalStorage.test.svelte @@ -1,7 +1,7 @@ diff --git a/tests/Popover.test.svelte b/tests/Popover.test.svelte new file mode 100644 index 00000000..ea2c42d2 --- /dev/null +++ b/tests/Popover.test.svelte @@ -0,0 +1,20 @@ + + + +
    Content
    +
    diff --git a/types/ContextMenu/ContextMenu.d.ts b/types/ContextMenu/ContextMenu.d.ts new file mode 100644 index 00000000..17a4b547 --- /dev/null +++ b/types/ContextMenu/ContextMenu.d.ts @@ -0,0 +1,41 @@ +/// +import { SvelteComponentTyped } from "svelte"; + +export interface ContextMenuProps + extends svelte.JSX.HTMLAttributes { + /** + * Set to `true` to open the menu + * Either `x` and `y` must be greater than zero + * @default false + */ + open?: boolean; + + /** + * Specify the horizontal offset of the menu position + * @default 0 + */ + x?: number; + + /** + * Specify the vertical offset of the menu position + * @default 0 + */ + y?: number; + + /** + * Obtain a reference to the unordered list HTML element + * @default null + */ + ref?: null | HTMLUListElement; +} + +export default class ContextMenu extends SvelteComponentTyped< + ContextMenuProps, + { + click: WindowEventMap["click"]; + keydown: WindowEventMap["keydown"]; + open: CustomEvent; + close: CustomEvent; + }, + { default: {} } +> {} diff --git a/types/ContextMenu/ContextMenuDivider.d.ts b/types/ContextMenu/ContextMenuDivider.d.ts new file mode 100644 index 00000000..24aa8ed7 --- /dev/null +++ b/types/ContextMenu/ContextMenuDivider.d.ts @@ -0,0 +1,10 @@ +/// +import { SvelteComponentTyped } from "svelte"; + +export interface ContextMenuDividerProps {} + +export default class ContextMenuDivider extends SvelteComponentTyped< + ContextMenuDividerProps, + {}, + {} +> {} diff --git a/types/ContextMenu/ContextMenuGroup.d.ts b/types/ContextMenu/ContextMenuGroup.d.ts new file mode 100644 index 00000000..bbe0f5d3 --- /dev/null +++ b/types/ContextMenu/ContextMenuGroup.d.ts @@ -0,0 +1,21 @@ +/// +import { SvelteComponentTyped } from "svelte"; + +export interface ContextMenuGroupProps { + /** + * @default [] + */ + selectedIds?: string[]; + + /** + * Specify the label text + * @default "" + */ + labelText?: string; +} + +export default class ContextMenuGroup extends SvelteComponentTyped< + ContextMenuGroupProps, + {}, + { default: {} } +> {} diff --git a/types/ContextMenu/ContextMenuOption.d.ts b/types/ContextMenu/ContextMenuOption.d.ts new file mode 100644 index 00000000..b6763f33 --- /dev/null +++ b/types/ContextMenu/ContextMenuOption.d.ts @@ -0,0 +1,74 @@ +/// +import { SvelteComponentTyped } from "svelte"; + +export interface ContextMenuOptionProps + extends svelte.JSX.HTMLAttributes { + /** + * Set to `true` to enable the disabled state + * @default false + */ + disabled?: boolean; + + /** + * Set to `true` to indent the label + * @default false + */ + indented?: boolean; + + /** + * Specify the icon from `carbon-icons-svelte` to render + * Icon is rendered to the left of the label text + */ + icon?: typeof import("carbon-icons-svelte").CarbonIcon; + + /** + * Specify the label text + * Alternatively, use the "labelText" slot (e.g., ...) + * @default "" + */ + labelText?: string; + + /** + * Set to `true` to use the selected variant + * @default false + */ + selected?: boolean; + + /** + * Set to `true` to enable the selectable variant + * Automatically set to `true` if `selected` is `true` + * @default false + */ + selectable?: boolean; + + /** + * Specify the shortcut text + * Alternatively, use the "shortcutText" slot (e.g., ...) + * @default "" + */ + shortcutText?: string; + + /** + * Specify the id + * It's recommended to provide an id as a value to bind to within a selectable/radio menu group + * @default "ccs-" + Math.random().toString(36) + */ + id?: string; + + /** + * Obtain a reference to the list item HTML element + * @default null + */ + ref?: null | HTMLLIElement; +} + +export default class ContextMenuOption extends SvelteComponentTyped< + ContextMenuOptionProps, + { + keydown: WindowEventMap["keydown"]; + mouseenter: WindowEventMap["mouseenter"]; + mouseleave: WindowEventMap["mouseleave"]; + click: CustomEvent; + }, + { default: {}; labelText: {}; shortcutText: {} } +> {} diff --git a/types/ContextMenu/ContextMenuRadioGroup.d.ts b/types/ContextMenu/ContextMenuRadioGroup.d.ts new file mode 100644 index 00000000..8ea1c9a7 --- /dev/null +++ b/types/ContextMenu/ContextMenuRadioGroup.d.ts @@ -0,0 +1,22 @@ +/// +import { SvelteComponentTyped } from "svelte"; + +export interface ContextMenuRadioGroupProps { + /** + * Set the selected radio group id + * @default "" + */ + selectedId?: string; + + /** + * Specify the label text + * @default "" + */ + labelText?: string; +} + +export default class ContextMenuRadioGroup extends SvelteComponentTyped< + ContextMenuRadioGroupProps, + {}, + { default: {} } +> {} diff --git a/types/MultiSelect/MultiSelect.d.ts b/types/MultiSelect/MultiSelect.d.ts index 872702d8..9d89e4ec 100644 --- a/types/MultiSelect/MultiSelect.d.ts +++ b/types/MultiSelect/MultiSelect.d.ts @@ -184,7 +184,7 @@ export default class MultiSelect extends SvelteComponentTyped< selected: MultiSelectItem[]; unselected: MultiSelectItem[]; }>; - clear: WindowEventMap["clear"]; + clear: CustomEvent; keydown: WindowEventMap["keydown"]; focus: WindowEventMap["focus"]; blur: WindowEventMap["blur"]; diff --git a/types/Pagination/Pagination.d.ts b/types/Pagination/Pagination.d.ts index 95c5f392..3918f385 100644 --- a/types/Pagination/Pagination.d.ts +++ b/types/Pagination/Pagination.d.ts @@ -102,6 +102,10 @@ export interface PaginationProps export default class Pagination extends SvelteComponentTyped< PaginationProps, - { update: CustomEvent<{ pageSize: number; page: number }> }, + { + update: CustomEvent<{ pageSize: number; page: number }>; + ["click:button--previous"]: CustomEvent<{ page: number }>; + ["click:button--next"]: CustomEvent<{ page: number }>; + }, {} > {} diff --git a/types/Popover/Popover.d.ts b/types/Popover/Popover.d.ts new file mode 100644 index 00000000..f8feec0d --- /dev/null +++ b/types/Popover/Popover.d.ts @@ -0,0 +1,65 @@ +/// +import { SvelteComponentTyped } from "svelte"; + +export interface PopoverProps + extends svelte.JSX.HTMLAttributes { + /** + * Set to `true` to display the popover + * @default false + */ + open?: boolean; + + /** + * Set to `true` to close the popover on an outside click + * @default false + */ + closeOnOutsideClick?: boolean; + + /** + * Set to `true` render a caret + * @default false + */ + caret?: boolean; + + /** + * Specify the alignment of the caret + * @default "top" + */ + align?: + | "top" + | "top-left" + | "top-right" + | "bottom" + | "bottom-left" + | "bottom-right" + | "left" + | "left-bottom" + | "left-top" + | "right" + | "right-bottom" + | "right-top"; + + /** + * Set to `true` to enable the light variant + * @default false + */ + light?: boolean; + + /** + * Set to `true` to enable the high contrast variant + * @default false + */ + highContrast?: boolean; + + /** + * Set to `true` to use a relative position + * @default false + */ + relative?: boolean; +} + +export default class Popover extends SvelteComponentTyped< + PopoverProps, + { ["click:outside"]: CustomEvent }, + { default: {} } +> {} diff --git a/types/Select/Select.d.ts b/types/Select/Select.d.ts index 914b462a..93bc7546 100644 --- a/types/Select/Select.d.ts +++ b/types/Select/Select.d.ts @@ -54,6 +54,18 @@ export interface SelectProps */ 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 "" diff --git a/types/Tabs/TabsSkeleton.d.ts b/types/Tabs/TabsSkeleton.d.ts index c6abc7a5..d9ff46dd 100644 --- a/types/Tabs/TabsSkeleton.d.ts +++ b/types/Tabs/TabsSkeleton.d.ts @@ -8,6 +8,12 @@ export interface TabsSkeletonProps * @default 4 */ count?: number; + + /** + * Specify the type of tabs + * @default "default" + */ + type?: "default" | "container"; } export default class TabsSkeleton extends SvelteComponentTyped< diff --git a/types/index.d.ts b/types/index.d.ts index 16073c71..cf20c00d 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -12,6 +12,11 @@ export { default as Checkbox } from "./Checkbox/Checkbox"; export { default as CheckboxSkeleton } from "./Checkbox/CheckboxSkeleton"; export { default as ContentSwitcher } from "./ContentSwitcher/ContentSwitcher"; export { default as Switch } from "./ContentSwitcher/Switch"; +export { default as ContextMenu } from "./ContextMenu/ContextMenu"; +export { default as ContextMenuDivider } from "./ContextMenu/ContextMenuDivider"; +export { default as ContextMenuGroup } from "./ContextMenu/ContextMenuGroup"; +export { default as ContextMenuOption } from "./ContextMenu/ContextMenuOption"; +export { default as ContextMenuRadioGroup } from "./ContextMenu/ContextMenuRadioGroup"; export { default as Copy } from "./Copy/Copy"; export { default as CopyButton } from "./CopyButton/CopyButton"; export { default as ComboBox } from "./ComboBox/ComboBox"; @@ -86,6 +91,7 @@ export { default as OverflowMenuItem } from "./OverflowMenu/OverflowMenuItem"; export { default as Pagination } from "./Pagination/Pagination"; export { default as PaginationSkeleton } from "./Pagination/PaginationSkeleton"; export { default as PaginationNav } from "./PaginationNav/PaginationNav"; +export { default as Popover } from "./Popover/Popover"; export { default as ProgressIndicator } from "./ProgressIndicator/ProgressIndicator"; export { default as ProgressIndicatorSkeleton } from "./ProgressIndicator/ProgressIndicatorSkeleton"; export { default as ProgressStep } from "./ProgressIndicator/ProgressStep"; diff --git a/yarn.lock b/yarn.lock index 635a2915..50ad392c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -453,20 +453,20 @@ 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.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== +carbon-components@10.31.0: + version "10.31.0" + resolved "https://registry.yarnpkg.com/carbon-components/-/carbon-components-10.31.0.tgz#050751e7fb4d845b7d1c6e8ac7fdfa9c71403c12" + integrity sha512-gUXRky9rUHavqFLJJQf+Lzouk8GHsXJUjxRgTOUQ6vdBfA0ks6ugwptG8fiFGwCJJht/CW9/YsKb5w8N9a39sg== dependencies: "@carbon/telemetry" "0.0.0-alpha.6" flatpickr "4.6.1" lodash.debounce "^4.0.8" warning "^3.0.0" -carbon-icons-svelte@^10.21.0: - version "10.21.0" - resolved "https://registry.npmjs.org/carbon-icons-svelte/-/carbon-icons-svelte-10.21.0.tgz#9bbdd37d5513d484e9706d6335c121f60f3186c4" - integrity sha512-5NNaRdmbS4N36dUGNj72Ys3VqVjH3fZ69AhYUHx+bH02GFYCwAaE49qjtP77kP7DKMtDV9NmMEti/P/JB83aYQ== +carbon-icons-svelte@^10.27.0: + version "10.27.0" + resolved "https://registry.yarnpkg.com/carbon-icons-svelte/-/carbon-icons-svelte-10.27.0.tgz#918e806d09e0e9cf61cf756ff0f9be49125ff9ea" + integrity sha512-e3l95wurOuEYMQxaDT2oYH322yRKgvTq5TDkzvylMGlCkA8erJH5lSwCM59VNFgPtptH4fIW9FlbQtpfp4iQ7Q== chalk@^2.0.0, chalk@^2.4.1: version "2.4.2"