Skip to content

Commit

Permalink
feat: Add width prop to fields to control width (#2070)
Browse files Browse the repository at this point in the history
* custom width for fieldbase

* add width to fieldbase

* add with prop to checkbox

* width props for checkbox group

* add width prop to number field

* add width prop to radios

* add width prop to select

* add width prop to slider

* add width prop to switch

* add witdh to switch story

* lint

* add width prop to textarea

* add width prop to textfield

* Create thin-keys-cheer.md

* add witdth to doku
  • Loading branch information
sebald authored May 16, 2022
1 parent c35afcf commit a411723
Show file tree
Hide file tree
Showing 42 changed files with 586 additions and 145 deletions.
5 changes: 5 additions & 0 deletions .changeset/thin-keys-cheer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@marigold/components": minor
---

feat: Add `width` prop to fields to control width
13 changes: 7 additions & 6 deletions docs/content/components/checkbox.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,13 @@ import { Checkbox, CheckboxGroup } from '@marigold/components';

## Props

| Name | Type | Default | Description |
| :----------------- | :-------- | :---------- | :----------------------------------------------------------------------------------------------------------------- |
| `variant` | `string` | | Use a different _variant_ from theme |
| `size` | `string` | `'level-1'` | Use a different _size_ from theme |
| `error` (optional) | `boolean` | `false` | If `true`, the checkbox is considered invalid and if set the `errorMessage` is shown instead of the `description`. |
| ... | | | Yes you can use all regular attributes of `input`! |
| Name | Type | Default | Description |
| :------------------- | :-------- | :---------- | :----------------------------------------------------------------------------------------------------------------- |
| `variant` (optional) | `string` | | Use a different _variant_ from theme |
| `size` (optional) | `string` | `'level-1'` | Use a different _size_ from theme |
| `error` (optional) | `boolean` | `false` | If `true`, the checkbox is considered invalid and if set the `errorMessage` is shown instead of the `description`. |
| `width` (optional) | `string` | `100%` | Control the width of the field. |
| ... | | | Yes you can use all regular attributes of `input`! |

## Examples

Expand Down
1 change: 1 addition & 0 deletions docs/content/components/number-field.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import { NumberField } from '@marigold/components';
| `readOnly` (optional) | `boolean` | `false` | If `true`, the input is readOnly. |
| `onChange` (optional) | `function` | | A callback function that is called with the input's current `value` when the input value changes. |
| `formatOptions` (optional) | `Intl.NumberFormatOptions` | | Apply formatting. See [`Intl.NumberFormatOptions`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat) for available options. |
| `width` (optional) | `string` | `100%` | Control the width of the field. |
| ... | | | Yes you can use all regular attributes of `input`! |

## Examples
Expand Down
13 changes: 7 additions & 6 deletions docs/content/components/radio.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,13 @@ import { Radio } from '@marigold/components';

## Props

| Name | Type | Default | Description |
| :----------------- | :-------- | :---------- | :----------------------------------------------------------------------------------------------------------------- |
| `variant` | `string` | | Use a different _variant_ from theme |
| `size` | `string` | `'level-1'` | Use a different _size_ from theme |
| `error` (optional) | `boolean` | `false` | If `true`, the checkbox is considered invalid and if set the `errorMessage` is shown instead of the `description`. |
| ... | | | Yes you can use all regular attributes of `input`! |
| Name | Type | Default | Description |
| :------------------- | :-------- | :---------- | :----------------------------------------------------------------------------------------------------------------- |
| `variant` (optional) | `string` | | Use a different _variant_ from theme |
| `size` (optional) | `string` | `'level-1'` | Use a different _size_ from theme |
| `error` (optional) | `boolean` | `false` | If `true`, the checkbox is considered invalid and if set the `errorMessage` is shown instead of the `description`. |
| `width` (optional) | `string` | `100%` | Control the width of the field. |
| ... | | | Yes you can use all regular attributes of `input`! |

## Examples

Expand Down
1 change: 1 addition & 0 deletions docs/content/components/select.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ import { Select } from '@marigold/components';
| `errorMessage` (optional) | `string` | |
| `width` (optional) | `ResponsiveStyleValue<number⎮string>` | |
| `onSelectionChange` (optional) | `(key: Key) => any` | |
| `width` (optional) | `string` | `100%` |

## Examples

Expand Down
2 changes: 1 addition & 1 deletion docs/content/components/slider.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,12 @@ import { Slider } from '@marigold/components';
| Property | Type | Default | Description |
| :------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------- | :------ | :-------------------------------------------------------------- |
| `disabled` (optional) | `boolean` | `false` | If `true`, the slider is disabled. |
| `width` (optional) | `string, boolean` | `100%` | The slider's width value. |
| `value` (optional) | `number[]` | | The slider's value (controlled). |
| `defaultValue` (optional) | `number[]` | | The slider's default value (uncontrolled). |
| `maxValue` (optional) | `number` | `100` | The slider's maximum value. |
| `step` (optional) | `number` | | The slider's step value. |
| `formatOptions` (optional) | [`Intl.NumberFormatOptions`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat) | | The slider's step value. |
| `width` (optional) | `string` | `100%` | Control the width of the field. |
| ... | | | Yes you can use all regular attributes of `input type = range`! |

## Examples
Expand Down
5 changes: 3 additions & 2 deletions docs/content/components/switch.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,13 @@ import { Switch } from '@marigold/components';

## Props

| Property | Type | Default |
| :-------------------- | :-------- | :------ |
| Property | Type | Default | Description |
| :-------------------- | :-------- | :------ | ------------------------------- |
| `variant` (optional) | `string` | `` |
| `disabled` (optional) | `boolean` | `false` |
| `checked` (optional) | `boolean` | `false` |
| `size` (optional) | `string` | `` |
| `width` (optional) | `string` | `100%` | Control the width of the field. |

## Examples

Expand Down
3 changes: 2 additions & 1 deletion docs/content/components/text-area.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ import { TextArea } from '@marigold/components';
| `required` (optional) | `boolean` | `false` | If `true`, the input is required. |
| `readOnly` (optional) | `boolean` | `false` | If `true`, the input is readOnly. |
| `onChange` (optional) | `function` | | A callback function that is called with the input's current `value` when the input value changes. |
| others | | | Yes you can use all regular attributes of `textarea`! |
| `width` (optional) | `string` | `100%` | Control the width of the field. |
| ... | | | Yes you can use all regular attributes of `textarea`! |

## Examples

Expand Down
1 change: 1 addition & 0 deletions docs/content/components/text-field.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import { TextField } from '@marigold/components';
| `readOnly` (optional) | `boolean` | `false` | If `true`, the input is readOnly. |
| `type` (optional) | `string` | `text` | The type of the input field. |
| `onChange` (optional) | `function` | | A callback function that is called with the input's current `value` when the input value changes. |
| `width` (optional) | `string` | `100%` | Control the width of the field. |
| ... | | | Yes you can use all regular attributes of `input`! |

## Examples
Expand Down
6 changes: 6 additions & 0 deletions packages/components/src/Checkbox/Checkbox.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ export default {
description: 'Option to define an indeterminate state',
defaultValue: false,
},
width: {
control: {
type: 'text',
},
description: 'The width of the field',
},
},
} as Meta;

