Skip to content

Commit

Permalink
Merge branch 'add-multiselect-to-combobox' into 1290-v2-resources-and…
Browse files Browse the repository at this point in the history
…-home-extension
  • Loading branch information
rolfheij-sil committed Dec 5, 2024
2 parents 7174608 + ed4abcf commit 6599f25
Show file tree
Hide file tree
Showing 12 changed files with 366 additions and 152 deletions.
2 changes: 1 addition & 1 deletion extensions/tailwind.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import typography from '@tailwindcss/typography';
import tailwindCssAnimate from 'tailwindcss-animate';

const config: Config = {
content: ['./src/**/*.{js,ts,jsx,tsx}'],
content: ['./src/**/*.{js,ts,jsx,tsx}', '!./**/node_modules/**/*'],
// Prefix on all tailwind classes so they don't clash with built-in classes
// short for tailwind - we hope to have the same prefix as users of this library so the cn
// function that uses tailwind-merge can properly overwrite related tailwind classes
Expand Down
84 changes: 45 additions & 39 deletions lib/platform-bible-react/dist/index.cjs

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion lib/platform-bible-react/dist/index.cjs.map

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions lib/platform-bible-react/dist/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -417,17 +417,17 @@ export type MultiSelectComboBoxEntry = {
label: string;
starred?: boolean;
};
export interface MultiSelectComboboxProps {
export interface MultiSelectComboBoxProps {
options: MultiSelectComboBoxEntry[];
getOptionsCount?: (option: MultiSelectComboBoxEntry) => number;
selected: string[];
onChange: (values: string[]) => void;
placeholder: string;
customSelectedText?: string;
sortSelected?: boolean;
isTypeCombobox?: boolean;
icon?: React$1.ReactNode;
}
export declare function MultiSelectComboBox({ options, selected, onChange, placeholder, customSelectedText, sortSelected, isTypeCombobox, icon, }: MultiSelectComboboxProps): import("react/jsx-runtime").JSX.Element;
export declare function MultiSelectComboBox({ options, getOptionsCount, selected, onChange, placeholder, customSelectedText, sortSelected, icon, }: MultiSelectComboBoxProps): import("react/jsx-runtime").JSX.Element;
export type TabKeyValueContent = {
key: string;
value: string;
Expand Down Expand Up @@ -995,7 +995,7 @@ export declare const Alert: React$1.ForwardRefExoticComponent<React$1.HTMLAttrib
export declare const AlertTitle: React$1.ForwardRefExoticComponent<React$1.HTMLAttributes<HTMLHeadingElement> & React$1.RefAttributes<HTMLParagraphElement>>;
export declare const AlertDescription: React$1.ForwardRefExoticComponent<React$1.HTMLAttributes<HTMLParagraphElement> & React$1.RefAttributes<HTMLParagraphElement>>;
export declare const badgeVariants: (props?: ({
variant?: "default" | "outline" | "destructive" | "secondary" | null | undefined;
variant?: "default" | "outline" | "muted" | "destructive" | "secondary" | null | undefined;
} & import("class-variance-authority/dist/types").ClassProp) | undefined) => string;
export interface BadgeProps extends React$1.HTMLAttributes<HTMLDivElement>, VariantProps<typeof badgeVariants> {
}
Expand Down
139 changes: 78 additions & 61 deletions lib/platform-bible-react/dist/index.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion lib/platform-bible-react/dist/index.js.map

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -18,27 +18,27 @@ type MultiSelectComboBoxEntry = {
starred?: boolean;
};

interface MultiSelectComboboxProps {
interface MultiSelectComboBoxProps {
options: MultiSelectComboBoxEntry[];
getOptionsCount?: (option: MultiSelectComboBoxEntry) => number;
selected: string[];
onChange: (values: string[]) => void;
placeholder: string;
customSelectedText?: string;
sortSelected?: boolean;
isTypeCombobox?: boolean;
icon?: ReactNode;
}

function MultiSelectComboBox({
options,
getOptionsCount = undefined,
selected,
onChange,
placeholder,
customSelectedText,
sortSelected = false,
isTypeCombobox = false,
icon = undefined,
}: MultiSelectComboboxProps) {
}: MultiSelectComboBoxProps) {
const [open, setOpen] = useState(false);

const handleSelect = useCallback(
Expand All @@ -55,10 +55,10 @@ function MultiSelectComboBox({
);

const getPlaceholderText = () => {
if (selected.length === 0) return placeholder;
if (isTypeCombobox && selected.length === options.length) return 'All types';
if (selected.length === 1)
return options.find((option) => option.value === selected[0])?.label ?? placeholder;
if (customSelectedText) return customSelectedText;
return `${selected.length} ${placeholder.toLowerCase().split(' ')[1]}`;
return placeholder;
};

const sortedOptions = useMemo(() => {
Expand Down Expand Up @@ -87,7 +87,10 @@ function MultiSelectComboBox({
variant="outline"
role="combobox"
aria-expanded={open}
className="tw-w-full tw-justify-between"
className={cn(
'tw-w-full tw-justify-between',
selected.length > 0 && selected.length < options.length && 'tw-border-primary',
)}
>
<div className="tw-flex tw-items-center tw-gap-2">
<div className="tw-ml-2 tw-h-4 tw-w-4 tw-shrink-0 tw-opacity-50">
Expand All @@ -106,27 +109,35 @@ function MultiSelectComboBox({
<CommandList>
<CommandEmpty>No item found.</CommandEmpty>
<CommandGroup>
{sortedOptions.map((option) => (
<CommandItem
key={option.value}
value={option.value}
onSelect={handleSelect}
className="tw-flex tw-items-center tw-gap-2"
>
<div className="w-4">
<Check
className={cn(
'tw-h-4 tw-w-4',
selected.includes(option.value) ? 'tw-opacity-100' : 'tw-opacity-0',
)}
/>
</div>
<div className="tw-w-4">
{option.starred && <Star className="tw-h-4 tw-w-4 tw-text-yellow-500" />}
</div>
{option.label}
</CommandItem>
))}
{sortedOptions.map((option) => {
const count: number | undefined = getOptionsCount
? getOptionsCount(option)
: undefined;
return (
<CommandItem
key={option.value}
value={option.value}
onSelect={handleSelect}
className="tw-flex tw-items-center tw-gap-2"
>
<div className="w-4">
<Check
className={cn(
'tw-h-4 tw-w-4',
selected.includes(option.value) ? 'tw-opacity-100' : 'tw-opacity-0',
)}
/>
</div>
<div className="tw-w-4">
{option.starred && <Star className="tw-h-4 tw-w-4" />}
</div>
<div className="tw-flex-grow">{option.label}</div>
{getOptionsCount && (
<div className="tw-w-10 tw-text-right tw-text-muted-foreground">{count}</div>
)}
</CommandItem>
);
})}
</CommandGroup>
</CommandList>
</Command>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const badgeVariants = cva(
'tw-border-transparent tw-bg-primary tw-text-primary-foreground hover:tw-bg-primary/80',
secondary:
'tw-border-transparent tw-bg-secondary tw-text-secondary-foreground hover:tw-bg-secondary/80',
muted: 'tw-border-transparent tw-bg-muted tw-text-muted-foreground hover:tw-bg-muted/80',
destructive:
'tw-border-transparent tw-bg-destructive tw-text-destructive-foreground hover:tw-bg-destructive/80',
outline: 'tw-text-foreground',
Expand Down
2 changes: 1 addition & 1 deletion lib/platform-bible-react/src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
}
}

/* #region shared with https://github.com/paranext/paranext-extension-template/blob/main/tailwind.css */
/* #region shared with https://github.com/paranext/paranext-extension-template/blob/main/src/tailwind.css */

@layer base {
@font-face {
Expand Down
Loading

0 comments on commit 6599f25

Please sign in to comment.