Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/metal-pumpkins-appear.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@cube-dev/ui-kit": patch
---

Full items prop support in FilterPicker.
5 changes: 2 additions & 3 deletions src/components/actions/Button/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ export const DEFAULT_BUTTON_STYLES = {
},

ButtonIcon: {
width: 'max-content',
width: 'min 1fs',
},

'& [data-element="ButtonIcon"]:first-child:not(:last-child)': {
Expand Down Expand Up @@ -722,8 +722,7 @@ export const Button = forwardRef(function Button(
<LoadingIcon data-element="ButtonIcon" />
)
) : null}
{((hasIcons && children) || (!!icon && !!rightIcon)) &&
typeof children === 'string' ? (
{hasIcons && typeof children === 'string' ? (
<Text ellipsis>{children}</Text>
) : (
children
Expand Down
4 changes: 2 additions & 2 deletions src/components/fields/FilterListBox/FilterListBox.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1187,12 +1187,12 @@ EscapeKeyHandling.parameters = {
};

export const VirtualizedList: StoryFn<CubeFilterListBoxProps<any>> = (args) => {
const [selectedKeys, setSelectedKeys] = useState<string[]>([]);
const [selectedKeys, setSelectedKeys] = useState<string[]>(['item-2']);

// Generate a large list of items with varying content to test virtualization
// Mix items with and without descriptions to test dynamic sizing
const items = Array.from({ length: 100 }, (_, i) => ({
id: `item-${i}`,
id: `item-${i + 1}`,
name: `Item ${i + 1}${i % 7 === 0 ? ' - This is a longer item name to test dynamic sizing' : ''}`,
description:
i % 3 === 0
Expand Down
13 changes: 6 additions & 7 deletions src/components/fields/FilterPicker/FilterPicker.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1526,12 +1526,12 @@ export const VirtualizedList: Story = {
await userEvent.click(trigger);
},
render: (args) => {
const [selectedKeys, setSelectedKeys] = useState<string[]>([]);
const [selectedKeys, setSelectedKeys] = useState<string[]>(['item-2']);

// Generate a large list of items with varying content to trigger virtualization
// Mix items with and without descriptions to test dynamic sizing
const items = Array.from({ length: 100 }, (_, i) => ({
id: `item-${i}`,
id: `item-${i + 1}`,
name: `Item ${i + 1}${i % 7 === 0 ? ' - This is a longer item name to test dynamic sizing' : ''}`,
description:
i % 3 === 0
Expand Down Expand Up @@ -1584,15 +1584,15 @@ export const VirtualizedList: Story = {

export const WithSelectAll: Story = {
render: (args) => (
<FilterPicker {...args}>
{permissions.map((permission) => (
<FilterPicker items={permissions} {...args}>
{(permission: any) => (
<FilterPicker.Item
key={permission.key}
description={permission.description}
>
{permission.label}
</FilterPicker.Item>
))}
)}
</FilterPicker>
),
args: {
Expand All @@ -1603,8 +1603,7 @@ export const WithSelectAll: Story = {
showSelectAll: true,
selectAllLabel: 'All Permissions',
defaultSelectedKeys: ['read'],
type: 'outline',
size: 'medium',
width: '30x',
},
parameters: {
docs: {
Expand Down
71 changes: 71 additions & 0 deletions src/components/fields/FilterPicker/FilterPicker.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -843,4 +843,75 @@ describe('<FilterPicker />', () => {
expect(options[1]).toHaveTextContent('Apple');
});
});

describe('Items prop functionality', () => {
const itemsWithLabels = [
{ key: 'apple', label: 'Red Apple' },
{ key: 'banana', label: 'Yellow Banana' },
{ key: 'cherry', label: 'Sweet Cherry' },
];

it('should display labels correctly when using items prop with label property', async () => {
const { getByRole } = renderWithRoot(
<FilterPicker
label="Select fruits"
placeholder="Choose fruits..."
selectionMode="single"
items={itemsWithLabels}
selectedKey="apple"
>
{(item) => (
<FilterPicker.Item key={item.key}>{item.label}</FilterPicker.Item>
)}
</FilterPicker>,
);

// Wait for component to render
await act(async () => {
await new Promise((resolve) => setTimeout(resolve, 50));
});

const trigger = getByRole('button');

// Should display the label, not the key
expect(trigger).toHaveTextContent('Red Apple');
expect(trigger).not.toHaveTextContent('apple');
});

it('should display correct labels in multiple selection mode with items prop', async () => {
const renderSummary = jest.fn(
({ selectedLabels }) => `Selected: ${selectedLabels.join(', ')}`,
);

const { getByRole } = renderWithRoot(
<FilterPicker
label="Select fruits"
placeholder="Choose fruits..."
selectionMode="multiple"
items={itemsWithLabels}
selectedKeys={['apple', 'cherry']}
renderSummary={renderSummary}
>
{(item) => (
<FilterPicker.Item key={item.key}>{item.label}</FilterPicker.Item>
)}
</FilterPicker>,
);

// Wait for component to render
await act(async () => {
await new Promise((resolve) => setTimeout(resolve, 50));
});

// Check that renderSummary was called with correct labels
expect(renderSummary).toHaveBeenCalledWith({
selectedLabels: ['Red Apple', 'Sweet Cherry'],
selectedKeys: ['apple', 'cherry'],
selectionMode: 'multiple',
});

const trigger = getByRole('button');
expect(trigger).toHaveTextContent('Selected: Red Apple, Sweet Cherry');
});
});
});
Loading
Loading