Expand Down
30 changes: 30 additions & 0 deletions packages/components/src/Checkbox/Checkbox.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ const theme = {
none: 0,
'small-1': 2,
},
sizes: {
none: 0,
large: 40,
},
components: {
Checkbox: {
base: {
Expand Down Expand Up @@ -172,6 +176,32 @@ test('allows styling "error" state via theme', () => {
expect(checkbox).toHaveStyle(`background: ${theme.colors.red}`);
});

test('takes full width by default', () => {
render(
<ThemeProvider theme={theme}>
<Checkbox data-testid="checkbox">With Label</Checkbox>
</ThemeProvider>
);

// eslint-disable-next-line testing-library/no-node-access
const container = screen.getByTestId('checkbox').parentElement;
expect(container).toHaveStyle('width: 100%');
});

test('allows to set width', () => {
render(
<ThemeProvider theme={theme}>
<Checkbox data-testid="checkbox" width="large">
With Label
</Checkbox>
</ThemeProvider>
);

// eslint-disable-next-line testing-library/no-node-access
const container = screen.getByTestId('checkbox').parentElement;
expect(container).toHaveStyle(`width: ${theme.sizes.large}px`);
});

test('support default checked', () => {
render(
<ThemeProvider theme={theme}>
Expand Down
7 changes: 5 additions & 2 deletions packages/components/src/Checkbox/Checkbox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
} from '@marigold/system';
import { ComponentProps } from '@marigold/types';

import { useCheckboxGroupContext } from './CheckboxGroup';
import { useCheckboxGroupContext } from './Context';

// Theme Extension
// ---------------
Expand Down Expand Up @@ -90,10 +90,11 @@ export interface CheckboxProps
extends ThemeComponentProps,
Omit<
ComponentProps<'input'>,
'size' | 'type' | 'defaultValue' | CustomCheckboxProps
'size' | 'width' | 'type' | 'defaultValue' | CustomCheckboxProps
>,
Pick<AriaCheckboxProps, CustomCheckboxProps> {
children?: ReactNode;
width?: string;
indeterminate?: boolean;
error?: boolean;
}
Expand All @@ -103,6 +104,7 @@ export interface CheckboxProps
export const Checkbox = ({
size,
variant,
width,
disabled,
checked,
defaultChecked,
Expand Down Expand Up @@ -186,6 +188,7 @@ export const Checkbox = ({
alignItems: 'center',
gap: '1ch',
position: 'relative',
width: width || groupState?.width || '100%',
}}
css={styles.container}
{...hoverProps}
Expand Down
6 changes: 6 additions & 0 deletions packages/components/src/Checkbox/CheckboxGroup.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ export default {
description: 'Error state',
defaultValue: false,
},
width: {
control: {
type: 'text',
},
description: 'The width of the group',
},
},
} as Meta;

Expand Down
53 changes: 52 additions & 1 deletion packages/components/src/Checkbox/CheckboxGroup.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ const theme = {
'small-1': 12,
'large-1': 24,
},
sizes: {
none: 0,
medium: 40,
large: 60,
},
components: {
Checkbox: {
base: {
Expand Down Expand Up @@ -164,6 +169,52 @@ test('passed down variant and size to checkboxes', () => {
);
});

test('passes down "width" to checkboxes', () => {
render(
<ThemeProvider theme={theme}>
<CheckboxGroup label="Group of Checkboxes" width="large">
<Checkbox value="one" data-testid="one">
one
</Checkbox>
<Checkbox value="two" data-testid="two">
two
</Checkbox>
</CheckboxGroup>
</ThemeProvider>
);

// eslint-disable-next-line testing-library/no-node-access
const oneContainer = screen.getByTestId('one').parentElement;
expect(oneContainer).toHaveStyle(`width: ${theme.sizes.large}px`);

// eslint-disable-next-line testing-library/no-node-access
const twoContainer = screen.getByTestId('two').parentElement;
expect(twoContainer).toHaveStyle(`width: ${theme.sizes.large}px`);
});

test('passed down "width" can be locally overriden', () => {
render(
<ThemeProvider theme={theme}>
<CheckboxGroup label="Group of Checkboxes" width="large">
<Checkbox value="one" data-testid="one">
one
</Checkbox>
<Checkbox value="two" data-testid="two" width="medium">
two
</Checkbox>
</CheckboxGroup>
</ThemeProvider>
);

// eslint-disable-next-line testing-library/no-node-access
const oneContainer = screen.getByTestId('one').parentElement;
expect(oneContainer).toHaveStyle(`width: ${theme.sizes.large}px`);

// eslint-disable-next-line testing-library/no-node-access
const twoContainer = screen.getByTestId('two').parentElement;
expect(twoContainer).toHaveStyle(`width: ${theme.sizes.medium}px`);
});

test('passes down "disabled" to checkboxes', () => {
render(
<CheckboxGroup label="Group of Checkboxes" disabled>
Expand Down Expand Up @@ -232,7 +283,7 @@ test('passes down "error" to checkboxes', () => {
);
});

test('constrolled', () => {
test('controlled', () => {
const onChange = jest.fn();
render(
<CheckboxGroup label="Group of Checkboxes" onChange={onChange}>
Expand Down
29 changes: 6 additions & 23 deletions packages/components/src/Checkbox/CheckboxGroup.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
import React, { createContext, ReactNode, useContext } from 'react';
import React, { ReactNode } from 'react';
import { useCheckboxGroup } from '@react-aria/checkbox';
import {
CheckboxGroupState,
useCheckboxGroupState,
} from '@react-stately/checkbox';
import { useCheckboxGroupState } from '@react-stately/checkbox';
import { AriaCheckboxGroupProps } from '@react-types/checkbox';

import {
Expand All @@ -14,23 +11,7 @@ import {
import { ComponentProps } from '@marigold/types';

import { Label } from '../Label';

// Context
// ---------------
export interface CheckboxGroupContextProps extends CheckboxGroupState {
error?: boolean;
variant?: string;
size?: string;
}

/**
* Needs to be falsy so we can check if a checkbox is used as standalone
* or in a group.
*/
export const CheckboxGroupContext = createContext<CheckboxGroupContextProps>(
null as any
);
export const useCheckboxGroupContext = () => useContext(CheckboxGroupContext);
import { CheckboxGroupContext } from './Context';

// Theme Extension
// ---------------
Expand All @@ -45,6 +26,7 @@ interface CheckboxGroupProps
children: ReactNode;
variant?: string;
size?: string;
width?: string;
label?: ReactNode;
required?: boolean;
disabled?: boolean;
Expand All @@ -61,6 +43,7 @@ export const CheckboxGroup = ({
children,
variant,
size,
width,
required,
disabled,
readOnly,
Expand Down Expand Up @@ -101,7 +84,7 @@ export const CheckboxGroup = ({
css={styles.group}
>
<CheckboxGroupContext.Provider
value={{ variant, size, error, ...state }}
value={{ variant, size, width, error, ...state }}
>
{children}
</CheckboxGroupContext.Provider>
Expand Down
18 changes: 18 additions & 0 deletions packages/components/src/Checkbox/Context.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { createContext, useContext } from 'react';
import { CheckboxGroupState } from '@react-stately/checkbox';

export interface CheckboxGroupContextProps extends CheckboxGroupState {
error?: boolean;
variant?: string;
size?: string;
width?: string;
}

/**
* Needs to be falsy so we can check if a checkbox is used as standalone
* or in a group.
*/
export const CheckboxGroupContext = createContext<CheckboxGroupContextProps>(
null as any
);
export const useCheckboxGroupContext = () => useContext(CheckboxGroupContext);
6 changes: 6 additions & 0 deletions packages/components/src/FieldBase/FieldBase.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,12 @@ export default {
description: 'Whether the help text is an error',
defaultValue: false,
},
width: {
control: {
type: 'text',
},
description: 'The width of the field',
},
},
} as Meta;

Expand Down
Loading

0 comments on commit a411723

Please sign in to comment.