From 963f2066273f1879659b1a0f96022af9abb25cbf Mon Sep 17 00:00:00 2001 From: Kamil Emeleev Date: Tue, 10 Mar 2026 14:52:03 +0300 Subject: [PATCH 1/2] feat(DatePicker): add `triggerButton` slot --- .../components/DatePicker/DatePicker.test.tsx | 24 ++++++++++++ .../src/components/DatePicker/DatePicker.tsx | 38 +++++++++++-------- .../src/components/DatePicker/types.ts | 2 + 3 files changed, 49 insertions(+), 15 deletions(-) diff --git a/packages/components/src/components/DatePicker/DatePicker.test.tsx b/packages/components/src/components/DatePicker/DatePicker.test.tsx index 82d1617b..855f5ebf 100644 --- a/packages/components/src/components/DatePicker/DatePicker.test.tsx +++ b/packages/components/src/components/DatePicker/DatePicker.test.tsx @@ -1,6 +1,7 @@ import { createRef } from 'react'; import type { CalendarDate } from '@internationalized/date'; +import { IconClock16 } from '@koobiq/react-icons'; import { screen, render } from '@testing-library/react'; import { describe, it, expect } from 'vitest'; @@ -65,4 +66,27 @@ describe('DatePicker', () => { expect(getRoot()).toHaveTextContent('fail'); }); + + it('should allow custom open button icon via triggerButton slot', () => { + render( + , + }, + }} + /> + ); + + const openButton = screen.getByRole('button'); + + expect(screen.getByTestId('custom-open-icon')).toBeInTheDocument(); + + expect( + openButton.querySelector('svg[data-testid="custom-open-icon"]') + ).toBeInTheDocument(); + + expect(openButton.querySelectorAll('svg')).toHaveLength(1); + }); }); diff --git a/packages/components/src/components/DatePicker/DatePicker.tsx b/packages/components/src/components/DatePicker/DatePicker.tsx index a78aad20..a2325eb1 100644 --- a/packages/components/src/components/DatePicker/DatePicker.tsx +++ b/packages/components/src/components/DatePicker/DatePicker.tsx @@ -79,23 +79,31 @@ export function DatePickerRender( // eslint-disable-next-line no-unsafe-optional-chaining const { slotProps: rootSlotProps, ...otherRoot } = slotProps?.root || {}; + const triggerButtonProps = mergeProps( + { + variant: isInvalid ? 'error' : 'fade-contrast', + className: s.calendar, + children: , + }, + buttonProps, + slotProps?.triggerButton + ); + const mergedRootSlotProps = { ...rootSlotProps, - group: mergeProps(rootSlotProps?.group, groupProps, { - ref: anchorRef, - endAddon: ( - <> - {endAddon} - - - - - ), - }), + group: mergeProps( + groupProps, + { + ref: anchorRef, + endAddon: ( + <> + {endAddon} + + + ), + }, + rootSlotProps?.group + ), }; const rootProps = mergeProps( diff --git a/packages/components/src/components/DatePicker/types.ts b/packages/components/src/components/DatePicker/types.ts index 3f3889d1..9d2d0a6a 100644 --- a/packages/components/src/components/DatePicker/types.ts +++ b/packages/components/src/components/DatePicker/types.ts @@ -10,6 +10,7 @@ import type { DateInputRef, } from '../DateInput'; import type { FormFieldLabelProps } from '../FormField'; +import type { IconButtonProps } from '../IconButton'; import type { PopoverProps } from '../Popover'; export type DatePickerProps = { @@ -48,6 +49,7 @@ export type DatePickerProps = { label?: FormFieldLabelProps; popover?: PopoverProps; calendar?: CalendarProps; + triggerButton?: IconButtonProps; }; } & Omit, 'description' | 'validationState'>; From bf13c3cb56d538cbc4a6b4fe407940865f6f4aab Mon Sep 17 00:00:00 2001 From: Kamil Emeleev Date: Tue, 10 Mar 2026 15:01:58 +0300 Subject: [PATCH 2/2] test(DatePicker): simplify triggerButton test --- .../src/components/DatePicker/DatePicker.test.tsx | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/packages/components/src/components/DatePicker/DatePicker.test.tsx b/packages/components/src/components/DatePicker/DatePicker.test.tsx index 855f5ebf..61a7ae04 100644 --- a/packages/components/src/components/DatePicker/DatePicker.test.tsx +++ b/packages/components/src/components/DatePicker/DatePicker.test.tsx @@ -1,7 +1,6 @@ import { createRef } from 'react'; import type { CalendarDate } from '@internationalized/date'; -import { IconClock16 } from '@koobiq/react-icons'; import { screen, render } from '@testing-library/react'; import { describe, it, expect } from 'vitest'; @@ -73,7 +72,7 @@ describe('DatePicker', () => { {...baseProps} slotProps={{ triggerButton: { - children: , + children: , }, }} /> @@ -84,9 +83,9 @@ describe('DatePicker', () => { expect(screen.getByTestId('custom-open-icon')).toBeInTheDocument(); expect( - openButton.querySelector('svg[data-testid="custom-open-icon"]') + openButton.querySelector('[data-testid="custom-open-icon"]') ).toBeInTheDocument(); - expect(openButton.querySelectorAll('svg')).toHaveLength(1); + expect(openButton.querySelector('svg')).not.toBeInTheDocument(); }); });