Skip to content

Commit f30ef0f

Browse files
Merge pull request #71 from linked-planet/select-custom-components
Select custom components
2 parents 8107b61 + 0e23094 commit f30ef0f

File tree

4 files changed

+331
-14
lines changed

4 files changed

+331
-14
lines changed

library/src/components/DropdownMenu.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -492,7 +492,7 @@ const Trigger = forwardRef<HTMLButtonElement, DropdownTriggerProps>(
492492
className={`hidden h-4 w-4 items-center justify-center ${
493493
hideChevron
494494
? ""
495-
: "group-data-[state=closed]:flex group-data-[state=open]:visible"
495+
: "group-data-[state=closed]:flex group-data-[state=closed]:visible"
496496
}`}
497497
>
498498
<ChevronDownIcon label="" size="small" />

library/src/components/inputs/index.ts

Lines changed: 142 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ export { Label } from "./Label"
22
export { Input, Fieldset } from "./Inputs"
33
//export { RadixSelect } from "./RadixSelect"
44
export { Select } from "./Select"
5+
export { components as selectComponents } from "react-select"
56
export { DatePicker } from "./datetimepicker/DatePicker"
67
export { TimePicker } from "./datetimepicker/TimePicker"
78
export { DateTimePicker } from "./datetimepicker/DateTimePicker"
@@ -22,15 +23,145 @@ export type {
2223
DateTimePickerInFormProps,
2324
} from "./datetimepicker/DateTimePicker"
2425

25-
export {
26-
type SelectProps,
27-
type SelectInFormProps,
28-
type SelectClassNamesConfig,
29-
type OptionGroupType,
30-
type OptionType,
31-
type SelectAriaOnChange,
32-
type SelectAriaOnFilter,
33-
type SelectAriaOnFocus,
34-
type SelectAriaGuidance,
35-
type SelectAriaLiveMessages,
26+
export type {
27+
SelectProps,
28+
SelectInFormProps,
29+
SelectClassNamesConfig,
30+
OptionGroupType,
31+
OptionType,
32+
SelectAriaOnChange,
33+
SelectAriaOnFilter,
34+
SelectAriaOnFocus,
35+
SelectAriaGuidance,
36+
SelectAriaLiveMessages,
3637
} from "./Select"
38+
39+
import type * as rselect from "react-select"
40+
import type { OptionType, OptionGroupType } from "./Select"
41+
export namespace SelectComponentProps {
42+
export type OptionProps<
43+
T,
44+
isMulti extends boolean = boolean,
45+
> = rselect.OptionProps<OptionType<T>, isMulti, OptionGroupType<T>>
46+
export type SingleValueProps<
47+
T,
48+
isMulti extends boolean = boolean,
49+
> = rselect.SingleValueProps<OptionType<T>, isMulti, OptionGroupType<T>>
50+
export type MultiValueProps<
51+
T,
52+
isMulti extends boolean = boolean,
53+
> = rselect.MultiValueProps<OptionType<T>, isMulti, OptionGroupType<T>>
54+
55+
export type PlaceholderProps<
56+
T,
57+
isMulti extends boolean = boolean,
58+
> = rselect.PlaceholderProps<OptionType<T>, isMulti, OptionGroupType<T>>
59+
60+
export type ClearIndicatorProps<
61+
T,
62+
isMulti extends boolean = boolean,
63+
> = rselect.ClearIndicatorProps<OptionType<T>, isMulti, OptionGroupType<T>>
64+
65+
export type DropdownIndicatorProps<
66+
T,
67+
isMulti extends boolean = boolean,
68+
> = rselect.DropdownIndicatorProps<
69+
OptionType<T>,
70+
isMulti,
71+
OptionGroupType<T>
72+
>
73+
74+
export type IndicatorSeparatorProps<
75+
T,
76+
isMulti extends boolean = boolean,
77+
> = rselect.IndicatorSeparatorProps<
78+
OptionType<T>,
79+
isMulti,
80+
OptionGroupType<T>
81+
>
82+
83+
export type LoadingIndicatorProps<
84+
T,
85+
isMulti extends boolean = boolean,
86+
> = rselect.LoadingIndicatorProps<
87+
OptionType<T>,
88+
isMulti,
89+
OptionGroupType<T>
90+
>
91+
92+
export type MenuProps<
93+
T,
94+
isMulti extends boolean = boolean,
95+
> = rselect.MenuProps<OptionType<T>, isMulti, OptionGroupType<T>>
96+
97+
export type MenuListProps<
98+
T,
99+
isMulti extends boolean = boolean,
100+
> = rselect.MenuListProps<OptionType<T>, isMulti, OptionGroupType<T>>
101+
102+
export type NoticeProps<
103+
T,
104+
isMulti extends boolean = boolean,
105+
> = rselect.NoticeProps<OptionType<T>, isMulti, OptionGroupType<T>>
106+
107+
export type MultiValueContainerProps<
108+
T,
109+
isMulti extends boolean = boolean,
110+
> = rselect.MultiValueGenericProps<
111+
OptionType<T>,
112+
isMulti,
113+
OptionGroupType<T>
114+
>
115+
116+
export type MultiValueLabelProps<
117+
T,
118+
isMulti extends boolean = boolean,
119+
> = rselect.MultiValueGenericProps<
120+
OptionType<T>,
121+
isMulti,
122+
OptionGroupType<T>
123+
>
124+
125+
export type MultiValueRemoveProps<
126+
T,
127+
isMulti extends boolean = boolean,
128+
> = rselect.MultiValueRemoveProps<
129+
OptionType<T>,
130+
isMulti,
131+
OptionGroupType<T>
132+
>
133+
134+
export type GroupProps<
135+
T,
136+
isMulti extends boolean = boolean,
137+
> = rselect.GroupProps<OptionType<T>, isMulti, OptionGroupType<T>>
138+
139+
export type GroupHeadingProps<
140+
T,
141+
isMulti extends boolean = boolean,
142+
> = rselect.GroupHeadingProps<OptionType<T>, isMulti, OptionGroupType<T>>
143+
144+
export type SelectContainerProps<
145+
T,
146+
isMulti extends boolean = boolean,
147+
> = rselect.ContainerProps<OptionType<T>, isMulti, OptionGroupType<T>>
148+
149+
export type ValueContainerProps<
150+
T,
151+
isMulti extends boolean = boolean,
152+
> = rselect.ValueContainerProps<OptionType<T>, isMulti, OptionGroupType<T>>
153+
154+
export type IndicatorsContainerProps<
155+
T,
156+
isMulti extends boolean = boolean,
157+
> = rselect.IndicatorsContainerProps<
158+
OptionType<T>,
159+
isMulti,
160+
OptionGroupType<T>
161+
>
162+
163+
export type ControlProps<
164+
T,
165+
isMulti extends boolean = boolean,
166+
> = rselect.ControlProps<OptionType<T>, isMulti, OptionGroupType<T>>
167+
}

showcase/public/showcase-sources.txt

Lines changed: 94 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6050,9 +6050,11 @@ import {
60506050
ButtonGroup,
60516051
Label,
60526052
Select,
6053+
type SelectComponentProps,
60536054
type OptionGroupType,
6055+
selectComponents,
60546056
} from "@linked-planet/ui-kit-ts"
6055-
import { useState } from "react"
6057+
import { useMemo, useState } from "react"
60566058
import { useForm } from "react-hook-form"
60576059
import ShowcaseWrapperItem, {
60586060
type ShowcaseProps,
@@ -6203,6 +6205,92 @@ function ControlledFormExample() {
62036205
}
62046206
//#endregion select2form-controlled
62056207

6208+
//#region select-custom-component
6209+
type Book = {
6210+
title: string
6211+
author: string
6212+
isbn: string
6213+
language: string
6214+
}
6215+
6216+
const books: Book[] = [
6217+
{
6218+
title: "The Lord of the Rings",
6219+
author: "J.R.R. Tolkien",
6220+
isbn: "978-3-86680-192-9",
6221+
language: "English",
6222+
},
6223+
{
6224+
title: "Harry Potter",
6225+
author: "J.K. Rowling",
6226+
isbn: "978-3-86680-192-9",
6227+
language: "English",
6228+
},
6229+
{
6230+
title: "The Historical Development of the Heart from Its Formation in the Primitive Vertebrate to Its Most Recent Manifestation in Modern Homo Sapiens as Seen in the Context of the Evolutionary Process, Along with Reflections on Its Influence upon Social, Cultural, and Economic Development with Reference to the Views of Charles Darwin and Other Prominent Thinkers, and Including Detailed Examinations of the Physiological and Anatomical Aspects of the Organ, with Illustrations Drawn from Various Epochs and Regions of the World, as well as a Comprehensive Study of Heart Disease and Its Treatment from Ancient Times to the Present Day, Covering Both Eastern and Western Medical Practices, with a Special Section Devoted to the Role of Diet and Lifestyle in the Maintenance of Cardiovascular Health, Alongside a Discussion of the Spiritual and Symbolic Significance of the Heart in World Religions, and an Appendix on the Potential Future Developments in Heart Transplantation and Artificial Heart Research in the 21st Century",
6231+
author: "Nigel Tomm",
6232+
isbn: "123-4-56789-234-5",
6233+
language: "English",
6234+
},
6235+
{
6236+
title: "ABC",
6237+
author: "Sir Augustus Maximilian Percival Thaddeus Leopold Ambrose Fitzwilliam Kensington-Rutherford de la Croix Montmorency Beaumont Windsor St. John Alistair Edward Victor Montgomery Hawthorne-Darcy Fitzgerald, Duke of Abernathy, Marquess of Silverwood, Earl of Whitehall, Viscount Longfellow, Baron Cresswell of Eversfield",
6238+
isbn: "123-4-56789-234-5",
6239+
language: "English",
6240+
},
6241+
]
6242+
6243+
// https://react-select.com/components
6244+
function BookOption(props: SelectComponentProps.OptionProps<Book>) {
6245+
const value = props.data.value
6246+
return (
6247+
<selectComponents.Option {...props}>
6248+
<div className="py-2">
6249+
<h3 className="font-bold">{value.title}</h3>
6250+
<div
6251+
className="grid pt-1"
6252+
style={{
6253+
gridTemplateColumns: "1fr 12rem auto",
6254+
}}
6255+
>
6256+
<p className="truncate text-left">{value.author}</p>
6257+
<p className="truncate text-center px-2">{value.isbn}</p>
6258+
<p className="truncate text-right pl-2">{value.language}</p>
6259+
</div>
6260+
</div>
6261+
</selectComponents.Option>
6262+
)
6263+
}
6264+
6265+
function CustomComponentExample() {
6266+
const [selectedBook, setSelectedBook] = useState<Book | null>(null)
6267+
6268+
const options = useMemo(() => {
6269+
return books.map((book) => ({
6270+
label: book.title,
6271+
value: book,
6272+
}))
6273+
}, [])
6274+
6275+
const value =
6276+
options?.find((option) => option.value === selectedBook) ?? null
6277+
6278+
return (
6279+
<Select<Book, false>
6280+
options={options}
6281+
value={value}
6282+
onChange={(opt) => {
6283+
setSelectedBook(opt?.value ?? null)
6284+
}}
6285+
components={{
6286+
Option: BookOption,
6287+
}}
6288+
/>
6289+
)
6290+
}
6291+
6292+
//#endregion
6293+
62066294
function SelectShowcase(props: ShowcaseProps) {
62076295
//#region select
62086296
const example1 = (
@@ -6411,6 +6499,11 @@ function SelectShowcase(props: ShowcaseProps) {
64116499
example: <ControlledFormExample />,
64126500
sourceCodeExampleId: "select2form-controlled",
64136501
},
6502+
{
6503+
title: "Custom Component",
6504+
example: <CustomComponentExample />,
6505+
sourceCodeExampleId: "select-custom-component",
6506+
},
64146507
]}
64156508
/>
64166509
)

0 commit comments

Comments
 (0)