From 38b134f07dfbe8c34c1af1e5c2f5ae0e5d2b217a Mon Sep 17 00:00:00 2001 From: Brian Reynolds Date: Tue, 2 Mar 2021 08:47:11 -0600 Subject: [PATCH] feat: update valueRenderer type to accept elements as well as strings as return values --- src/lib/interfaces.ts | 4 +- stories/custom-element.stories.tsx | 110 +++++++++++++++++++++++++++++ 2 files changed, 113 insertions(+), 1 deletion(-) create mode 100644 stories/custom-element.stories.tsx diff --git a/src/lib/interfaces.ts b/src/lib/interfaces.ts index 7fb49c1..41310e3 100644 --- a/src/lib/interfaces.ts +++ b/src/lib/interfaces.ts @@ -1,3 +1,5 @@ +import { ReactNode } from "react"; + export interface Option { value; label: string; @@ -10,7 +12,7 @@ export interface ISelectProps { value: Option[]; focusSearchOnOpen?: boolean; onChange?; - valueRenderer?: (selected: Option[], options: Option[]) => string; + valueRenderer?: (selected: Option[], options: Option[]) => ReactNode; ItemRenderer?: Function; ArrowRenderer?: ({ expanded }) => JSX.Element; selectAllLabel?: string; diff --git a/stories/custom-element.stories.tsx b/stories/custom-element.stories.tsx new file mode 100644 index 0000000..91b328d --- /dev/null +++ b/stories/custom-element.stories.tsx @@ -0,0 +1,110 @@ +import { boolean, text, withKnobs } from "@storybook/addon-knobs"; +import React, { useState } from "react"; + +import { css } from "goober"; +import { cn } from "../src/lib/classnames"; + +import MultiSelect from "../src/multi-select"; +import { options } from "./constants"; + +const MultiSelectOverrides = css({ + ".dropdown-container": { + border: 0, + display: "inline-block", + width: "100%", + "&:focus-within": { + boxShadow: "none", + borderColor: "transparent", + }, + }, + ".dropdown-heading": { + padding: 0, + height: "auto", + }, + ".dropdown-heading-dropdown-arrow": { + display: "none", + }, +}); + +export default { + title: "Custom Element", + decorators: [withKnobs], +}; + +export const ExampleWithStrings = () => { + const [selected, setSelected] = useState([]); + + const valueRenderer = ( selected: typeof options ) => { + if ( !selected.length ) { + return "No Item Selected"; + } + + return selected.length === 1 + ? `${selected[0].label} 😶` + : selected.map(({ label }) => "✔️ " + label) + } + + return ( +
+
{JSON.stringify(selected)}
+ +
+ ); +}; + +ExampleWithStrings.story = { + name: "With Strings", +}; + +export const ExampleWithReactNode = () => { + const [selected, setSelected] = useState([]); + + const valueRenderer = ( selected: typeof options ) => { + if ( !selected.length ) { + return ( + + ); + } + + return selected.length === 1 + ? ( ) + : selected.map(({ label }) => ( )) + } + + return ( +
+
{JSON.stringify(selected)}
+ +
+ ); +}; + +ExampleWithReactNode.story = { + name: "With Element", +}; \ No newline at end of file