Skip to content

Commit 7d59ddd

Browse files
authored
fix(NumberInput): right padding (#864)
1 parent d8e8982 commit 7d59ddd

File tree

10 files changed

+183
-14
lines changed

10 files changed

+183
-14
lines changed

.changeset/afraid-adults-thank.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
"@cube-dev/ui-kit": patch
3+
---
4+
5+
Replace `noCard` prop with `type` prop in ListBox component. The new `type` prop accepts three values:
6+
- `card` (default): Standard card styling with border and margin
7+
- `plain`: No border, no margin, no radius - suitable for embedded use
8+
- `popover`: No border, but keeps margin and radius - suitable for overlay use

.changeset/cuddly-meals-compete.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@cube-dev/ui-kit": patch
3+
---
4+
5+
Remove the hardcoded default width for NumberInput.

.changeset/tame-bananas-teach.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@cube-dev/ui-kit": patch
3+
---
4+
5+
Fix right padding in NumberInput.

src/components/fields/ComboBox/ComboBox.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -929,9 +929,7 @@ function ComboBoxOverlay({
929929
headingStyles={headingStyles}
930930
stateRef={listStateRef}
931931
size="medium"
932-
mods={{
933-
popover: true,
934-
}}
932+
type="popover"
935933
onSelectionChange={onSelectionChange}
936934
>
937935
{children as any}

src/components/fields/FilterListBox/FilterListBox.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ const StyledHeaderWithoutBorder = tasty(StyledHeader, {
103103
});
104104

105105
export interface CubeFilterListBoxProps<T>
106-
extends Omit<CubeListBoxProps<T>, 'filter'>,
106+
extends Omit<CubeListBoxProps<T>, 'filter' | 'type'>,
107107
FieldBaseProps {
108108
/** Placeholder text for the search input */
109109
searchPlaceholder?: string;

src/components/fields/ListBox/ListBox.docs.mdx

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,16 @@ The `mods` property accepts the following modifiers you can override:
126126
- Array of keys for items that should be disabled
127127
- Disabled items cannot be selected and are visually distinguished
128128

129+
### Visual Styling
130+
131+
**type** (`'card' | 'plain' | 'popover'`, default: `'card'`)
132+
- Controls the visual styling of the ListBox container
133+
- `card`: Standard card styling with border and margin (default)
134+
- `plain`: No border, no margin, no radius - suitable for embedded use
135+
- `popover`: No border, but keeps margin and radius - suitable for overlay use
136+
- Use `plain` when embedding ListBox directly into another component
137+
- Use `popover` when using ListBox inside overlays (Dialog, ComboBox, Picker)
138+
129139
### Focus and Interaction
130140

131141
**focusOnHover** (`boolean`, default: `true`)
@@ -515,6 +525,30 @@ const [selectedKey, setSelectedKey] = useState('apple');
515525
</ListBox>
516526
```
517527

528+
### Visual Type Variants
529+
530+
<Story of={ListBoxStories.TypeVariants} />
531+
532+
```jsx
533+
{/* Card type (default) - with border and margin */}
534+
<ListBox type="card" label="Select a fruit" selectionMode="single">
535+
<ListBox.Item key="apple">Apple</ListBox.Item>
536+
<ListBox.Item key="banana">Banana</ListBox.Item>
537+
</ListBox>
538+
539+
{/* Plain type - no border, no margin, no radius */}
540+
<ListBox type="plain" label="Select a fruit" selectionMode="single">
541+
<ListBox.Item key="apple">Apple</ListBox.Item>
542+
<ListBox.Item key="banana">Banana</ListBox.Item>
543+
</ListBox>
544+
545+
{/* Popover type - no border, but keeps margin and radius */}
546+
<ListBox type="popover" label="Select a fruit" selectionMode="single">
547+
<ListBox.Item key="apple">Apple</ListBox.Item>
548+
<ListBox.Item key="banana">Banana</ListBox.Item>
549+
</ListBox>
550+
```
551+
518552
### Custom Escape Handling
519553

520554
<Story of={ListBoxStories.EscapeKeyHandling} />

src/components/fields/ListBox/ListBox.stories.tsx

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,14 @@ const meta: any = {
8282
defaultValue: { summary: 'medium' },
8383
},
8484
},
85+
type: {
86+
options: ['card', 'plain', 'popover'],
87+
control: { type: 'radio' },
88+
description: 'Visual type of the ListBox',
89+
table: {
90+
defaultValue: { summary: 'card' },
91+
},
92+
},
8593
header: {
8694
control: { type: 'text' },
8795
description: 'Custom header content',
@@ -1392,3 +1400,102 @@ export const AllValuePropsExample: Story = {
13921400
},
13931401
},
13941402
};
1403+
1404+
export const TypeVariants: Story = {
1405+
render: () => (
1406+
<Space gap="4x" flow="column">
1407+
<div>
1408+
<Text preset="t3" weight="600">
1409+
Card Type (default)
1410+
</Text>
1411+
<Text preset="t4" color="#dark.60">
1412+
Standard card styling with border and margin
1413+
</Text>
1414+
<Space height="1x" />
1415+
<ListBox
1416+
type="card"
1417+
label="Select a fruit"
1418+
selectionMode="single"
1419+
defaultSelectedKey="apple"
1420+
>
1421+
{fruits.slice(0, 4).map((fruit) => (
1422+
<ListBox.Item key={fruit.key}>{fruit.label}</ListBox.Item>
1423+
))}
1424+
</ListBox>
1425+
</div>
1426+
1427+
<div>
1428+
<Text preset="t3" weight="600">
1429+
Plain Type
1430+
</Text>
1431+
<Text preset="t4" color="#dark.60">
1432+
No border, no margin, no radius - suitable for embedded use
1433+
</Text>
1434+
<Space height="1x" />
1435+
<ListBox
1436+
type="plain"
1437+
label="Select a fruit"
1438+
selectionMode="single"
1439+
defaultSelectedKey="banana"
1440+
>
1441+
{fruits.slice(0, 4).map((fruit) => (
1442+
<ListBox.Item key={fruit.key}>{fruit.label}</ListBox.Item>
1443+
))}
1444+
</ListBox>
1445+
</div>
1446+
1447+
<div>
1448+
<Text preset="t3" weight="600">
1449+
Popover Type
1450+
</Text>
1451+
<Text preset="t4" color="#dark.60">
1452+
No border, but keeps margin and radius - suitable for overlay use
1453+
</Text>
1454+
<Space height="1x" />
1455+
<ListBox
1456+
type="popover"
1457+
label="Select a fruit"
1458+
selectionMode="single"
1459+
defaultSelectedKey="cherry"
1460+
>
1461+
{fruits.slice(0, 4).map((fruit) => (
1462+
<ListBox.Item key={fruit.key}>{fruit.label}</ListBox.Item>
1463+
))}
1464+
</ListBox>
1465+
</div>
1466+
1467+
<div>
1468+
<Text preset="t3" weight="600">
1469+
Plain Type with Sections
1470+
</Text>
1471+
<Text preset="t4" color="#dark.60">
1472+
Section margins are preserved even with plain type
1473+
</Text>
1474+
<Space height="1x" />
1475+
<ListBox
1476+
type="plain"
1477+
label="Select food items"
1478+
selectionMode="single"
1479+
defaultSelectedKey="carrot"
1480+
>
1481+
<ListBox.Section title="Fruits">
1482+
<ListBox.Item key="apple">Apple</ListBox.Item>
1483+
<ListBox.Item key="banana">Banana</ListBox.Item>
1484+
</ListBox.Section>
1485+
<ListBox.Section title="Vegetables">
1486+
<ListBox.Item key="carrot">Carrot</ListBox.Item>
1487+
<ListBox.Item key="broccoli">Broccoli</ListBox.Item>
1488+
</ListBox.Section>
1489+
</ListBox>
1490+
</div>
1491+
</Space>
1492+
),
1493+
parameters: {
1494+
docs: {
1495+
description: {
1496+
story:
1497+
'The `type` prop controls the visual styling of the ListBox. Use `card` for standalone use, `plain` for embedded use without decoration, and `popover` for use inside overlays where borders are handled by the container.',
1498+
},
1499+
},
1500+
},
1501+
};

src/components/fields/ListBox/ListBox.tsx

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,11 @@ const ListBoxWrapperElement = tasty({
6565
flow: 'column',
6666
gap: 0,
6767
position: 'relative',
68-
radius: '1cr',
68+
radius: {
69+
'': '1cr',
70+
'[data-type="popover"]': '(1cr - 1bw)',
71+
'[data-type="plain"]': '0',
72+
},
6973
color: '#dark-02',
7074
transition: 'theme',
7175
outline: {
@@ -79,7 +83,7 @@ const ListBoxWrapperElement = tasty({
7983
valid: '#success-text.50',
8084
invalid: '#danger-text.50',
8185
disabled: true,
82-
'popover | searchable': false,
86+
'[data-type="plain"] | [data-type="popover"] | searchable': false,
8387
},
8488
},
8589
});
@@ -93,7 +97,7 @@ const ListElement = tasty({
9397
boxSizing: 'border-box',
9498
margin: {
9599
'': '.5x .5x 0 .5x',
96-
sections: '.5x .5x 0 .5x',
100+
'[data-type="plain"]': '0',
97101
},
98102
height: 'max-content',
99103
},
@@ -309,6 +313,15 @@ export interface CubeListBoxProps<T>
309313
* Defaults to "No items".
310314
*/
311315
emptyLabel?: ReactNode;
316+
317+
/**
318+
* Visual type of the ListBox styling.
319+
* - `card` (default): Standard card styling with border and margin
320+
* - `plain`: No border, no margin, no radius - suitable for embedded use
321+
* - `popover`: No border, but keeps margin and radius - suitable for overlay use
322+
* Defaults to 'card'.
323+
*/
324+
type?: 'card' | 'plain' | 'popover';
312325
}
313326

314327
const PROP_STYLES = [...BASE_STYLES, ...OUTER_STYLES, ...COLOR_STYLES];
@@ -516,6 +529,7 @@ export const ListBox = forwardRef(function ListBox<T extends object>(
516529
allValueProps,
517530
filter,
518531
emptyLabel = 'No items',
532+
type = 'card',
519533
form,
520534
...otherProps
521535
} = props;
@@ -861,6 +875,7 @@ export const ListBox = forwardRef(function ListBox<T extends object>(
861875
qa="ListBoxWrapper"
862876
mods={mods}
863877
styles={styles}
878+
data-type={type}
864879
>
865880
{header ? (
866881
<StyledHeader styles={headerStyles} data-size={size}>
@@ -902,6 +917,7 @@ export const ListBox = forwardRef(function ListBox<T extends object>(
902917
styles={listStyles}
903918
aria-disabled={isDisabled || undefined}
904919
mods={{ sections: hasSections }}
920+
data-type={type}
905921
style={
906922
shouldVirtualize
907923
? {

src/components/fields/NumberInput/NumberInput.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,6 @@ const StyledTextInputBase = tasty(TextInputBase, {
2424
styles: {
2525
textAlign: 'right',
2626
},
27-
wrapperStyles: {
28-
width: 'initial 13x 100%',
29-
},
3027
});
3128

3229
const StepperContainer = tasty({
@@ -36,6 +33,7 @@ const StepperContainer = tasty({
3633
gridRows: '1sf 1sf',
3734
flow: 'column',
3835
placeSelf: 'stretch',
36+
margin: '(.5x - 1bw) left',
3937
},
4038
});
4139

src/components/fields/Picker/Picker.tsx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ import { CubeListBoxProps, ListBox } from '../ListBox/ListBox';
4444
import type { FieldBaseProps } from '../../../shared';
4545

4646
export interface CubePickerProps<T>
47-
extends Omit<CubeListBoxProps<T>, 'size' | 'tooltip'>,
47+
extends Omit<CubeListBoxProps<T>, 'size' | 'tooltip' | 'type'>,
4848
Omit<CubeItemProps, 'children' | 'size'>,
4949
BasePropsWithoutChildren,
5050
BaseStyleProps,
@@ -683,9 +683,7 @@ export const Picker = forwardRef(function Picker<T extends object>(
683683
isLoading={isLoading}
684684
stateRef={internalListStateRef}
685685
isCheckable={isCheckable}
686-
mods={{
687-
popover: true,
688-
}}
686+
type="popover"
689687
size="medium"
690688
showSelectAll={showSelectAll}
691689
selectAllLabel={selectAllLabel}

0 commit comments

Comments
 (0)