mirror of
https://github.com/carbon-design-system/carbon-components-svelte.git
synced 2025-09-15 02:11:05 +00:00
Refactor UI Shell global search component (#417)
* feat(ui-shell): refactor UI Shell search component * fix(ui-shell): dispatched event is "select", not "search" * test(header-search): validate HeaderSearch types * fix(header-search): selecting a result should reset the search * feat(header-search): deefault selectedResultIndex should be 0 Reset selectedResultIndex, value after dispatching. * docs(header-search): demo basic filtering * chore: rebuild types, docs * feat(header-search): pass index as a slot prop
This commit is contained in:
parent
b7bf9ea1f0
commit
30cfc842d5
12 changed files with 737 additions and 5 deletions
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"total": 154,
|
||||
"total": 155,
|
||||
"components": [
|
||||
{
|
||||
"moduleName": "SkeletonText",
|
||||
|
@ -10258,6 +10258,93 @@
|
|||
"typedefs": [],
|
||||
"rest_props": { "type": "Element", "name": "button" }
|
||||
},
|
||||
{
|
||||
"moduleName": "HeaderSearch",
|
||||
"filePath": "/src/UIShell/HeaderSearch.svelte",
|
||||
"props": [
|
||||
{
|
||||
"name": "value",
|
||||
"kind": "let",
|
||||
"description": "Specify the search input value",
|
||||
"type": "string",
|
||||
"value": "\"\"",
|
||||
"isFunction": false,
|
||||
"constant": false,
|
||||
"reactive": true
|
||||
},
|
||||
{
|
||||
"name": "active",
|
||||
"kind": "let",
|
||||
"description": "Set to `true` to activate and focus the search bar",
|
||||
"type": "boolean",
|
||||
"value": "false",
|
||||
"isFunction": false,
|
||||
"constant": false,
|
||||
"reactive": true
|
||||
},
|
||||
{
|
||||
"name": "ref",
|
||||
"kind": "let",
|
||||
"description": "Obtain a reference to the input HTML element",
|
||||
"type": "null | HTMLInputElement",
|
||||
"value": "null",
|
||||
"isFunction": false,
|
||||
"constant": false,
|
||||
"reactive": true
|
||||
},
|
||||
{
|
||||
"name": "results",
|
||||
"kind": "let",
|
||||
"description": "Render a list of search results",
|
||||
"type": "HeaderSearchResult[]",
|
||||
"value": "[]",
|
||||
"isFunction": false,
|
||||
"constant": false,
|
||||
"reactive": false
|
||||
},
|
||||
{
|
||||
"name": "selectedResultIndex",
|
||||
"kind": "let",
|
||||
"description": "Specify the selected result index",
|
||||
"type": "number",
|
||||
"value": "0",
|
||||
"isFunction": false,
|
||||
"constant": false,
|
||||
"reactive": true
|
||||
}
|
||||
],
|
||||
"slots": [
|
||||
{
|
||||
"name": "__default__",
|
||||
"default": true,
|
||||
"fallback": "{result.text}\n {#if result.description}<span>– {result.description}</span>{/if}",
|
||||
"slot_props": "{ result: HeaderSearchResult; index: number }"
|
||||
}
|
||||
],
|
||||
"events": [
|
||||
{ "type": "dispatched", "name": "active", "detail": "any" },
|
||||
{ "type": "dispatched", "name": "inactive", "detail": "any" },
|
||||
{ "type": "dispatched", "name": "clear", "detail": "any" },
|
||||
{
|
||||
"type": "dispatched",
|
||||
"name": "select",
|
||||
"detail": "{ value: string; selectedResultIndex: number; selectedResult: HeaderSearchResult }"
|
||||
},
|
||||
{ "type": "forwarded", "name": "change", "element": "input" },
|
||||
{ "type": "forwarded", "name": "input", "element": "input" },
|
||||
{ "type": "forwarded", "name": "focus", "element": "input" },
|
||||
{ "type": "forwarded", "name": "blur", "element": "input" },
|
||||
{ "type": "forwarded", "name": "keydown", "element": "input" }
|
||||
],
|
||||
"typedefs": [
|
||||
{
|
||||
"type": "{ href: string; text: string; description?: string; }",
|
||||
"name": "HeaderSearchResult",
|
||||
"ts": "interface HeaderSearchResult { href: string; text: string; description?: string; }"
|
||||
}
|
||||
],
|
||||
"rest_props": { "type": "Element", "name": "input" }
|
||||
},
|
||||
{
|
||||
"moduleName": "UnorderedList",
|
||||
"filePath": "/src/UnorderedList/UnorderedList.svelte",
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
components: ["Header",
|
||||
"HeaderAction",
|
||||
"HeaderActionLink",
|
||||
"HeaderActionSearch",
|
||||
"HeaderSearch",
|
||||
"HeaderNav",
|
||||
"HeaderNavItem",
|
||||
"HeaderNavMenu",
|
||||
|
@ -34,6 +34,10 @@ components: ["Header",
|
|||
|
||||
<FileSource src="/framed/UIShell/HeaderSwitcher" />
|
||||
|
||||
### Header with global search
|
||||
|
||||
<FileSource src="/framed/UIShell/HeaderSearch" />
|
||||
|
||||
### Header with utilities
|
||||
|
||||
<FileSource src="/framed/UIShell/HeaderUtilities" />
|
||||
|
|
130
docs/src/pages/framed/UIShell/HeaderSearch.svelte
Normal file
130
docs/src/pages/framed/UIShell/HeaderSearch.svelte
Normal file
|
@ -0,0 +1,130 @@
|
|||
<script>
|
||||
import {
|
||||
Header,
|
||||
HeaderUtilities,
|
||||
HeaderAction,
|
||||
HeaderSearch,
|
||||
HeaderPanelLinks,
|
||||
HeaderPanelDivider,
|
||||
HeaderPanelLink,
|
||||
SkipToContent,
|
||||
Content,
|
||||
Grid,
|
||||
Row,
|
||||
Column,
|
||||
Button,
|
||||
} from "carbon-components-svelte";
|
||||
|
||||
const data = [
|
||||
{
|
||||
href: "/",
|
||||
text: "Kubernetes Service",
|
||||
description:
|
||||
"Deploy secure, highly available apps in a native Kubernetes experience. IBM Cloud Kubernetes Service creates a cluster of compute hosts and deploys highly available containers.",
|
||||
},
|
||||
{
|
||||
href: "/",
|
||||
text: "Red Hat OpenShift on IBM Cloud",
|
||||
description:
|
||||
"Deploy and secure enterprise workloads on native OpenShift with developer focused tools to run highly available apps. OpenShift clusters build on Kubernetes container orchestration that offers consistency and flexibility in operations.",
|
||||
},
|
||||
{
|
||||
href: "/",
|
||||
text: "Container Registry",
|
||||
description:
|
||||
"Securely store container images and monitor their vulnerabilities in a private registry.",
|
||||
},
|
||||
{
|
||||
href: "/",
|
||||
text: "Code Engine",
|
||||
description:
|
||||
"Run your application, job, or container on a managed serverless platform.",
|
||||
},
|
||||
];
|
||||
|
||||
let ref = null;
|
||||
let active = false;
|
||||
let value = "";
|
||||
let selectedResultIndex = 0;
|
||||
let events = [];
|
||||
|
||||
$: lowerCaseValue = value.toLowerCase();
|
||||
$: results =
|
||||
value.length > 0
|
||||
? data.filter((item) => {
|
||||
return (
|
||||
item.text.toLowerCase().includes(lowerCaseValue) ||
|
||||
item.description.includes(lowerCaseValue)
|
||||
);
|
||||
})
|
||||
: [];
|
||||
|
||||
$: console.log("ref", ref);
|
||||
$: console.log("active", active);
|
||||
$: console.log("value", value);
|
||||
$: console.log("selectedResultIndex", selectedResultIndex);
|
||||
</script>
|
||||
|
||||
<Header company="IBM" platformName="Carbon Svelte">
|
||||
<div slot="skip-to-content">
|
||||
<SkipToContent />
|
||||
</div>
|
||||
<HeaderUtilities>
|
||||
<HeaderSearch
|
||||
bind:ref
|
||||
bind:active
|
||||
bind:value
|
||||
bind:selectedResultIndex
|
||||
placeholder="Search services"
|
||||
results="{results}"
|
||||
on:active="{() => {
|
||||
events = [...events, { type: 'active' }];
|
||||
}}"
|
||||
on:inactive="{() => {
|
||||
events = [...events, { type: 'inactive' }];
|
||||
}}"
|
||||
on:clear="{() => {
|
||||
events = [...events, { type: 'clear' }];
|
||||
}}"
|
||||
on:select="{(e) => {
|
||||
events = [...events, { type: 'select', ...e.detail }];
|
||||
}}"
|
||||
/>
|
||||
</HeaderUtilities>
|
||||
</Header>
|
||||
|
||||
<Content>
|
||||
<Grid>
|
||||
<Row>
|
||||
<Column>
|
||||
<h1>HeaderSearch</h1>
|
||||
<Button
|
||||
on:click="{() => {
|
||||
active = true;
|
||||
}}"
|
||||
>
|
||||
Activate the search bar
|
||||
</Button>
|
||||
<h2>Reactive values</h2>
|
||||
<p><strong>active</strong>: {active}</p>
|
||||
<p><strong>value</strong>: {value}</p>
|
||||
<p><strong>selectedResultIndex</strong>: {selectedResultIndex}</p>
|
||||
<h2>Events</h2>
|
||||
<p>
|
||||
Click the button and search for something. Dispatched events are
|
||||
logged below:
|
||||
</p>
|
||||
<div style="overflow-x: scroll;">
|
||||
{#each events as { type, ...rest }}
|
||||
<div style="display: block; margin-bottom: var(--cds-layout-01)">
|
||||
<div><strong>on:{type}</strong></div>
|
||||
{#if Object.keys(rest).length > 0}
|
||||
<pre>{JSON.stringify(rest, null, 2)}</pre>
|
||||
{/if}
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
</Column>
|
||||
</Row>
|
||||
</Grid>
|
||||
</Content>
|
|
@ -3,7 +3,6 @@
|
|||
Header,
|
||||
HeaderUtilities,
|
||||
HeaderAction,
|
||||
HeaderActionSearch,
|
||||
HeaderGlobalAction,
|
||||
HeaderPanelLinks,
|
||||
HeaderPanelDivider,
|
||||
|
@ -30,7 +29,6 @@
|
|||
<SkipToContent />
|
||||
</div>
|
||||
<HeaderUtilities>
|
||||
<HeaderActionSearch />
|
||||
<HeaderGlobalAction aria-label="Settings" icon="{SettingsAdjust20}" />
|
||||
<HeaderAction bind:isOpen>
|
||||
<HeaderPanelLinks>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue