Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add fluid button set #15843

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
//
// Copyright IBM Corp. 2024, 2024
//
// This source code is licensed under the Apache-2.0 license found in the
// LICENSE file in the root directory of this source tree.
//

@use '@carbon/react/scss/spacing' as *;
@use '@carbon/react/scss/theme' as *;
@use '@carbon/react/scss/type' as *;
@use '../prefix' as *;

$block-class: #{$prefix}--display-box;

$indicator-width: $spacing-02;
$indicator-height: $spacing-04;

/**
Adds a box indicating the extent of the available space to the displayed component
*/
.#{$block-class} {
display: inline-block;
color: $text-helper;
margin-block-start: $spacing-09; /* provides space in docs */
max-inline-size: 100%;
padding-block-start: $spacing-05; /* space for the indicators */
}

.#{$block-class}__story {
inline-size: var(--container-width, 400);
max-inline-size: 100%;
}

.#{$block-class}__indicator {
position: relative;
border-block-end: 1px solid $text-helper;
inline-size: 100%;
inset-block-start: 0;
margin-block: $spacing-05;
white-space: nowrap;
@include type-style('helper-text-01');
}

.#{$block-class}__message {
inset-block-end: $spacing-02;
}

.sb-main-centered .#{$block-class}__message {
inset-inline-start: 50%;
min-inline-size: 100vh;
text-align: center;
transform: translateX(-50%);
}

.#{$block-class}__indicator--left,
.#{$block-class}__indicator--right {
position: absolute;
block-size: 0;
border-block-start: $indicator-height solid $text-helper;
border-inline-end: $indicator-width solid transparent;
border-inline-start: $indicator-width solid transparent;
inline-size: 0;
inset-block-end: calc(-1 * $indicator-height);
}

.#{$block-class}__indicator--left {
inset-inline-start: calc(-1 * $indicator-width);
}

.#{$block-class}__indicator--right {
inset-inline-end: calc(-1 * $indicator-width);
}
54 changes: 54 additions & 0 deletions packages/react/.storybook/templates/WithDisplayBox/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/**
* Copyright IBM Corp. 2024, 2024
*
* This source code is licensed under the Apache-2.0 license found in the
* LICENSE file in the root directory of this source tree.
*/

import PropTypes from 'prop-types';
import React, { useState } from 'react';
import cx from 'classnames';
import { prefix } from '../_prefix';
import { Form, Slider } from '../../../src';
import './WithDisplayBox.scss';

const blockClass = `${prefix}--display-box`;

function WithDisplayBox({ children, className, msg }) {
const [width, setWidth] = useState(400);

return (
<div
className={cx(blockClass, className)}
style={{ '--container-width': `${width}px` }}>
<Form>
<Slider
max={1600}
min={100}
step={5}
value={width}
onChange={({ value }) => setWidth(value)}
labelText="Adjust maximum width of container in which the component is displayed."
/>
</Form>
<div className={`${blockClass}__story`}>
<div className={`${blockClass}__indicator`}>
<div className={`${blockClass}__message`}>
Width available to component (not part of component).
</div>
<div className={`${blockClass}__indicator--left`} />
<div className={`${blockClass}__indicator--right`} />
</div>
{children}
</div>
</div>
);
}

WithDisplayBox.propTypes = {
children: PropTypes.node,
className: PropTypes.string,
msg: PropTypes.node,
};

