feat: create Select component with radix-ui primitives
This commit is contained in:
parent
84ac086678
commit
fc7f4b8358
7 changed files with 222 additions and 5 deletions
|
@ -35,6 +35,7 @@
|
|||
"@otplib/plugin-thirty-two": "^12.0.1",
|
||||
"@prisma/client": "^4.12.0",
|
||||
"@radix-ui/react-dialog": "^1.0.3",
|
||||
"@radix-ui/react-select": "^1.2.1",
|
||||
"@radix-ui/react-switch": "^1.0.2",
|
||||
"@radix-ui/react-tabs": "^1.0.3",
|
||||
"@runtipi/postgres-migrations": "^5.3.0",
|
||||
|
@ -85,6 +86,7 @@
|
|||
"@testing-library/jest-dom": "^5.16.5",
|
||||
"@testing-library/react": "^14.0.0",
|
||||
"@testing-library/user-event": "^14.4.3",
|
||||
"@total-typescript/shoehorn": "^0.1.0",
|
||||
"@total-typescript/ts-reset": "^0.4.2",
|
||||
"@types/express": "^4.17.13",
|
||||
"@types/fs-extra": "^11.0.1",
|
||||
|
|
137
pnpm-lock.yaml
137
pnpm-lock.yaml
|
@ -19,6 +19,9 @@ dependencies:
|
|||
'@radix-ui/react-dialog':
|
||||
specifier: ^1.0.3
|
||||
version: 1.0.3(@types/react@18.0.28)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@radix-ui/react-select':
|
||||
specifier: ^1.2.1
|
||||
version: 1.2.1(@types/react@18.0.28)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@radix-ui/react-switch':
|
||||
specifier: ^1.0.2
|
||||
version: 1.0.2(react-dom@18.2.0)(react@18.2.0)
|
||||
|
@ -165,6 +168,9 @@ devDependencies:
|
|||
'@testing-library/user-event':
|
||||
specifier: ^14.4.3
|
||||
version: 14.4.3(@testing-library/dom@9.0.1)
|
||||
'@total-typescript/shoehorn':
|
||||
specifier: ^0.1.0
|
||||
version: 0.1.0
|
||||
'@total-typescript/ts-reset':
|
||||
specifier: ^0.4.2
|
||||
version: 0.4.2
|
||||
|
@ -992,16 +998,40 @@ packages:
|
|||
engines: {node: '>=14.0.0', npm: '>=6.0.0'}
|
||||
dev: true
|
||||
|
||||
/@floating-ui/core@0.7.3:
|
||||
resolution: {integrity: sha512-buc8BXHmG9l82+OQXOFU3Kr2XQx9ys01U/Q9HMIrZ300iLc8HLMgh7dcCqgYzAzf4BkoQvDcXf5Y+CuEZ5JBYg==}
|
||||
dev: false
|
||||
|
||||
/@floating-ui/core@1.2.1:
|
||||
resolution: {integrity: sha512-LSqwPZkK3rYfD7GKoIeExXOyYx6Q1O4iqZWwIehDNuv3Dv425FIAE8PRwtAx1imEolFTHgBEcoFHm9MDnYgPCg==}
|
||||
dev: false
|
||||
|
||||
/@floating-ui/dom@0.5.4:
|
||||
resolution: {integrity: sha512-419BMceRLq0RrmTSDxn8hf9R3VCJv2K9PUfugh5JyEFmdjzDo+e8U5EdR8nzKq8Yj1htzLm3b6eQEEam3/rrtg==}
|
||||
dependencies:
|
||||
'@floating-ui/core': 0.7.3
|
||||
dev: false
|
||||
|
||||
/@floating-ui/dom@1.2.1:
|
||||
resolution: {integrity: sha512-Rt45SmRiV8eU+xXSB9t0uMYiQ/ZWGE/jumse2o3i5RGlyvcbqOF4q+1qBnzLE2kZ5JGhq0iMkcGXUKbFe7MpTA==}
|
||||
dependencies:
|
||||
'@floating-ui/core': 1.2.1
|
||||
dev: false
|
||||
|
||||
/@floating-ui/react-dom@0.7.2(@types/react@18.0.28)(react-dom@18.2.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-1T0sJcpHgX/u4I1OzIEhlcrvkUN8ln39nz7fMoE/2HDHrPiMFoOGR7++GYyfUmIQHkkrTinaeQsO3XWubjSvGg==}
|
||||
peerDependencies:
|
||||
react: '>=16.8.0'
|
||||
react-dom: '>=16.8.0'
|
||||
dependencies:
|
||||
'@floating-ui/dom': 0.5.4
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0(react@18.2.0)
|
||||
use-isomorphic-layout-effect: 1.1.2(@types/react@18.0.28)(react@18.2.0)
|
||||
transitivePeerDependencies:
|
||||
- '@types/react'
|
||||
dev: false
|
||||
|
||||
/@hookform/resolvers@2.9.11(react-hook-form@7.43.7):
|
||||
resolution: {integrity: sha512-bA3aZ79UgcHj7tFV7RlgThzwSSHZgvfbt2wprldRkYBcMopdMvHyO17Wwp/twcJasNFischFfS7oz8Katz8DdQ==}
|
||||
peerDependencies:
|
||||
|
@ -1557,12 +1587,30 @@ packages:
|
|||
resolution: {integrity: sha512-0alKtnxhNB5hYU+ymESBlGI4b9XrGGSdv7Ud+8TE/fBNOEhIud0XQsAR+TrvUZgS4na5czubiMsODw0TUrgkIA==}
|
||||
requiresBuild: true
|
||||
|
||||
/@radix-ui/number@1.0.0:
|
||||
resolution: {integrity: sha512-Ofwh/1HX69ZfJRiRBMTy7rgjAzHmwe4kW9C9Y99HTRUcYLUuVT0KESFj15rPjRgKJs20GPq8Bm5aEDJ8DuA3vA==}
|
||||
dependencies:
|
||||
'@babel/runtime': 7.20.13
|
||||
dev: false
|
||||
|
||||
/@radix-ui/primitive@1.0.0:
|
||||
resolution: {integrity: sha512-3e7rn8FDMin4CgeL7Z/49smCA3rFYY3Ha2rUQ7HRWFadS5iCRw08ZgVT1LaNTCNqgvrUiyczLflrVrF0SRQtNA==}
|
||||
dependencies:
|
||||
'@babel/runtime': 7.20.13
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-arrow@1.0.2(react-dom@18.2.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-fqYwhhI9IarZ0ll2cUSfKuXHlJK0qE4AfnRrPBbRwEH/4mGQn04/QFGomLi8TXWIdv9WJk//KgGm+aDxVIr1wA==}
|
||||
peerDependencies:
|
||||
react: ^16.8 || ^17.0 || ^18.0
|
||||
react-dom: ^16.8 || ^17.0 || ^18.0
|
||||
dependencies:
|
||||
'@babel/runtime': 7.20.13
|
||||
'@radix-ui/react-primitive': 1.0.2(react-dom@18.2.0)(react@18.2.0)
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0(react@18.2.0)
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-collection@1.0.2(react-dom@18.2.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-s8WdQQ6wNXpaxdZ308KSr8fEWGrg4un8i4r/w7fhiS4ElRNjk5rRcl0/C6TANG2LvLOGIxtzo/jAg6Qf73TEBw==}
|
||||
peerDependencies:
|
||||
|
@ -1681,6 +1729,29 @@ packages:
|
|||
react: 18.2.0
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-popper@1.1.1(@types/react@18.0.28)(react-dom@18.2.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-keYDcdMPNMjSC8zTsZ8wezUMiWM9Yj14wtF3s0PTIs9srnEPC9Kt2Gny1T3T81mmSeyDjZxsD9N5WCwNNb712w==}
|
||||
peerDependencies:
|
||||
react: ^16.8 || ^17.0 || ^18.0
|
||||
react-dom: ^16.8 || ^17.0 || ^18.0
|
||||
dependencies:
|
||||
'@babel/runtime': 7.20.13
|
||||
'@floating-ui/react-dom': 0.7.2(@types/react@18.0.28)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@radix-ui/react-arrow': 1.0.2(react-dom@18.2.0)(react@18.2.0)
|
||||
'@radix-ui/react-compose-refs': 1.0.0(react@18.2.0)
|
||||
'@radix-ui/react-context': 1.0.0(react@18.2.0)
|
||||
'@radix-ui/react-primitive': 1.0.2(react-dom@18.2.0)(react@18.2.0)
|
||||
'@radix-ui/react-use-callback-ref': 1.0.0(react@18.2.0)
|
||||
'@radix-ui/react-use-layout-effect': 1.0.0(react@18.2.0)
|
||||
'@radix-ui/react-use-rect': 1.0.0(react@18.2.0)
|
||||
'@radix-ui/react-use-size': 1.0.0(react@18.2.0)
|
||||
'@radix-ui/rect': 1.0.0
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0(react@18.2.0)
|
||||
transitivePeerDependencies:
|
||||
- '@types/react'
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-portal@1.0.2(react-dom@18.2.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-swu32idoCW7KA2VEiUZGBSu9nB6qwGdV6k6HYhUoOo3M1FFpD+VgLzUqtt3mwL1ssz7r2x8MggpLSQach2Xy/Q==}
|
||||
peerDependencies:
|
||||
|
@ -1738,6 +1809,40 @@ packages:
|
|||
react-dom: 18.2.0(react@18.2.0)
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-select@1.2.1(@types/react@18.0.28)(react-dom@18.2.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-GULRMITaOHNj79BZvQs3iZO0+f2IgI8g5HDhMi7Bnc13t7IlG86NFtOCfTLme4PNZdEtU+no+oGgcl6IFiphpQ==}
|
||||
peerDependencies:
|
||||
react: ^16.8 || ^17.0 || ^18.0
|
||||
react-dom: ^16.8 || ^17.0 || ^18.0
|
||||
dependencies:
|
||||
'@babel/runtime': 7.20.13
|
||||
'@radix-ui/number': 1.0.0
|
||||
'@radix-ui/primitive': 1.0.0
|
||||
'@radix-ui/react-collection': 1.0.2(react-dom@18.2.0)(react@18.2.0)
|
||||
'@radix-ui/react-compose-refs': 1.0.0(react@18.2.0)
|
||||
'@radix-ui/react-context': 1.0.0(react@18.2.0)
|
||||
'@radix-ui/react-direction': 1.0.0(react@18.2.0)
|
||||
'@radix-ui/react-dismissable-layer': 1.0.3(react-dom@18.2.0)(react@18.2.0)
|
||||
'@radix-ui/react-focus-guards': 1.0.0(react@18.2.0)
|
||||
'@radix-ui/react-focus-scope': 1.0.2(react-dom@18.2.0)(react@18.2.0)
|
||||
'@radix-ui/react-id': 1.0.0(react@18.2.0)
|
||||
'@radix-ui/react-popper': 1.1.1(@types/react@18.0.28)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@radix-ui/react-portal': 1.0.2(react-dom@18.2.0)(react@18.2.0)
|
||||
'@radix-ui/react-primitive': 1.0.2(react-dom@18.2.0)(react@18.2.0)
|
||||
'@radix-ui/react-slot': 1.0.1(react@18.2.0)
|
||||
'@radix-ui/react-use-callback-ref': 1.0.0(react@18.2.0)
|
||||
'@radix-ui/react-use-controllable-state': 1.0.0(react@18.2.0)
|
||||
'@radix-ui/react-use-layout-effect': 1.0.0(react@18.2.0)
|
||||
'@radix-ui/react-use-previous': 1.0.0(react@18.2.0)
|
||||
'@radix-ui/react-visually-hidden': 1.0.2(react-dom@18.2.0)(react@18.2.0)
|
||||
aria-hidden: 1.2.3
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0(react@18.2.0)
|
||||
react-remove-scroll: 2.5.5(@types/react@18.0.28)(react@18.2.0)
|
||||
transitivePeerDependencies:
|
||||
- '@types/react'
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-slot@1.0.1(react@18.2.0):
|
||||
resolution: {integrity: sha512-avutXAFL1ehGvAXtPquu0YK5oz6ctS474iM3vNGQIkswrVhdrS52e3uoMQBzZhNRAIE0jBnUyXWNmSjGHhCFcw==}
|
||||
peerDependencies:
|
||||
|
@ -1832,6 +1937,16 @@ packages:
|
|||
react: 18.2.0
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-use-rect@1.0.0(react@18.2.0):
|
||||
resolution: {integrity: sha512-TB7pID8NRMEHxb/qQJpvSt3hQU4sqNPM1VCTjTRjEOa7cEop/QMuq8S6fb/5Tsz64kqSvB9WnwsDHtjnrM9qew==}
|
||||
peerDependencies:
|
||||
react: ^16.8 || ^17.0 || ^18.0
|
||||
dependencies:
|
||||
'@babel/runtime': 7.20.13
|
||||
'@radix-ui/rect': 1.0.0
|
||||
react: 18.2.0
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-use-size@1.0.0(react@18.2.0):
|
||||
resolution: {integrity: sha512-imZ3aYcoYCKhhgNpkNDh/aTiU05qw9hX+HHI1QDBTyIlcFjgeFlKKySNGMwTp7nYFLQg/j0VA2FmCY4WPDDHMg==}
|
||||
peerDependencies:
|
||||
|
@ -1842,6 +1957,24 @@ packages:
|
|||
react: 18.2.0
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-visually-hidden@1.0.2(react-dom@18.2.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-qirnJxtYn73HEk1rXL12/mXnu2rwsNHDID10th2JGtdK25T9wX+mxRmGt7iPSahw512GbZOc0syZX1nLQGoEOg==}
|
||||
peerDependencies:
|
||||
react: ^16.8 || ^17.0 || ^18.0
|
||||
react-dom: ^16.8 || ^17.0 || ^18.0
|
||||
dependencies:
|
||||
'@babel/runtime': 7.20.13
|
||||
'@radix-ui/react-primitive': 1.0.2(react-dom@18.2.0)(react@18.2.0)
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0(react@18.2.0)
|
||||
dev: false
|
||||
|
||||
/@radix-ui/rect@1.0.0:
|
||||
resolution: {integrity: sha512-d0O68AYy/9oeEy1DdC07bz1/ZXX+DqCskRd3i4JzLSTXwefzaepQrKjXC7aNM8lTHjFLDO0pDgaEiQ7jEk+HVg==}
|
||||
dependencies:
|
||||
'@babel/runtime': 7.20.13
|
||||
dev: false
|
||||
|
||||
/@redis/bloom@1.2.0(@redis/client@1.5.6):
|
||||
resolution: {integrity: sha512-HG2DFjYKbpNmVXsa0keLHp/3leGJz1mjh09f2RLGGLQZzSHpkmZWuwJbAvo3QcRY8p80m5+ZdXZdYOSBLlp7Cg==}
|
||||
peerDependencies:
|
||||
|
@ -2097,6 +2230,10 @@ packages:
|
|||
engines: {node: '>= 10'}
|
||||
dev: true
|
||||
|
||||
/@total-typescript/shoehorn@0.1.0:
|
||||
resolution: {integrity: sha512-XKig6hXxWnUh0fsW3LR2vxpxwLlPFokfOSR0riHKA9uXvdHDfwOOPdAOi4U/YNKLmgYUu/plUfnF3yiAAz1+Zg==}
|
||||
dev: true
|
||||
|
||||
/@total-typescript/ts-reset@0.4.2:
|
||||
resolution: {integrity: sha512-vqd7ZUDSrXFVT1n8b2kc3LnklncDQFPvR58yUS1kEP23/nHPAO9l1lMjUfnPrXYYk4Hj54rrLKMW5ipwk7k09A==}
|
||||
dev: true
|
||||
|
|
|
@ -21,9 +21,6 @@ const DialogPortal = ({ className, children, ...props }: DialogPrimitive.DialogP
|
|||
<div className={clsx('modal modal-sm d-block', styles.dimmedBackground)}>
|
||||
<div className={clsx(`modal-dialog modal-dialog-centered modal-${props.size || 'lg'}`, styles.zoomIn)}>
|
||||
<div className="shadow modal-content">
|
||||
<DialogPrimitive.Close className="btn-close mt-1">
|
||||
<button data-testid="modal-close-button" type="button" className="btn-close" aria-label="Close" />
|
||||
</DialogPrimitive.Close>
|
||||
<div data-testid="modal-status" className={clsx('modal-status', { [`bg-${props.type}`]: Boolean(props.type), 'd-none': !props.type })} />
|
||||
{children}
|
||||
</div>
|
||||
|
@ -41,8 +38,12 @@ DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;
|
|||
const DialogContent = React.forwardRef<React.ElementRef<typeof DialogPrimitive.Content>, React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content> & ModalProps>(
|
||||
({ className, children, ...props }, ref) => (
|
||||
<DialogPortal type={props.type} size={props.size}>
|
||||
<DialogOverlay />
|
||||
<DialogPrimitive.Content ref={ref} className={clsx('modal-content mt-1', className)} {...props}>
|
||||
{children}
|
||||
<DialogPrimitive.Close className="btn-close">
|
||||
<button data-testid="modal-close-button" type="button" className="btn-close" aria-label="Close" />
|
||||
</DialogPrimitive.Close>
|
||||
</DialogPrimitive.Content>
|
||||
</DialogPortal>
|
||||
),
|
||||
|
|
|
@ -4,7 +4,7 @@ import clsx from 'clsx';
|
|||
interface IProps {
|
||||
placeholder?: string;
|
||||
error?: string;
|
||||
label?: string;
|
||||
label?: string | React.ReactNode;
|
||||
className?: string;
|
||||
isInvalid?: boolean;
|
||||
type?: HTMLInputElement['type'];
|
||||
|
|
76
src/client/components/ui/Select/Select.tsx
Normal file
76
src/client/components/ui/Select/Select.tsx
Normal file
|
@ -0,0 +1,76 @@
|
|||
'use client';
|
||||
|
||||
import * as React from 'react';
|
||||
import * as SelectPrimitive from '@radix-ui/react-select';
|
||||
import { IconCheck, IconChevronDown, IconChevronUp } from '@tabler/icons-react';
|
||||
import clsx from 'clsx';
|
||||
|
||||
type TriggerProps = {
|
||||
label?: string | React.ReactNode;
|
||||
error?: string;
|
||||
};
|
||||
|
||||
const Select: React.FC<React.ComponentPropsWithoutRef<typeof SelectPrimitive.Root> & { label?: string; error?: string; className?: string }> = ({ children, error, className, ...props }) => {
|
||||
return <SelectPrimitive.Root {...props}>{children}</SelectPrimitive.Root>;
|
||||
};
|
||||
|
||||
const SelectGroup = SelectPrimitive.Group;
|
||||
|
||||
const SelectValue = SelectPrimitive.Value;
|
||||
|
||||
// Button
|
||||
const SelectTrigger = React.forwardRef<React.ElementRef<typeof SelectPrimitive.Trigger>, React.ComponentPropsWithoutRef<typeof SelectPrimitive.Trigger> & TriggerProps>(
|
||||
({ className, error, label, children, ...props }, ref) => (
|
||||
<label htmlFor={props.name} aria-labelledby={props.name} className={clsx('w-100', className)}>
|
||||
{Boolean(label) && (
|
||||
<span id={props.name} className="form-label">
|
||||
{label}
|
||||
</span>
|
||||
)}
|
||||
<SelectPrimitive.Trigger ref={ref} className={clsx('d-flex w-100 align-items-center justify-content-between form-select', { 'is-invalid is-invalid-lite': error })} {...props}>
|
||||
{children}
|
||||
</SelectPrimitive.Trigger>
|
||||
{error && <div className="invalid-feedback">{error}</div>}
|
||||
</label>
|
||||
),
|
||||
);
|
||||
SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
|
||||
|
||||
const SelectContent = React.forwardRef<React.ElementRef<typeof SelectPrimitive.Content>, React.ComponentPropsWithoutRef<typeof SelectPrimitive.Content>>(({ className, children, ...props }, ref) => (
|
||||
<SelectPrimitive.Portal>
|
||||
<SelectPrimitive.Content ref={ref} style={{ zIndex: 2000 }} className={clsx('overflow-hidden dropdown-menu', className)} {...props}>
|
||||
<SelectPrimitive.ScrollUpButton className="d-flex align-items-center justify-content-center">
|
||||
<IconChevronUp />
|
||||
</SelectPrimitive.ScrollUpButton>
|
||||
<SelectPrimitive.Viewport className="p-1">{children}</SelectPrimitive.Viewport>
|
||||
<SelectPrimitive.ScrollDownButton className="d-flex align-items-center justify-content-center">
|
||||
<IconChevronDown />
|
||||
</SelectPrimitive.ScrollDownButton>
|
||||
</SelectPrimitive.Content>
|
||||
</SelectPrimitive.Portal>
|
||||
));
|
||||
SelectContent.displayName = SelectPrimitive.Content.displayName;
|
||||
|
||||
const SelectLabel = React.forwardRef<React.ElementRef<typeof SelectPrimitive.Label>, React.ComponentPropsWithoutRef<typeof SelectPrimitive.Label>>(({ className, ...props }, ref) => (
|
||||
<SelectPrimitive.Label ref={ref} className={clsx('', className)} {...props} />
|
||||
));
|
||||
SelectLabel.displayName = SelectPrimitive.Label.displayName;
|
||||
|
||||
const SelectItem = React.forwardRef<React.ElementRef<typeof SelectPrimitive.Item>, React.ComponentPropsWithoutRef<typeof SelectPrimitive.Item>>(({ className, children, ...props }, ref) => (
|
||||
<SelectPrimitive.Item ref={ref} className={clsx('ps-8 position-relative d-flex align-items-center dropdown-item', className)} {...props}>
|
||||
<SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>
|
||||
<span style={{ right: 8 }} className="position-absolute d-flex align-items-center justify-content-center">
|
||||
<SelectPrimitive.ItemIndicator>
|
||||
<IconCheck size={20} style={{ marginBottom: 3 }} />
|
||||
</SelectPrimitive.ItemIndicator>
|
||||
</span>
|
||||
</SelectPrimitive.Item>
|
||||
));
|
||||
SelectItem.displayName = SelectPrimitive.Item.displayName;
|
||||
|
||||
const SelectSeparator = React.forwardRef<React.ElementRef<typeof SelectPrimitive.Separator>, React.ComponentPropsWithoutRef<typeof SelectPrimitive.Separator>>(({ className, ...props }, ref) => (
|
||||
<SelectPrimitive.Separator ref={ref} className={clsx('', className)} {...props} />
|
||||
));
|
||||
SelectSeparator.displayName = SelectPrimitive.Separator.displayName;
|
||||
|
||||
export { Select, SelectGroup, SelectValue, SelectTrigger, SelectContent, SelectLabel, SelectItem, SelectSeparator };
|
1
src/client/components/ui/Select/index.ts
Normal file
1
src/client/components/ui/Select/index.ts
Normal file
|
@ -0,0 +1 @@
|
|||
export { Select, SelectItem, SelectContent, SelectTrigger, SelectValue, SelectGroup, SelectLabel, SelectSeparator } from './Select';
|
|
@ -7,7 +7,7 @@ import classes from './Switch.module.scss';
|
|||
|
||||
type RootProps = typeof SwitchPrimitives.Root;
|
||||
|
||||
const Switch = React.forwardRef<React.ElementRef<RootProps>, React.ComponentPropsWithoutRef<RootProps> & { label?: string }>(({ className, ...props }, ref) => (
|
||||
const Switch = React.forwardRef<React.ElementRef<RootProps>, React.ComponentPropsWithoutRef<RootProps> & { label?: string | React.ReactNode }>(({ className, ...props }, ref) => (
|
||||
<label htmlFor={props.name} aria-labelledby={props.name} className={clsx('form-check form-switch form-check-sigle', className)}>
|
||||
<SwitchPrimitives.Root name={props.name} className={clsx('form-check-input', classes.root)} {...props} ref={ref}>
|
||||
<SwitchPrimitives.Thumb />
|
||||
|
|
Loading…
Reference in a new issue