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

New component ButtonGroup #6202

Merged
merged 3 commits into from
Mar 22, 2024
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
Original file line number Diff line number Diff line change
@@ -1,44 +1,47 @@
import { DocSectionCode } from '@/components/doc/common/docsectioncode';
import { DocSectionText } from '@/components/doc/common/docsectiontext';
import { Button } from '@/components/lib/button/Button';
import { ButtonGroup } from '@/components/lib/buttongroup/ButtonGroup';

export function ButtonSetDoc(props) {
export function ButtonGroupDoc(props) {
const code = {
basic: `
<span className="p-buttonset">
<ButtonGroup>
<Button label="Save" icon="pi pi-check" />
<Button label="Delete" icon="pi pi-trash" />
<Button label="Cancel" icon="pi pi-times" />
</span>
</ButtonGroup>
`,
javascript: `
import React from 'react';
import { Button } from 'primereact/button';
import { ButtonGroup } from 'primereact/buttongroup';

export default function ButtonSetDemo() {
return (
<div className="card flex justify-content-center">
<span className="p-buttonset">
<ButtonGroup>
<Button label="Save" icon="pi pi-check" />
<Button label="Delete" icon="pi pi-trash" />
<Button label="Cancel" icon="pi pi-times" />
</span>
</ButtonGroup>
</div>
)
}
`,
typescript: `
import React from 'react';
import { Button } from 'primereact/button';
import { ButtonGroup } from 'primereact/buttongroup';

export default function ButtonSetDemo() {
return (
<div className="card flex justify-content-center">
<span className="p-buttonset">
<ButtonGroup>
<Button label="Save" icon="pi pi-check" />
<Button label="Delete" icon="pi pi-trash" />
<Button label="Cancel" icon="pi pi-times" />
</span>
</ButtonGroup>
</div>
)
}
Expand All @@ -49,15 +52,15 @@ export default function ButtonSetDemo() {
<>
<DocSectionText {...props}>
<p>
Multiple buttons are grouped when wrapped inside an element with <i>p-buttonset</i> class.
Multiple buttons are grouped when wrapped inside an element with <i>ButtonGroup</i> component.
</p>
</DocSectionText>
<div className="card flex justify-content-center">
<span className="p-buttonset">
<ButtonGroup>
<Button label="Save" icon="pi pi-check" />
<Button label="Delete" icon="pi pi-trash" />
<Button label="Cancel" icon="pi pi-times" />
</span>
</ButtonGroup>
</div>
<DocSectionCode code={code} />
</>
Expand Down
115 changes: 115 additions & 0 deletions components/doc/common/apidoc/index.json
Original file line number Diff line number Diff line change
Expand Up @@ -5763,6 +5763,121 @@
}
}
},
"buttongroup": {
"description": "A set of Buttons can be displayed together using the ButtonGroup component.\n\n[Live Demo](https://www.primereact.org/button/)",
"components": {
"ButtonGroup": {
"methods": {
"description": "Defines methods that can be accessed by the component's reference.",
"values": []
},
"props": {
"description": "",
"values": []
},
"callbacks": {
"description": "Defines callbacks that determine the behavior of the component based on a given condition or report the actions that the component takes.",
"values": []
}
}
},
"interfaces": {
"description": "Defines the custom interfaces used by the module.",
"values": {
"ButtonGroupPassThroughMethodOptions": {
"description": "Custom passthrough(pt) option method.",
"relatedProp": "",
"props": [
{
"name": "props",
"optional": false,
"readonly": false,
"type": "ButtonGroupProps",
"description": "Defines valid properties."
},
{
"name": "global",
"optional": false,
"readonly": false,
"type": "undefined | object",
"description": "Defines passthrough(pt) options in global config."
}
],
"callbacks": []
},
"ButtonGroupPassThroughOptions": {
"description": "Custom passthrough(pt) options.",
"relatedProp": "pt",
"props": [
{
"name": "root",
"optional": true,
"readonly": false,
"type": "ButtonGroupPassThroughOptionType",
"description": "Used to pass attributes to the root's DOM element."
},
{
"name": "hooks",
"optional": true,
"readonly": false,
"type": "ComponentHooks",
"description": "Used to manage all lifecycle hooks."
}
],
"callbacks": []
},
"ButtonGroupPassThroughAttributes": {
"description": "Custom passthrough attributes for each DOM elements",
"relatedProp": "",
"props": [
{
"name": "[key: string]",
"optional": false,
"readonly": false,
"type": "any"
}
],
"callbacks": []
},
"ButtonGroupProps": {
"description": "Defines valid properties in ButtonGroup component.",
"relatedProp": "",
"props": [
{
"name": "pt",
"optional": true,
"readonly": false,
"type": "ButtonGroupPassThroughOptions",
"description": "Used to pass attributes to DOM elements inside the component."
},
{
"name": "ptOptions",
"optional": true,
"readonly": false,
"type": "PassThroughOptions",
"description": "Used to configure passthrough(pt) options of the component."
},
{
"name": "unstyled",
"optional": true,
"readonly": false,
"type": "boolean",
"description": "When enabled, it removes component related styles in the core."
}
],
"callbacks": []
}
}
},
"types": {
"description": "Defines the custom types used by the module.",
"values": {
"ButtonGroupPassThroughOptionType": {
"values": "ButtonGroupPassThroughAttributes | Function | string | null | undefined"
}
}
}
},
"calendar": {
"description": "Calendar also known as DatePicker, is a form component to work with dates.\n\n[Live Demo](https://www.primereact.org/calendar/)",
"components": {
Expand Down
32 changes: 32 additions & 0 deletions components/lib/buttongroup/ButtonGroup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import * as React from 'react';
import { PrimeReactContext } from '../api/Api';
import { useHandleStyle } from '../componentbase/Componentbase';
import { useMergeProps } from '../hooks/Hooks';
import { classNames } from '../utils/Utils';
import { ButtonGroupBase } from './ButtonGroupBase';

export const ButtonGroup = React.memo(
React.forwardRef((inProps) => {
const mergeProps = useMergeProps();
const context = React.useContext(PrimeReactContext);
const props = ButtonGroupBase.getProps(inProps, context);
const { ptm, cx, isUnstyled } = ButtonGroupBase.setMetaData({
props
});

useHandleStyle(ButtonGroupBase.css.styles, isUnstyled, { name: 'buttongroup' });

const rootProps = mergeProps(
{
className: classNames(cx('root')),
role: 'group'
},
ButtonGroupBase.getOtherProps(props),
ptm('root')
);

return <span {...rootProps}>{props.children}</span>;
})
);

ButtonGroup.displayName = 'ButtonGroup';
15 changes: 15 additions & 0 deletions components/lib/buttongroup/ButtonGroupBase.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { ComponentBase } from '../componentbase/ComponentBase';

const classes = {
root: 'p-button-group p-component'
};

export const ButtonGroupBase = ComponentBase.extend({
defaultProps: {
__TYPE: 'ButtonGroup',
children: undefined
},
css: {
classes
}
});
86 changes: 86 additions & 0 deletions components/lib/buttongroup/buttongroup.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/**
*
* A set of Buttons can be displayed together using the ButtonGroup component.
*
* [Live Demo](https://www.primereact.org/button/)
*
* @module buttongroup
*
*/
import * as React from 'react';
import { ComponentHooks } from '../componentbase/componentbase';
import { PassThroughOptions } from '../passthrough';

export declare type ButtonGroupPassThroughOptionType = ButtonGroupPassThroughAttributes | ((options: ButtonGroupPassThroughMethodOptions) => ButtonGroupPassThroughAttributes | string) | string | null | undefined;

/**
* Custom passthrough(pt) option method.
*/
export interface ButtonGroupPassThroughMethodOptions {
/**
* Defines valid properties.
*/
props: ButtonGroupProps;
/**
* Defines passthrough(pt) options in global config.
*/
global: object | undefined;
}

/**
* Custom passthrough(pt) options.
* @see {@link ButtonGroupProps.pt}
*/
export interface ButtonGroupPassThroughOptions {
/**
* Used to pass attributes to the root's DOM element.
*/
root?: ButtonGroupPassThroughOptionType;
/**
* Used to manage all lifecycle hooks.
* @see {@link ComponentHooks}
*/
hooks?: ComponentHooks;
}

/**
* Custom passthrough attributes for each DOM elements
*/
export interface ButtonGroupPassThroughAttributes {
[key: string]: any;
}

/**
* Defines valid properties in ButtonGroup component.
*/
export interface ButtonGroupProps {
/**
* Used to pass attributes to DOM elements inside the component.
* @type {ButtonGroupPassThroughOptions}
*/
pt?: ButtonGroupPassThroughOptions;
/**
* Used to configure passthrough(pt) options of the component.
* @type {PassThroughOptions}
*/
ptOptions?: PassThroughOptions;
/**
* When enabled, it removes component related styles in the core.
* @defaultValue false
*/
unstyled?: boolean;
}

/**
* **PrimeReact - ButtonGroup**
*
* _ButtonGroup appears on top of the input field when focused._
*
* [Live Demo](https://www.primereact.org/button/)
* --- ---
* ![PrimeReact](https://primefaces.org/cdn/primereact/images/logo-100.png)
*
* @group Component
*
*/
export declare const ButtonGroup: React.ForwardRefExoticComponent<ButtonGroupProps>;
7 changes: 7 additions & 0 deletions components/lib/buttongroup/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"main": "./buttongroup.cjs.js",
"module": "./buttongroup.esm.js",
"unpkg": "./buttongroup.min.js",
"types": "./buttongroup.d.ts",
"sideEffects": false
}
12 changes: 6 additions & 6 deletions components/lib/componentbase/ComponentBase.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,29 +68,29 @@ const buttonStyles = `
order: 2;
}

.p-buttonset .p-button {
.p-button-group .p-button {
margin: 0;
}

.p-buttonset .p-button:not(:last-child) {
.p-button-group .p-button:not(:last-child) {
border-right: 0 none;
}

.p-buttonset .p-button:not(:first-of-type):not(:last-of-type) {
.p-button-group .p-button:not(:first-of-type):not(:last-of-type) {
border-radius: 0;
}

.p-buttonset .p-button:first-of-type {
.p-button-group .p-button:first-of-type {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}

.p-buttonset .p-button:last-of-type {
.p-button-group .p-button:last-of-type {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}

.p-buttonset .p-button:focus {
.p-button-group .p-button:focus {
position: relative;
z-index: 1;
}
Expand Down
2 changes: 1 addition & 1 deletion components/lib/dataview/DataViewBase.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ export const DataViewLayoutOptionsBase = ComponentBase.extend({
},
css: {
classes: {
root: 'p-dataview p-component p-dataview-layout-options p-selectbutton p-buttonset',
root: 'p-dataview p-component p-dataview-layout-options p-selectbutton p-button-group',
listButton: ({ props }) => classNames('p-button p-button-icon-only', { 'p-highlight': props.layout === 'list' }),
gridButton: ({ props }) => classNames('p-button p-button-icon-only', { 'p-highlight': props.layout === 'grid' })
}
Expand Down
2 changes: 1 addition & 1 deletion components/lib/selectbutton/SelectButtonBase.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { ComponentBase } from '../componentbase/ComponentBase';
import { classNames } from '../utils/Utils';

const classes = {
root: ({ props }) => classNames('p-selectbutton p-buttonset p-component', props.className, { 'p-invalid': props.invalid }),
root: ({ props }) => classNames('p-selectbutton p-button-group p-component', props.className, { 'p-invalid': props.invalid }),
button: ({ itemProps: props, focusedState }) =>
classNames('p-button p-component', {
'p-highlight': props.selected,
Expand Down
Loading
Loading