Skip to content

Commit

Permalink
Merge branch 'next' of github:HolodexNet/Holodex into next
Browse files Browse the repository at this point in the history
  • Loading branch information
P-man2976 committed Oct 27, 2023
2 parents dc582bf + f7a7c5a commit 3a8daf6
Show file tree
Hide file tree
Showing 13 changed files with 176 additions and 197 deletions.
4 changes: 2 additions & 2 deletions packages/react/src/components/header/header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
DropdownMenuItem,
} from "@/shadcn/ui/dropdown-menu";
import { useAuth } from "@/hooks/useAuth";
import { SearchBar } from "./searchbar/SearchBar";
import { SearchBar } from "./searchbar/components/SearchBar";

interface HeaderProps
extends React.DetailedHTMLProps<
Expand Down Expand Up @@ -41,7 +41,7 @@ export function Header({ id }: HeaderProps) {
<div className="i-heroicons:bars-3 rounded-md p-3" />
</Button>
<div className="hidden grow md:flex" />
<SearchBar className="max-w-lg" />
<SearchBar className="mt-3 max-w-lg self-start" />
<Button
size="icon"
variant="ghost"
Expand Down
118 changes: 0 additions & 118 deletions packages/react/src/components/header/searchbar/README.md

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { Command as CommandPrimitive } from "cmdk";
import { CommandItem } from "@/shadcn/ui/command";
import { QueryItem } from "../types";
import { useTranslation } from "react-i18next";
import { useCallback } from "react";

interface AutocompleteDropdownItemProps
extends React.ComponentPropsWithoutRef<typeof CommandPrimitive.Item> {
item: QueryItem;
onSelect: (_: string) => void;
}
export function AutocompleteDropdownItem({
item,
onSelect,
...rest
}: AutocompleteDropdownItemProps) {
const { t } = useTranslation();
const categoryName = useCallback(
(query: QueryItem) => {
return t(`search.class.${query.type}`, query.type);
},
[t],
);

const categoryExplanation = useCallback(
(query: QueryItem) => {
return t(`search.class_explanation.${query.type}`, " ");
},
[t],
);

const categoryValue = useCallback(
(query: QueryItem) => {
return query.text === "$t"
? t(`search.class_values.${query.type}.${query.value}`, " ")
: query.text === "?"
? query.value
: query.text;
},
[t],
);

return (
<CommandItem
key={item.type + item.value}
onMouseDown={(e) => {
e.preventDefault();
e.stopPropagation();
}}
value={item.type + item.value}
onSelect={onSelect}
className={"cursor-pointer"}
{...rest}
>
<b>{categoryName(item)}:&nbsp;</b>
{item.incomplete ? (
<span className="font-light opacity-60">
{categoryExplanation(item)}
</span>
) : (
<span>{categoryValue(item)}</span>
)}
</CommandItem>
);
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,43 @@
import * as React from "react";
import { X } from "lucide-react";
import { Badge } from "@/shadcn/ui/badge";
import { QueryItem } from "./types";
import { QueryItem } from "../types";
import { PrimitiveAtom, useAtomValue, useSetAtom } from "jotai";
import { splitQueryAtom } from "./SearchBarAtoms";
import { splitQueryAtom } from "../hooks/useAutocomplete";
import { useTranslation } from "react-i18next";

export function QueryBadge({ item }: { item: PrimitiveAtom<QueryItem> }) {
const queryItem = useAtomValue(item);
const querySplitItemAction = useSetAtom(splitQueryAtom);
const { t } = useTranslation();
const categoryName = React.useCallback(
(query: QueryItem) => {
return t(`search.class.${query.type}`, query.type);
},
[t],
);

// const categoryExplanation = React.useCallback(
// (query: QueryItem) => {
// return t(`search.class_explanation.${query.type}`, " ");
// },
// [t],
// );

const categoryValue = React.useCallback(
(query: QueryItem) => {
return query.text === "$t"
? t(`search.class_values.${query.type}.${query.value}`, " ")
: query.text === "?"
? query.value
: query.text;
},
[t],
);

return (
<Badge key={queryItem.value} variant="primary">
{queryItem.text}
<Badge key={queryItem.type + queryItem.value} variant="primary">
{categoryName(queryItem)}: {categoryValue(queryItem)}
<button
className="ml-1 rounded-full outline-none ring-offset-base-2 focus:ring-2 focus:ring-primary-9 focus:ring-offset-2"
onKeyDown={(e) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,20 @@ import {
Command,
CommandEmpty,
CommandGroup,
CommandItem,
CommandSeparator,
} from "@/shadcn/ui/command";
import { cn } from "@/lib/utils";
import { queryAtom, splitQueryAtom, useAutocomplete } from "./SearchBarAtoms";
import {
queryAtom,
splitQueryAtom,
useAutocomplete,
} from "../hooks/useAutocomplete";
import { useAtom } from "jotai";
import { JSON_SCHEMA, QueryItem } from "./types";
import { JSON_SCHEMA, QueryItem } from "../types";
import { QueryBadge } from "./QueryBadge";
import { useTranslation } from "react-i18next";
import { HTMLAttributes, useRef, useState, useCallback } from "react";
import { AutocompleteDropdownItem } from "./AutocompleteDropdownItem";

export function SearchBar({ className }: HTMLAttributes<HTMLDivElement>) {
const inputRef = useRef<HTMLInputElement>(null);
Expand Down Expand Up @@ -44,10 +48,39 @@ export function SearchBar({ className }: HTMLAttributes<HTMLDivElement>) {
[setQuery],
);

const handleItemSelect = useCallback(
(item: QueryItem) => {
if (item.incomplete) {
console.log("autocompleteItem - incomplete", item);
updateSearch(t(`search.class.${item.type}`, item.type) + ":");
return;
}

if (
JSON_SCHEMA[item.type].validation === undefined ||
JSON_SCHEMA[item.type].validation?.(item, query)
) {
console.log("autocompleteItem - trigger", item);
if (item.replace) {
setQuery((q) => q.filter((i) => i.type !== item.type).concat(item));
} else {
setQueryPieces({
type: "insert",
value: item,
});
}

updateSearch("");
} // onClick?.(e);
},
[query, updateSearch, t, setQuery, setQueryPieces],
);

return (
<Command
onKeyDown={handleKeyDown}
className={cn("overflow-visible bg-transparent", className)}
shouldFilter={false}
>
<div className="group rounded-md border border-base px-3 py-2 text-sm ring-offset-base-2 focus-within:ring-2 focus-within:ring-primary focus-within:ring-offset-2">
<div className="flex flex-wrap gap-1">
Expand All @@ -61,61 +94,26 @@ export function SearchBar({ className }: HTMLAttributes<HTMLDivElement>) {
onValueChange={updateSearch}
onBlur={() => setOpen(false)}
onFocus={() => setOpen(true)}
placeholder="Select frameworks..."
placeholder={t("component.search.searchLabel")}
className="ml-2 flex-1 bg-transparent outline-none placeholder:text-base-8"
/>
</div>
</div>
<div className="relative mt-2">
<div className="relative">
{open && autocomplete.length > 0 ? (
<>
<div className="absolute top-0 z-10 w-full rounded-md border border-base bg-base-1 text-base-11 shadow-md outline-none animate-in">
<CommandGroup heading="Search Options" />
<div className="absolute top-2 z-10 w-full rounded-md border border-base bg-base-1 text-base-11 shadow-md outline-none animate-in">
<CommandGroup
heading={<div>{t("search.menu_header_text")}</div>}
/>
<CommandSeparator />
<CommandGroup className="h-full overflow-auto">
{autocomplete.map((item) => {
return (
<CommandItem
key={item.type + item.value}
onMouseDown={(e) => {
e.preventDefault();
e.stopPropagation();
}}
value={JSON.stringify(item)}
onSelect={(_) => {
if (item.incomplete) {
console.log("autocompleteItem - incomplete", item);
updateSearch(
t(`search.class.${item.type}`, item.type) + ":",
);
return;
}

if (
JSON_SCHEMA[item.type].validation === undefined ||
JSON_SCHEMA[item.type].validation?.(item, query)
) {
console.log("autocompleteItem - trigger", item);
if (item.replace) {
setQuery((q) =>
q
.filter((i) => i.type !== item.type)
.concat(item),
);
} else {
setQueryPieces({
type: "insert",
value: item,
});
}

updateSearch("");
} // onClick?.(e);
}}
className={"cursor-pointer"}
>
{item.type} : {item.text}
</CommandItem>
<AutocompleteDropdownItem
item={item}
onSelect={() => handleItemSelect(item)}
/>
);
})}
</CommandGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import { atom, useAtomValue } from "jotai";
import { splitAtom } from "jotai/utils";
import { useMemo, useState } from "react";
import { useTranslation } from "react-i18next";
import { splitSearchClassTerms } from "./helper";
import { JSON_SCHEMA, QueryItem } from "./types";
import { splitSearchClassTerms } from "../helper";
import { JSON_SCHEMA, QueryItem } from "../types";
import { useClientAutocomplete } from "./useClientAutocomplete";
import { useServerAutocomplete } from "./useServerAutocomplete";

Expand Down
Loading

0 comments on commit 3a8daf6

Please sign in to comment.