Skip to content

Commit

Permalink
Merge pull request #6202 from gucal/new-component-buttongroup
Browse files Browse the repository at this point in the history
New component ButtonGroup
  • Loading branch information
gucal authored Mar 22, 2024
2 parents a17dfde + 7741320 commit dda958b
Show file tree
Hide file tree
Showing 55 changed files with 3,779 additions and 4,964 deletions.
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

0 comments on commit dda958b

Please sign in to comment.