export { WithDisplayBox };
Original file line number Diff line number Diff line change
Expand Up @@ -523,6 +523,9 @@ Map {
"className": Object {
"type": "string",
},
"fluid": Object {
"type": "bool",
},
"stacked": Object {
"type": "bool",
},
Expand Down
49 changes: 48 additions & 1 deletion packages/react/src/components/Button/Button.stories.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright IBM Corp. 2016, 2023
* Copyright IBM Corp. 2016, 2024
*
* This source code is licensed under the Apache-2.0 license found in the
* LICENSE file in the root directory of this source tree.
Expand All @@ -12,6 +12,12 @@ import { default as Button, ButtonSkeleton } from '../Button';
import ButtonSet from '../ButtonSet';
import mdx from './Button.mdx';
import './button-story.scss';
import { WithDisplayBox } from '../../../.storybook/templates/WithDisplayBox';
import {
fluidButtonLabels,
fluidButtonMapping,
fluidButtonOptions,
} from './__story__/fluid-button-set-args';

export default {
title: 'Components/Button',
Expand Down Expand Up @@ -135,3 +141,44 @@ export const Skeleton = () => (
<ButtonSkeleton size="sm" />
</div>
);

export const SetOfButtonsFluid = {
parameters: {
controls: {
include: ['Fluid Buttons', 'Stacked'],
},
},
argTypes: {
'Fluid Buttons': {
control: {
type: 'select',
labels: fluidButtonLabels,
},
options: fluidButtonOptions,
mapping: fluidButtonMapping,
},
},
render: ({ ...rest }) => {
const buttons = rest['Fluid Buttons'];

if (!buttons || buttons === 0) {
return <div>Select one or more buttons.</div>;
}

return (
<WithDisplayBox>
<ButtonSet fluid>
{buttons.map(({ label, kind, key }) => (
<Button key={key} kind={kind}>
{label}
</Button>
))}
</ButtonSet>
</WithDisplayBox>
);
},
};

SetOfButtonsFluid.args = {
'Fluid Buttons': 1,
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/**
* Copyright IBM Corp. 2024, 2024
*
* This source code is licensed under the Apache-2.0 license found in the
* LICENSE file in the root directory of this source tree.
*/

const btn = (label, kind, key) => {
return {

Check warning on line 9 in packages/react/src/components/Button/__story__/fluid-button-set-args.js

View check run for this annotation

Codecov / codecov/patch

packages/react/src/components/Button/__story__/fluid-button-set-args.js#L8-L9

Added lines #L8 - L9 were not covered by tests
label,
kind,
key,
};
};

const primary = btn('Primary', 'primary', 1);
const danger = btn('Danger', 'danger', 2);
const secondary = btn('Secondary', 'secondary', 3);
const secondary2 = btn('Secondary 2', 'secondary 2', 4);
const tertiary = btn('Tertiary', 'tertiary', 5);
const dangerGhost = btn('Danger-ghost', 'danger--ghost', 6);
const ghost = btn('Ghost', 'ghost', 7);

Check warning on line 22 in packages/react/src/components/Button/__story__/fluid-button-set-args.js

View check run for this annotation

Codecov / codecov/patch

packages/react/src/components/Button/__story__/fluid-button-set-args.js#L16-L22

Added lines #L16 - L22 were not covered by tests

const fluidButtonSets = [

Check warning on line 24 in packages/react/src/components/Button/__story__/fluid-button-set-args.js

View check run for this annotation

Codecov / codecov/patch

packages/react/src/components/Button/__story__/fluid-button-set-args.js#L24

Added line #L24 was not covered by tests
{ label: 'None', mapping: [] },
{ label: 'One button', mapping: [primary] },
{ label: 'A danger button', mapping: [danger] },
{ label: 'A ghost button', mapping: [ghost] },
{ label: 'Two buttons', mapping: [secondary, primary] },
{ label: 'Two buttons with one ghost', mapping: [ghost, primary] },
{ label: 'Three buttons', mapping: [secondary, secondary2, primary] },
{
label: 'Three buttons with one ghost',
mapping: [ghost, secondary, primary],
},
{
label: 'Three buttons with one danger',
mapping: [ghost, secondary, danger],
},
{
label: 'Four buttons',
mapping: [tertiary, secondary, secondary2, primary],
},
{
label: 'Four buttons with one ghost',
mapping: [ghost, secondary, secondary2, primary],
},
{
label: 'Four buttons with danger ghost',
mapping: [dangerGhost, secondary, secondary2, danger],
},
];

export const fluidButtonOptions = fluidButtonSets.map((_, i) => i);

Check warning on line 54 in packages/react/src/components/Button/__story__/fluid-button-set-args.js

View check run for this annotation

Codecov / codecov/patch

packages/react/src/components/Button/__story__/fluid-button-set-args.js#L54

Added line #L54 was not covered by tests

export const fluidButtonLabels = fluidButtonSets.reduce((acc, val, i) => {
acc[i] = val.label;
return acc;

Check warning on line 58 in packages/react/src/components/Button/__story__/fluid-button-set-args.js

View check run for this annotation

Codecov / codecov/patch

packages/react/src/components/Button/__story__/fluid-button-set-args.js#L56-L58

Added lines #L56 - L58 were not covered by tests
}, {});

export const fluidButtonMapping = fluidButtonSets.reduce((acc, val, i) => {
acc[i] = val.mapping;
return acc;

Check warning on line 63 in packages/react/src/components/Button/__story__/fluid-button-set-args.js

View check run for this annotation

Codecov / codecov/patch

packages/react/src/components/Button/__story__/fluid-button-set-args.js#L61-L63

Added lines #L61 - L63 were not covered by tests
}, {});
Loading
Loading