Skip to content

Commit

Permalink
docs(search): add cmdk style example
Browse files Browse the repository at this point in the history
  • Loading branch information
MengLinMaker committed Oct 31, 2024
1 parent 3559681 commit aaafbfd
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 42 deletions.
60 changes: 44 additions & 16 deletions apps/docs/src/examples/search.module.css
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
.search__control {
overflow: hidden;
display: inline-flex;
justify-content: space-between;
width: 250px;
Expand All @@ -14,11 +15,6 @@
color 250ms;
}

.search__control[data-invalid] {
border-color: hsl(0 72% 51%);
color: hsl(0 72% 51%);
}

.search__control_multi {
width: 100%;
min-width: 250px;
Expand Down Expand Up @@ -49,8 +45,6 @@
align-items: center;
width: auto;
outline: none;
border-top-left-radius: 6px;
border-bottom-left-radius: 6px;
padding: 0 10px;
background-color: hsl(240 5% 96%);
border-right: 1px solid hsl(240 6% 90%);
Expand Down Expand Up @@ -145,7 +139,6 @@
.search__item[data-highlighted] {
outline: none;
box-sizing: border-box;
background-color: hsl(240 5% 96%);
box-shadow: inset 0 0 0 2px hsl(200 98% 39%);
}

Expand Down Expand Up @@ -205,11 +198,6 @@
border-color: hsl(240 4% 46%);
}

[data-kb-theme="dark"] .search__control[data-invalid] {
border-color: hsl(0 72% 51%);
color: hsl(0 72% 51%);
}

[data-kb-theme="dark"] .search__input::placeholder {
color: hsl(0 100% 100% / 0.5);
}
Expand Down Expand Up @@ -245,13 +233,53 @@
}

.search__root_cmdk {
min-height: 250px;
min-height: 240px;
min-width: 250px;
display: flex;
flex-direction: column;
}

.search__control_cmdk {
overflow: hidden;
display: inline-flex;
justify-content: space-between;
border-radius: 12px 12px 0 0;
font-size: 16px;
line-height: 1;
outline: none;
background-color: white;
border: 1px solid hsl(240 6% 90%);
color: hsl(240 4% 16%);
transition:
border-color 250ms,
color 250ms;
}

.search__content_cmdk {
height: 200px;
height: 100%;
flex-grow: 1;
background-color: white;
border-radius: 6px;
border-radius: 0 0 12px 12px;
border: 1px solid hsl(240 6% 90%);
border-top: none;
display: flex;
flex-direction: column;
}

.search__no_result_cmdk {
text-align: center;
margin: auto;
padding-bottom: 24px;
color: hsl(240 4% 46%);
}

[data-kb-theme="dark"] .search__control_cmdk {
background-color: hsl(240 4% 16%);
border: 1px solid hsl(240 5% 34%);
color: hsl(0 100% 100% / 0.9);
}

[data-kb-theme="dark"] .search__content_cmdk {
background-color: hsl(240 4% 16%);
border: 1px solid hsl(240 5% 34%);
}
40 changes: 16 additions & 24 deletions apps/docs/src/examples/search.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -328,10 +328,6 @@ const RAW_EMOJI_DATA: EmojiDatum[] = ([] as any)
emoji: "🙁",
name: "slightly frowning face",
},
{
emoji: "☹",
name: "frowning face",
},
{
emoji: "😮",
name: "face with open mouth",
Expand Down Expand Up @@ -656,12 +652,13 @@ export function DebounceExample() {
);
}

export function CmdkExample() {
export function CmdkStyleExample() {
const [options, setOptions] = createSignal<EmojiDatum[]>([]);
const [emoji, setEmoji] = createSignal<EmojiDatum | null>();
return (
<>
<Search
open
options={options()}
onInputChange={(query: string) => {
setOptions(queryEmojiData(query));
Expand All @@ -671,31 +668,26 @@ export function CmdkExample() {
optionLabel="name"
placeholder="Search an emoji…"
itemComponent={(props: any) => (
<Search.Item item={props.item} class={style.search__item}>
<Search.Item as="button" item={props.item} class={style.search__item}>
<Search.ItemLabel>{props.item.rawValue.emoji}</Search.ItemLabel>
</Search.Item>
)}
class={style.search__root_cmdk}
>
<div>
<Search.Control class={style.search__control} aria-label="Emoji">
<Search.Indicator class={style.search__indicator}>
<Search.Icon class={style.search__icon}>
<MagnifyingGlassIcon class={style.center__icon} />
</Search.Icon>
</Search.Indicator>

<Search.Input class={style.search__input} />
</Search.Control>
</div>
<Search.Control class={style.search__control_cmdk} aria-label="Emoji">
<Search.Indicator class={style.search__indicator}>
<Search.Icon class={style.search__icon}>
<MagnifyingGlassIcon class={style.center__icon} />
</Search.Icon>
</Search.Indicator>

<div>
<Search.Content class={style.search__content_cmdk}>
<Search.Listbox class={style.search__listbox} />
<Search.NoResult class={style.search__no_result}>
😬 No emoji found
</Search.NoResult>
</Search.Content>
<Search.Input class={style.search__input} />
</Search.Control>
<div class={style.search__content_cmdk}>
<Search.Listbox class={style.search__listbox} />
<Search.NoResult class={style.search__no_result_cmdk}>
😬 No emoji found
</Search.NoResult>
</div>
</Search>

Expand Down
45 changes: 43 additions & 2 deletions apps/docs/src/routes/docs/core/components/search.mdx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Preview, TabsSnippets, Kbd, Callout } from "../../../../components";
import { BasicExample, DebounceExample, CmdkExample } from "../../../../examples/search";
import { BasicExample, DebounceExample, CmdkStyleExample } from "../../../../examples/search";

# Search

Expand Down Expand Up @@ -344,7 +344,7 @@ Show a debouncing icon by adding a `loadingComponent` to `Search.Indicator`.
optionValue="name"
optionLabel="name"
placeholder="Search an emoji…"
itemComponent={(props: any) => (
itemComponent={(props: any) => (
<Search.Item item={props.item}>
<Search.ItemLabel>{props.item.rawValue.emoji}</Search.ItemLabel>
</Search.Item>
Expand Down Expand Up @@ -375,6 +375,47 @@ Show a debouncing icon by adding a `loadingComponent` to `Search.Indicator`.
</Search>
```

### Cmdk style

To achieve the command menu look, add the `open` prop to permanently open dropdown. Replace `Search.Portal` and `Search.Content` with a `div` to directly mount your content below the search input.

<Preview>
<CmdkStyleExample />
</Preview>

```tsx
<Search
open
options={options()}
onInputChange={query => setOptions(queryEmojiData(query))}
onChange={result => setEmoji(result)}
debounceOptionsMillisecond={300}
optionValue="name"
optionLabel="name"
placeholder="Search an emoji…"
itemComponent={(props: any) => (
<Search.Item item={props.item}>
<Search.ItemLabel>{props.item.rawValue.emoji}</Search.ItemLabel>
</Search.Item>
)}
>
<Search.Control aria-label="Emoji">
<Search.Indicator>
<Search.Icon>
<MagnifyingGlassIcon />
</Search.Icon>
</Search.Indicator>
<Search.Input />
</Search.Control>
<div>
<Search.Listbox />
<Search.NoResult>
😬 No emoji found
</Search.NoResult>
</div>
</Search>
```

## API Reference

### Search
Expand Down

0 comments on commit aaafbfd

Please sign in to comment.