mirror of
https://github.com/carbon-design-system/carbon-components-svelte.git
synced 2025-09-18 11:36:36 +00:00
Merge 9ac8e34241
into 338f651178
This commit is contained in:
commit
1e01f51387
4 changed files with 89 additions and 23 deletions
|
@ -1505,6 +1505,18 @@
|
||||||
"constant": false,
|
"constant": false,
|
||||||
"reactive": true
|
"reactive": true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "allowArbitraryValues",
|
||||||
|
"kind": "let",
|
||||||
|
"description": "Set to `true` to allow values that aren't included in `items`",
|
||||||
|
"type": "boolean",
|
||||||
|
"value": "false",
|
||||||
|
"isFunction": false,
|
||||||
|
"isFunctionDeclaration": false,
|
||||||
|
"isRequired": false,
|
||||||
|
"constant": false,
|
||||||
|
"reactive": false
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "direction",
|
"name": "direction",
|
||||||
"kind": "let",
|
"kind": "let",
|
||||||
|
|
|
@ -34,6 +34,19 @@ items={[
|
||||||
{id: "2", text: "Fax"}
|
{id: "2", text: "Fax"}
|
||||||
]} />
|
]} />
|
||||||
|
|
||||||
|
## Arbitrary Values
|
||||||
|
|
||||||
|
Set `allowArbitraryValues` to `true` to allow the user to type in whatever value they want, even if it's not present in `items`.
|
||||||
|
`selectedId` will be set to `undefined` when the value is arbitrary.
|
||||||
|
|
||||||
|
<ComboBox allowArbitraryValues titleText="Contact" placeholder="Select contact method"
|
||||||
|
selectedId="1"
|
||||||
|
items={[
|
||||||
|
{id: "0", text: "Slack"},
|
||||||
|
{id: "1", text: "Email"},
|
||||||
|
{id: "2", text: "Fax"}
|
||||||
|
]} />
|
||||||
|
|
||||||
## Reactive example
|
## Reactive example
|
||||||
|
|
||||||
<FileSource src="/framed/ComboBox/ReactiveComboBox" />
|
<FileSource src="/framed/ComboBox/ReactiveComboBox" />
|
||||||
|
|
|
@ -120,6 +120,11 @@
|
||||||
resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.19.9.tgz#b2da6219b603e3fa371a78f53f5361260d0c5585"
|
resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.19.9.tgz#b2da6219b603e3fa371a78f53f5361260d0c5585"
|
||||||
integrity sha512-oxoQgglOP7RH6iasDrhY+R/3cHrfwIDvRlT4CGChflq6twk8iENeVvMJjmvBb94Ik1Z+93iGO27err7w6l54GQ==
|
integrity sha512-oxoQgglOP7RH6iasDrhY+R/3cHrfwIDvRlT4CGChflq6twk8iENeVvMJjmvBb94Ik1Z+93iGO27err7w6l54GQ==
|
||||||
|
|
||||||
|
"@ibm/telemetry-js@^1.2.1":
|
||||||
|
version "1.3.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@ibm/telemetry-js/-/telemetry-js-1.3.0.tgz#321f2ed4bbbc78d69dc1ee9cb6f83d2d2af9baef"
|
||||||
|
integrity sha512-9gIkyF2B9RizWN6rsdQN76DN6D+/Xbr4HGTwm6EUujfXvEVtWbf4jzxDFwKvZkeTC2tjHpkUNJQKdivbMKt8yg==
|
||||||
|
|
||||||
"@jridgewell/gen-mapping@^0.3.0":
|
"@jridgewell/gen-mapping@^0.3.0":
|
||||||
version "0.3.3"
|
version "0.3.3"
|
||||||
resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz#7e02e6eb5df901aaedb08514203b096614024098"
|
resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz#7e02e6eb5df901aaedb08514203b096614024098"
|
||||||
|
@ -399,8 +404,9 @@ bufferutil@^4.0.1:
|
||||||
node-gyp-build "~3.7.0"
|
node-gyp-build "~3.7.0"
|
||||||
|
|
||||||
carbon-components-svelte@../:
|
carbon-components-svelte@../:
|
||||||
version "0.82.5"
|
version "0.84.1"
|
||||||
dependencies:
|
dependencies:
|
||||||
|
"@ibm/telemetry-js" "^1.2.1"
|
||||||
flatpickr "4.6.9"
|
flatpickr "4.6.9"
|
||||||
|
|
||||||
carbon-icons-svelte@^12.4.1:
|
carbon-icons-svelte@^12.4.1:
|
||||||
|
|
|
@ -27,6 +27,12 @@
|
||||||
/** Specify the selected combobox value */
|
/** Specify the selected combobox value */
|
||||||
export let value = "";
|
export let value = "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allow values that aren't in `items`.
|
||||||
|
* @type {boolean}
|
||||||
|
*/
|
||||||
|
export let allowArbitraryValues = false
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specify the direction of the combobox dropdown menu
|
* Specify the direction of the combobox dropdown menu
|
||||||
* @type {"bottom" | "top"}
|
* @type {"bottom" | "top"}
|
||||||
|
@ -107,7 +113,7 @@
|
||||||
*/
|
*/
|
||||||
export let listRef = null;
|
export let listRef = null;
|
||||||
|
|
||||||
import { createEventDispatcher, afterUpdate, tick } from "svelte";
|
import { createEventDispatcher, afterUpdate, tick, onMount } from "svelte";
|
||||||
import Checkmark from "../icons/Checkmark.svelte";
|
import Checkmark from "../icons/Checkmark.svelte";
|
||||||
import WarningFilled from "../icons/WarningFilled.svelte";
|
import WarningFilled from "../icons/WarningFilled.svelte";
|
||||||
import WarningAltFilled from "../icons/WarningAltFilled.svelte";
|
import WarningAltFilled from "../icons/WarningAltFilled.svelte";
|
||||||
|
@ -165,6 +171,12 @@
|
||||||
if (options?.focus !== false) ref?.focus();
|
if (options?.focus !== false) ref?.focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
if (selectedItem) {
|
||||||
|
value = itemToString(selectedItem)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
afterUpdate(() => {
|
afterUpdate(() => {
|
||||||
if (open) {
|
if (open) {
|
||||||
ref.focus();
|
ref.focus();
|
||||||
|
@ -172,14 +184,16 @@
|
||||||
} else {
|
} else {
|
||||||
highlightedIndex = -1;
|
highlightedIndex = -1;
|
||||||
filteredItems = [];
|
filteredItems = [];
|
||||||
if (!selectedItem) {
|
if (!allowArbitraryValues) {
|
||||||
selectedId = undefined;
|
if (!selectedItem) {
|
||||||
value = "";
|
selectedId = undefined;
|
||||||
highlightedIndex = -1;
|
value = "";
|
||||||
highlightedId = undefined;
|
highlightedIndex = -1;
|
||||||
} else {
|
highlightedId = undefined;
|
||||||
// programmatically set value
|
} else {
|
||||||
value = itemToString(selectedItem);
|
// programmatically set value
|
||||||
|
value = itemToString(selectedItem);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -202,6 +216,39 @@
|
||||||
selectedItem = undefined;
|
selectedItem = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function searchForMatchingValue() {
|
||||||
|
// searching typed value in text list with lowercase
|
||||||
|
let matchedItem =
|
||||||
|
filteredItems.find(
|
||||||
|
(e) =>
|
||||||
|
e.text.toLowerCase() === value?.toLowerCase() && !e.disabled
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!allowArbitraryValues) {
|
||||||
|
// typed value has matched or fallback to first enabled item
|
||||||
|
matchedItem = matchedItem ?? filteredItems.find((e) => !e.disabled);
|
||||||
|
if (matchedItem) setMatchedItem(matchedItem)
|
||||||
|
} else {
|
||||||
|
// When allowing arbitrary values, we still want to select a value if the user types in one that exists.
|
||||||
|
// But if it doesn't exist, we don't try to fallback to another value.
|
||||||
|
if (matchedItem) {
|
||||||
|
setMatchedItem(matchedItem)
|
||||||
|
} else {
|
||||||
|
open = false;
|
||||||
|
selectedItem = undefined;
|
||||||
|
selectedId = undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @param item {ComboBoxItem}*/
|
||||||
|
function setMatchedItem(item) {
|
||||||
|
open = false;
|
||||||
|
selectedItem = item;
|
||||||
|
value = itemToString(selectedItem);
|
||||||
|
selectedId = selectedItem.id;
|
||||||
|
}
|
||||||
|
|
||||||
$: ariaLabel = $$props["aria-label"] || "Choose an item";
|
$: ariaLabel = $$props["aria-label"] || "Choose an item";
|
||||||
$: menuId = `menu-${id}`;
|
$: menuId = `menu-${id}`;
|
||||||
$: comboId = `combo-${id}`;
|
$: comboId = `combo-${id}`;
|
||||||
|
@ -305,19 +352,7 @@
|
||||||
selectedId = filteredItems[highlightedIndex].id;
|
selectedId = filteredItems[highlightedIndex].id;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// searching typed value in text list with lowercase
|
searchForMatchingValue()
|
||||||
const matchedItem =
|
|
||||||
filteredItems.find(
|
|
||||||
(e) =>
|
|
||||||
e.text.toLowerCase() === value?.toLowerCase() && !e.disabled
|
|
||||||
) ?? filteredItems.find((e) => !e.disabled);
|
|
||||||
if (matchedItem) {
|
|
||||||
// typed value has matched or fallback to first enabled item
|
|
||||||
open = false;
|
|
||||||
selectedItem = matchedItem;
|
|
||||||
value = itemToString(selectedItem);
|
|
||||||
selectedId = selectedItem.id;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
highlightedIndex = -1;
|
highlightedIndex = -1;
|
||||||
} else if (key === 'Tab') {
|
} else if (key === 'Tab') {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue