@vibe/button-group 4.0.2 → 4.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ButtonGroup/ButtonGroup.js +1 -1
- package/dist/ButtonGroup/ButtonGroup.js.map +1 -1
- package/dist/ButtonGroup/ButtonGroup.module.scss.js +1 -1
- package/dist/mocked_classnames/ButtonGroup/ButtonGroup.js +1 -1
- package/dist/mocked_classnames/ButtonGroup/ButtonGroup.js.map +1 -1
- package/dist/mocked_classnames/ButtonGroup/ButtonGroup.module.scss.js +1 -1
- package/package.json +4 -3
- package/dist/ButtonGroup/usePrevious.d.ts +0 -1
- package/dist/ButtonGroup/usePrevious.js +0 -2
- package/dist/ButtonGroup/usePrevious.js.map +0 -1
- package/dist/mocked_classnames/ButtonGroup/usePrevious.d.ts +0 -1
- package/dist/mocked_classnames/ButtonGroup/usePrevious.js +0 -2
- package/dist/mocked_classnames/ButtonGroup/usePrevious.js.map +0 -1
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import t,{forwardRef as e,useRef as o,useState as l,useCallback as i,useMemo as a,useEffect as r}from"react";import{camelCase as n}from"es-toolkit";import s from"classnames";import{useMergeRef as d,getStyle as u,getTestId as p,ComponentDefaultTestId as m,ComponentVibeId as c}from"@vibe/shared";import b
|
|
1
|
+
import t,{forwardRef as e,useRef as o,useState as l,useCallback as i,useMemo as a,useEffect as r}from"react";import{camelCase as n}from"es-toolkit";import s from"classnames";import{useMergeRef as d,getStyle as u,getTestId as p,ComponentDefaultTestId as m,ComponentVibeId as c}from"@vibe/shared";import{usePrevious as b}from"@vibe/hooks";import{ButtonWrapper as v}from"./ButtonWrapper.js";import f from"./ButtonGroup.module.scss.js";const h=e((({className:e,options:h,name:B="",disabled:y=!1,value:C="",onSelect:k,size:N="small",kind:T="secondary",groupAriaLabel:g="",tooltipPosition:x,tooltipHideDelay:O,tooltipShowDelay:U,tooltipContainerSelector:D,tooltipMoveBy:S,blurOnMouseUp:W=!0,id:E,"data-testid":G,fullWidth:M=!1},P)=>{const I=o(),j=d(P,I),[w,z]=l(C),A=b(C),F=i((t=>{y||t.disabled||(z(t.value),k&&k(t.value,B))}),[k,y,B]),H=t=>(null==t?void 0:t.value)===w,R=a((()=>h.find((t=>H(t)))),[h,w]),_=a((()=>h.map(((e,o)=>{const l=H(e),i=0===o,a=o===h.length-1,r=H(h[o+1]);return t.createElement(v,{key:e.value,size:N,onClick:()=>F(e),rightIcon:e.icon,leftIcon:e.leftIcon,active:l,rightFlat:o!==h.length-1,leftFlat:0!==o,kind:"tertiary",preventClickAnimation:!0,"aria-label":e["aria-label"],tooltipContent:e.tooltipContent,tooltipPosition:x,tooltipHideDelay:O,tooltipShowDelay:U,tooltipContainerSelector:D,tooltipMoveBy:S,blurOnMouseUp:W,fullWidth:M,className:s(f.button,f.optionText,{[f.selected]:l,[f.disabled]:y,[f.buttonDisabled]:e.disabled,[f.fullWidth]:M,[f.startBorder]:i,[f.endBorder]:a||!r}),activeButtonClassName:f.activeButton},e.text)}))),[h,w,N,x,O,U,D,S,W,y,M,F]);return r((()=>{C!==A&&C!==w&&z(C)}),[C,A,w,z]),t.createElement("div",{className:s(f.buttonGroup,e,u(f,n("kind-"+T)),{[f.disabled]:y}),id:E,"data-testid":G||p(m.BUTTON_GROUP,E),"data-vibe":c.BUTTON_GROUP,ref:j},t.createElement("div",{role:"group","aria-label":g,className:s(f.buttonsContainer,{[f.fullWidth]:M}),"aria-disabled":y},_),R&&R.subText&&t.createElement("div",{className:s(f.subTextContainer)},R.subText))}));export{h as default};
|
|
2
2
|
//# sourceMappingURL=ButtonGroup.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ButtonGroup.js","sources":["../../src/ButtonGroup/ButtonGroup.tsx"],"sourcesContent":["import React, { forwardRef, useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { camelCase } from \"es-toolkit\";\nimport cx from \"classnames\";\nimport {\n getStyle,\n useMergeRef,\n type VibeComponentProps,\n type MoveBy,\n getTestId,\n ComponentDefaultTestId,\n ComponentVibeId\n} from \"@vibe/shared\";\nimport usePrevious from \"
|
|
1
|
+
{"version":3,"file":"ButtonGroup.js","sources":["../../src/ButtonGroup/ButtonGroup.tsx"],"sourcesContent":["import React, { forwardRef, useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { camelCase } from \"es-toolkit\";\nimport cx from \"classnames\";\nimport {\n getStyle,\n useMergeRef,\n type VibeComponentProps,\n type MoveBy,\n getTestId,\n ComponentDefaultTestId,\n ComponentVibeId\n} from \"@vibe/shared\";\nimport { usePrevious } from \"@vibe/hooks\";\n\nimport { type SubIcon } from \"@vibe/icon\";\nimport { type ButtonValue } from \"./ButtonGroupConstants\";\nimport { ButtonWrapper } from \"./ButtonWrapper\";\nimport { type ButtonType, type ButtonSize } from \"@vibe/button\";\nimport styles from \"./ButtonGroup.module.scss\";\nimport { type TooltipPositions } from \"@vibe/tooltip\";\n\ntype ButtonGroupOption = {\n icon?: SubIcon;\n leftIcon?: SubIcon;\n \"aria-label\"?: string;\n subText?: string;\n value: ButtonValue;\n text: string;\n disabled?: boolean;\n tooltipContent?: string;\n};\n\nexport interface ButtonGroupProps extends VibeComponentProps {\n /**\n * The list of button options.\n */\n options: Array<ButtonGroupOption>;\n /**\n * The currently selected button value.\n */\n value?: ButtonValue;\n /**\n * Callback fired when a button is selected.\n */\n onSelect?: (value: ButtonValue, name: string) => void;\n /**\n * The size of the buttons.\n */\n size?: ButtonSize;\n /**\n * The style variant of the buttons.\n */\n kind?: Extract<ButtonType, \"secondary\" | \"tertiary\">;\n /**\n * The name of the button group.\n */\n name?: string;\n /**\n * If true, disables all buttons in the group.\n */\n disabled?: boolean;\n /**\n * The label of the button group for accessibility.\n */\n groupAriaLabel?: string;\n /**\n * The position of the tooltip relative to the button.\n */\n tooltipPosition?: TooltipPositions;\n /**\n * The delay in milliseconds before the tooltip hides.\n */\n tooltipHideDelay?: number;\n /**\n * The delay in milliseconds before the tooltip shows.\n */\n tooltipShowDelay?: number;\n /**\n * CSS selector for the tooltip container.\n */\n tooltipContainerSelector?: string;\n /**\n * Adjusts the tooltip position.\n */\n tooltipMoveBy?: MoveBy;\n /**\n * The content inside the button group.\n */\n children?: React.ReactNode;\n /**\n * If true, makes the button group take the full width of its container.\n */\n fullWidth?: boolean;\n /**\n * If true, removes focus from the button after clicking.\n */\n blurOnMouseUp?: boolean;\n}\n\nconst ButtonGroup = forwardRef(\n (\n {\n className,\n options,\n name = \"\",\n disabled = false,\n value = \"\",\n onSelect,\n size = \"small\",\n kind = \"secondary\",\n groupAriaLabel = \"\",\n tooltipPosition,\n tooltipHideDelay,\n tooltipShowDelay,\n tooltipContainerSelector,\n tooltipMoveBy,\n blurOnMouseUp = true,\n id,\n \"data-testid\": dataTestId,\n fullWidth = false\n }: ButtonGroupProps,\n ref: React.ForwardedRef<HTMLDivElement>\n ) => {\n const inputRef = useRef();\n const mergedRef = useMergeRef(ref, inputRef);\n\n const [valueState, setValueState] = useState(value);\n const prevValue = usePrevious(value);\n\n const onClick = useCallback(\n (option: ButtonGroupOption) => {\n const isDisabled = disabled || option.disabled;\n if (!isDisabled) {\n setValueState(option.value);\n if (onSelect) {\n onSelect(option.value, name);\n }\n }\n },\n [onSelect, disabled, name]\n );\n\n const isOptionActive = (option?: ButtonGroupOption) => option?.value === valueState;\n\n const selectedOption = useMemo(() => {\n return options.find(option => isOptionActive(option));\n }, [options, valueState]);\n\n const Buttons = useMemo(() => {\n return options.map((option, index) => {\n const isSelected = isOptionActive(option);\n const isFirst = index === 0;\n const isLast = index === options.length - 1;\n const isNextOptionActive = isOptionActive(options[index + 1]);\n\n return (\n <ButtonWrapper\n key={option.value}\n size={size}\n onClick={() => onClick(option)}\n rightIcon={option.icon}\n leftIcon={option.leftIcon}\n active={isSelected}\n rightFlat={index !== options.length - 1}\n leftFlat={index !== 0}\n kind=\"tertiary\"\n preventClickAnimation\n aria-label={option[\"aria-label\"]}\n tooltipContent={option.tooltipContent}\n tooltipPosition={tooltipPosition}\n tooltipHideDelay={tooltipHideDelay}\n tooltipShowDelay={tooltipShowDelay}\n tooltipContainerSelector={tooltipContainerSelector}\n tooltipMoveBy={tooltipMoveBy}\n blurOnMouseUp={blurOnMouseUp}\n fullWidth={fullWidth}\n className={cx(styles.button, styles.optionText, {\n [styles.selected]: isSelected,\n [styles.disabled]: disabled,\n [styles.buttonDisabled]: option.disabled,\n [styles.fullWidth]: fullWidth,\n [styles.startBorder]: isFirst,\n [styles.endBorder]: isLast || !isNextOptionActive\n })}\n activeButtonClassName={styles.activeButton}\n >\n {option.text}\n </ButtonWrapper>\n );\n });\n }, [\n options,\n valueState,\n size,\n tooltipPosition,\n tooltipHideDelay,\n tooltipShowDelay,\n tooltipContainerSelector,\n tooltipMoveBy,\n blurOnMouseUp,\n disabled,\n fullWidth,\n onClick\n ]);\n\n // Effects\n useEffect(() => {\n // Update value if changed from props\n if (value !== prevValue && value !== valueState) {\n setValueState(value);\n }\n }, [value, prevValue, valueState, setValueState]);\n\n return (\n <div\n className={cx(styles.buttonGroup, className, getStyle(styles, camelCase(\"kind-\" + kind)), {\n [styles.disabled]: disabled\n })}\n id={id}\n data-testid={dataTestId || getTestId(ComponentDefaultTestId.BUTTON_GROUP, id)}\n data-vibe={ComponentVibeId.BUTTON_GROUP}\n ref={mergedRef}\n >\n <div\n role=\"group\"\n aria-label={groupAriaLabel}\n className={cx(styles.buttonsContainer, { [styles.fullWidth]: fullWidth })}\n aria-disabled={disabled}\n >\n {Buttons}\n </div>\n {selectedOption && selectedOption.subText && (\n <div className={cx(styles.subTextContainer)}>{selectedOption.subText}</div>\n )}\n </div>\n );\n }\n);\n\nexport default ButtonGroup;\n"],"names":["ButtonGroup","forwardRef","className","options","name","disabled","value","onSelect","size","kind","groupAriaLabel","tooltipPosition","tooltipHideDelay","tooltipShowDelay","tooltipContainerSelector","tooltipMoveBy","blurOnMouseUp","id","dataTestId","fullWidth","ref","inputRef","useRef","mergedRef","useMergeRef","valueState","setValueState","useState","prevValue","usePrevious","onClick","useCallback","option","isOptionActive","selectedOption","useMemo","find","Buttons","map","index","isSelected","isFirst","isLast","length","isNextOptionActive","React","createElement","ButtonWrapper","key","rightIcon","icon","leftIcon","active","rightFlat","leftFlat","preventClickAnimation","tooltipContent","cx","styles","button","optionText","selected","buttonDisabled","startBorder","endBorder","activeButtonClassName","activeButton","text","useEffect","buttonGroup","getStyle","camelCase","getTestId","ComponentDefaultTestId","BUTTON_GROUP","ComponentVibeId","role","buttonsContainer","subText","subTextContainer"],"mappings":"gbAmGA,MAAMA,EAAcC,GAClB,EAEIC,YACAC,UACAC,OAAO,GACPC,YAAW,EACXC,QAAQ,GACRC,WACAC,OAAO,QACPC,OAAO,YACPC,iBAAiB,GACjBC,kBACAC,mBACAC,mBACAC,2BACAC,gBACAC,iBAAgB,EAChBC,KACA,cAAeC,EACfC,aAAY,GAEdC,KAEA,MAAMC,EAAWC,IACXC,EAAYC,EAAYJ,EAAKC,IAE5BI,EAAYC,GAAiBC,EAASrB,GACvCsB,EAAYC,EAAYvB,GAExBwB,EAAUC,GACbC,IACoB3B,GAAY2B,EAAO3B,WAEpCqB,EAAcM,EAAO1B,OACjBC,GACFA,EAASyB,EAAO1B,MAAOF,GAE3B,GAEF,CAACG,EAAUF,EAAUD,IAGjB6B,EAAkBD,IAA+BA,aAAA,EAAAA,EAAQ1B,SAAUmB,EAEnES,EAAiBC,GAAQ,IACtBhC,EAAQiC,MAAKJ,GAAUC,EAAeD,MAC5C,CAAC7B,EAASsB,IAEPY,EAAUF,GAAQ,IACfhC,EAAQmC,KAAI,CAACN,EAAQO,KAC1B,MAAMC,EAAaP,EAAeD,GAC5BS,EAAoB,IAAVF,EACVG,EAASH,IAAUpC,EAAQwC,OAAS,EACpCC,EAAqBX,EAAe9B,EAAQoC,EAAQ,IAE1D,OACEM,EAACC,cAAAC,EACC,CAAAC,IAAKhB,EAAO1B,MACZE,KAAMA,EACNsB,QAASA,IAAMA,EAAQE,GACvBiB,UAAWjB,EAAOkB,KAClBC,SAAUnB,EAAOmB,SACjBC,OAAQZ,EACRa,UAAWd,IAAUpC,EAAQwC,OAAS,EACtCW,SAAoB,IAAVf,EACV9B,KAAK,WACL8C,uBACY,EAAA,aAAAvB,EAAO,cACnBwB,eAAgBxB,EAAOwB,eACvB7C,gBAAiBA,EACjBC,iBAAkBA,EAClBC,iBAAkBA,EAClBC,yBAA0BA,EAC1BC,cAAeA,EACfC,cAAeA,EACfG,UAAWA,EACXjB,UAAWuD,EAAGC,EAAOC,OAAQD,EAAOE,WAAY,CAC9C,CAACF,EAAOG,UAAWrB,EACnB,CAACkB,EAAOrD,UAAWA,EACnB,CAACqD,EAAOI,gBAAiB9B,EAAO3B,SAChC,CAACqD,EAAOvC,WAAYA,EACpB,CAACuC,EAAOK,aAActB,EACtB,CAACiB,EAAOM,WAAYtB,IAAWE,IAEjCqB,sBAAuBP,EAAOQ,cAE7BlC,EAAOmC,KACM,KAGnB,CACDhE,EACAsB,EACAjB,EACAG,EACAC,EACAC,EACAC,EACAC,EACAC,EACAX,EACAc,EACAW,IAWF,OAPAsC,GAAU,KAEJ9D,IAAUsB,GAAatB,IAAUmB,GACnCC,EAAcpB,EAChB,GACC,CAACA,EAAOsB,EAAWH,EAAYC,IAGhCmB,uBACE3C,UAAWuD,EAAGC,EAAOW,YAAanE,EAAWoE,EAASZ,EAAQa,EAAU,QAAU9D,IAAQ,CACxF,CAACiD,EAAOrD,UAAWA,IAErBY,GAAIA,gBACSC,GAAcsD,EAAUC,EAAuBC,aAAczD,GAC/D,YAAA0D,EAAgBD,aAC3BtD,IAAKG,GAELsB,EAAAC,cAAA,MAAA,CACE8B,KAAK,QAAO,aACAlE,EACZR,UAAWuD,EAAGC,EAAOmB,iBAAkB,CAAE,CAACnB,EAAOvC,WAAYA,IAC9C,gBAAAd,GAEdgC,GAEFH,GAAkBA,EAAe4C,SAChCjC,EAAAC,cAAA,MAAA,CAAK5C,UAAWuD,EAAGC,EAAOqB,mBAAoB7C,EAAe4C,SAE3D"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var n={buttonGroup:"
|
|
1
|
+
var n={buttonGroup:"buttonGroup_79c4f09e3d",subTextContainer:"subTextContainer_9cb7a962f0",buttonsContainer:"buttonsContainer_26caf62c0b",fullWidth:"fullWidth_8be749460a",button:"button_102adba12a",activeButton:"activeButton_00c796686a",disabled:"disabled_3cc9500f41",buttonDisabled:"buttonDisabled_c222f2e363",startBorder:"startBorder_fe7bdeb577",endBorder:"endBorder_f8602fa406",kindTertiary:"kindTertiary_d934ec8be7",optionText:"optionText_82d70b2805",selected:"selected_b5142521a2",wrapper:"wrapper_1be7660fad"};!function(n){const t="s_id-3abf5c8d9776_4_0_2";if("undefined"!=typeof document){const e=document.head||document.getElementsByTagName("head")[0];if(e.querySelector("#"+t))return;const o=document.createElement("style");o.id=t,e.firstChild?e.insertBefore(o,e.firstChild):e.appendChild(o),o.appendChild(document.createTextNode(n))}else globalThis.injectedStyles&&(globalThis.injectedStyles[t]=n)}("/* stylelint-disable */\n/* stylelint-enable */\n.buttonGroup_79c4f09e3d {\n display: flex;\n flex-direction: column;\n}\n.subTextContainer_9cb7a962f0 {\n font: var(--font-text2-normal);\n -webkit-font-smoothing: var(--font-smoothing-webkit);\n -moz-osx-font-smoothing: var(--font-smoothing-moz);\n}\n.buttonsContainer_26caf62c0b {\n display: flex;\n align-items: center;\n justify-content: center;\n}\n.buttonsContainer_26caf62c0b.fullWidth_8be749460a {\n justify-content: flex-start;\n width: 100%;\n}\n.buttonsContainer_26caf62c0b .button_102adba12a {\n border-style: solid;\n border-width: 1px 0;\n background-color: var(--primary-background-color);\n border-color: var(--ui-border-color);\n}\n.buttonsContainer_26caf62c0b .button_102adba12a.activeButton_00c796686a {\n background-color: var(--primary-selected-color);\n border-color: var(--primary-color);\n border-inline-start-width: 1px;\n border-inline-end-width: 1px;\n}\n.buttonsContainer_26caf62c0b .button_102adba12a.activeButton_00c796686a:hover {\n background-color: var(--primary-selected-color);\n}\n.buttonsContainer_26caf62c0b .button_102adba12a.disabled_3cc9500f41, .buttonsContainer_26caf62c0b .button_102adba12a.buttonDisabled_c222f2e363 {\n background-color: var(--disabled-background-color);\n opacity: 0.5;\n cursor: not-allowed;\n}\n.buttonsContainer_26caf62c0b .button_102adba12a.startBorder_fe7bdeb577 {\n border-inline-start-width: 1px;\n}\n.buttonsContainer_26caf62c0b .button_102adba12a.endBorder_f8602fa406 {\n border-inline-end-width: 1px;\n}\n.buttonsContainer_26caf62c0b .button_102adba12a.fullWidth_8be749460a {\n width: 100%;\n display: flex;\n}\n.kindTertiary_d934ec8be7 .buttonsContainer_26caf62c0b .button_102adba12a {\n border-color: transparent;\n}\n.kindTertiary_d934ec8be7 .buttonsContainer_26caf62c0b .button_102adba12a:first-child {\n border-color: transparent;\n}\n.optionText_82d70b2805:not(.disabled_3cc9500f41) {\n color: var(--primary-text-color);\n}\n.optionText_82d70b2805:not(.disabled_3cc9500f41).selected_b5142521a2 {\n color: var(--primary-text-color);\n}\n.wrapper_1be7660fad.disabled_3cc9500f41 {\n cursor: not-allowed;\n}\n.fullWidth_8be749460a {\n flex: 1;\n}");export{n as default};
|
|
2
2
|
//# sourceMappingURL=ButtonGroup.module.scss.js.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import t,{forwardRef as e,useRef as o,useState as l,useCallback as i,useMemo as a,useEffect as r}from"react";import{camelCase as n}from"es-toolkit";import s from"classnames";import{useMergeRef as d,getStyle as u,getTestId as p,ComponentDefaultTestId as m,ComponentVibeId as c}from"@vibe/shared";import b
|
|
1
|
+
import t,{forwardRef as e,useRef as o,useState as l,useCallback as i,useMemo as a,useEffect as r}from"react";import{camelCase as n}from"es-toolkit";import s from"classnames";import{useMergeRef as d,getStyle as u,getTestId as p,ComponentDefaultTestId as m,ComponentVibeId as c}from"@vibe/shared";import{usePrevious as b}from"@vibe/hooks";import{ButtonWrapper as v}from"./ButtonWrapper.js";import f from"./ButtonGroup.module.scss.js";const h=e((({className:e,options:h,name:B="",disabled:y=!1,value:C="",onSelect:k,size:N="small",kind:T="secondary",groupAriaLabel:g="",tooltipPosition:x,tooltipHideDelay:O,tooltipShowDelay:U,tooltipContainerSelector:D,tooltipMoveBy:S,blurOnMouseUp:W=!0,id:E,"data-testid":G,fullWidth:M=!1},P)=>{const I=o(),j=d(P,I),[w,z]=l(C),A=b(C),F=i((t=>{y||t.disabled||(z(t.value),k&&k(t.value,B))}),[k,y,B]),H=t=>(null==t?void 0:t.value)===w,R=a((()=>h.find((t=>H(t)))),[h,w]),_=a((()=>h.map(((e,o)=>{const l=H(e),i=0===o,a=o===h.length-1,r=H(h[o+1]);return t.createElement(v,{key:e.value,size:N,onClick:()=>F(e),rightIcon:e.icon,leftIcon:e.leftIcon,active:l,rightFlat:o!==h.length-1,leftFlat:0!==o,kind:"tertiary",preventClickAnimation:!0,"aria-label":e["aria-label"],tooltipContent:e.tooltipContent,tooltipPosition:x,tooltipHideDelay:O,tooltipShowDelay:U,tooltipContainerSelector:D,tooltipMoveBy:S,blurOnMouseUp:W,fullWidth:M,className:s(f.button,f.optionText,{[f.selected]:l,[f.disabled]:y,[f.buttonDisabled]:e.disabled,[f.fullWidth]:M,[f.startBorder]:i,[f.endBorder]:a||!r}),activeButtonClassName:f.activeButton},e.text)}))),[h,w,N,x,O,U,D,S,W,y,M,F]);return r((()=>{C!==A&&C!==w&&z(C)}),[C,A,w,z]),t.createElement("div",{className:s(f.buttonGroup,e,u(f,n("kind-"+T)),{[f.disabled]:y}),id:E,"data-testid":G||p(m.BUTTON_GROUP,E),"data-vibe":c.BUTTON_GROUP,ref:j},t.createElement("div",{role:"group","aria-label":g,className:s(f.buttonsContainer,{[f.fullWidth]:M}),"aria-disabled":y},_),R&&R.subText&&t.createElement("div",{className:s(f.subTextContainer)},R.subText))}));export{h as default};
|
|
2
2
|
//# sourceMappingURL=ButtonGroup.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ButtonGroup.js","sources":["../../../src/ButtonGroup/ButtonGroup.tsx"],"sourcesContent":["import React, { forwardRef, useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { camelCase } from \"es-toolkit\";\nimport cx from \"classnames\";\nimport {\n getStyle,\n useMergeRef,\n type VibeComponentProps,\n type MoveBy,\n getTestId,\n ComponentDefaultTestId,\n ComponentVibeId\n} from \"@vibe/shared\";\nimport usePrevious from \"
|
|
1
|
+
{"version":3,"file":"ButtonGroup.js","sources":["../../../src/ButtonGroup/ButtonGroup.tsx"],"sourcesContent":["import React, { forwardRef, useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { camelCase } from \"es-toolkit\";\nimport cx from \"classnames\";\nimport {\n getStyle,\n useMergeRef,\n type VibeComponentProps,\n type MoveBy,\n getTestId,\n ComponentDefaultTestId,\n ComponentVibeId\n} from \"@vibe/shared\";\nimport { usePrevious } from \"@vibe/hooks\";\n\nimport { type SubIcon } from \"@vibe/icon\";\nimport { type ButtonValue } from \"./ButtonGroupConstants\";\nimport { ButtonWrapper } from \"./ButtonWrapper\";\nimport { type ButtonType, type ButtonSize } from \"@vibe/button\";\nimport styles from \"./ButtonGroup.module.scss\";\nimport { type TooltipPositions } from \"@vibe/tooltip\";\n\ntype ButtonGroupOption = {\n icon?: SubIcon;\n leftIcon?: SubIcon;\n \"aria-label\"?: string;\n subText?: string;\n value: ButtonValue;\n text: string;\n disabled?: boolean;\n tooltipContent?: string;\n};\n\nexport interface ButtonGroupProps extends VibeComponentProps {\n /**\n * The list of button options.\n */\n options: Array<ButtonGroupOption>;\n /**\n * The currently selected button value.\n */\n value?: ButtonValue;\n /**\n * Callback fired when a button is selected.\n */\n onSelect?: (value: ButtonValue, name: string) => void;\n /**\n * The size of the buttons.\n */\n size?: ButtonSize;\n /**\n * The style variant of the buttons.\n */\n kind?: Extract<ButtonType, \"secondary\" | \"tertiary\">;\n /**\n * The name of the button group.\n */\n name?: string;\n /**\n * If true, disables all buttons in the group.\n */\n disabled?: boolean;\n /**\n * The label of the button group for accessibility.\n */\n groupAriaLabel?: string;\n /**\n * The position of the tooltip relative to the button.\n */\n tooltipPosition?: TooltipPositions;\n /**\n * The delay in milliseconds before the tooltip hides.\n */\n tooltipHideDelay?: number;\n /**\n * The delay in milliseconds before the tooltip shows.\n */\n tooltipShowDelay?: number;\n /**\n * CSS selector for the tooltip container.\n */\n tooltipContainerSelector?: string;\n /**\n * Adjusts the tooltip position.\n */\n tooltipMoveBy?: MoveBy;\n /**\n * The content inside the button group.\n */\n children?: React.ReactNode;\n /**\n * If true, makes the button group take the full width of its container.\n */\n fullWidth?: boolean;\n /**\n * If true, removes focus from the button after clicking.\n */\n blurOnMouseUp?: boolean;\n}\n\nconst ButtonGroup = forwardRef(\n (\n {\n className,\n options,\n name = \"\",\n disabled = false,\n value = \"\",\n onSelect,\n size = \"small\",\n kind = \"secondary\",\n groupAriaLabel = \"\",\n tooltipPosition,\n tooltipHideDelay,\n tooltipShowDelay,\n tooltipContainerSelector,\n tooltipMoveBy,\n blurOnMouseUp = true,\n id,\n \"data-testid\": dataTestId,\n fullWidth = false\n }: ButtonGroupProps,\n ref: React.ForwardedRef<HTMLDivElement>\n ) => {\n const inputRef = useRef();\n const mergedRef = useMergeRef(ref, inputRef);\n\n const [valueState, setValueState] = useState(value);\n const prevValue = usePrevious(value);\n\n const onClick = useCallback(\n (option: ButtonGroupOption) => {\n const isDisabled = disabled || option.disabled;\n if (!isDisabled) {\n setValueState(option.value);\n if (onSelect) {\n onSelect(option.value, name);\n }\n }\n },\n [onSelect, disabled, name]\n );\n\n const isOptionActive = (option?: ButtonGroupOption) => option?.value === valueState;\n\n const selectedOption = useMemo(() => {\n return options.find(option => isOptionActive(option));\n }, [options, valueState]);\n\n const Buttons = useMemo(() => {\n return options.map((option, index) => {\n const isSelected = isOptionActive(option);\n const isFirst = index === 0;\n const isLast = index === options.length - 1;\n const isNextOptionActive = isOptionActive(options[index + 1]);\n\n return (\n <ButtonWrapper\n key={option.value}\n size={size}\n onClick={() => onClick(option)}\n rightIcon={option.icon}\n leftIcon={option.leftIcon}\n active={isSelected}\n rightFlat={index !== options.length - 1}\n leftFlat={index !== 0}\n kind=\"tertiary\"\n preventClickAnimation\n aria-label={option[\"aria-label\"]}\n tooltipContent={option.tooltipContent}\n tooltipPosition={tooltipPosition}\n tooltipHideDelay={tooltipHideDelay}\n tooltipShowDelay={tooltipShowDelay}\n tooltipContainerSelector={tooltipContainerSelector}\n tooltipMoveBy={tooltipMoveBy}\n blurOnMouseUp={blurOnMouseUp}\n fullWidth={fullWidth}\n className={cx(styles.button, styles.optionText, {\n [styles.selected]: isSelected,\n [styles.disabled]: disabled,\n [styles.buttonDisabled]: option.disabled,\n [styles.fullWidth]: fullWidth,\n [styles.startBorder]: isFirst,\n [styles.endBorder]: isLast || !isNextOptionActive\n })}\n activeButtonClassName={styles.activeButton}\n >\n {option.text}\n </ButtonWrapper>\n );\n });\n }, [\n options,\n valueState,\n size,\n tooltipPosition,\n tooltipHideDelay,\n tooltipShowDelay,\n tooltipContainerSelector,\n tooltipMoveBy,\n blurOnMouseUp,\n disabled,\n fullWidth,\n onClick\n ]);\n\n // Effects\n useEffect(() => {\n // Update value if changed from props\n if (value !== prevValue && value !== valueState) {\n setValueState(value);\n }\n }, [value, prevValue, valueState, setValueState]);\n\n return (\n <div\n className={cx(styles.buttonGroup, className, getStyle(styles, camelCase(\"kind-\" + kind)), {\n [styles.disabled]: disabled\n })}\n id={id}\n data-testid={dataTestId || getTestId(ComponentDefaultTestId.BUTTON_GROUP, id)}\n data-vibe={ComponentVibeId.BUTTON_GROUP}\n ref={mergedRef}\n >\n <div\n role=\"group\"\n aria-label={groupAriaLabel}\n className={cx(styles.buttonsContainer, { [styles.fullWidth]: fullWidth })}\n aria-disabled={disabled}\n >\n {Buttons}\n </div>\n {selectedOption && selectedOption.subText && (\n <div className={cx(styles.subTextContainer)}>{selectedOption.subText}</div>\n )}\n </div>\n );\n }\n);\n\nexport default ButtonGroup;\n"],"names":["ButtonGroup","forwardRef","className","options","name","disabled","value","onSelect","size","kind","groupAriaLabel","tooltipPosition","tooltipHideDelay","tooltipShowDelay","tooltipContainerSelector","tooltipMoveBy","blurOnMouseUp","id","dataTestId","fullWidth","ref","inputRef","useRef","mergedRef","useMergeRef","valueState","setValueState","useState","prevValue","usePrevious","onClick","useCallback","option","isOptionActive","selectedOption","useMemo","find","Buttons","map","index","isSelected","isFirst","isLast","length","isNextOptionActive","React","createElement","ButtonWrapper","key","rightIcon","icon","leftIcon","active","rightFlat","leftFlat","preventClickAnimation","tooltipContent","cx","styles","button","optionText","selected","buttonDisabled","startBorder","endBorder","activeButtonClassName","activeButton","text","useEffect","buttonGroup","getStyle","camelCase","getTestId","ComponentDefaultTestId","BUTTON_GROUP","ComponentVibeId","role","buttonsContainer","subText","subTextContainer"],"mappings":"gbAmGA,MAAMA,EAAcC,GAClB,EAEIC,YACAC,UACAC,OAAO,GACPC,YAAW,EACXC,QAAQ,GACRC,WACAC,OAAO,QACPC,OAAO,YACPC,iBAAiB,GACjBC,kBACAC,mBACAC,mBACAC,2BACAC,gBACAC,iBAAgB,EAChBC,KACA,cAAeC,EACfC,aAAY,GAEdC,KAEA,MAAMC,EAAWC,IACXC,EAAYC,EAAYJ,EAAKC,IAE5BI,EAAYC,GAAiBC,EAASrB,GACvCsB,EAAYC,EAAYvB,GAExBwB,EAAUC,GACbC,IACoB3B,GAAY2B,EAAO3B,WAEpCqB,EAAcM,EAAO1B,OACjBC,GACFA,EAASyB,EAAO1B,MAAOF,GAE3B,GAEF,CAACG,EAAUF,EAAUD,IAGjB6B,EAAkBD,IAA+BA,aAAA,EAAAA,EAAQ1B,SAAUmB,EAEnES,EAAiBC,GAAQ,IACtBhC,EAAQiC,MAAKJ,GAAUC,EAAeD,MAC5C,CAAC7B,EAASsB,IAEPY,EAAUF,GAAQ,IACfhC,EAAQmC,KAAI,CAACN,EAAQO,KAC1B,MAAMC,EAAaP,EAAeD,GAC5BS,EAAoB,IAAVF,EACVG,EAASH,IAAUpC,EAAQwC,OAAS,EACpCC,EAAqBX,EAAe9B,EAAQoC,EAAQ,IAE1D,OACEM,EAACC,cAAAC,EACC,CAAAC,IAAKhB,EAAO1B,MACZE,KAAMA,EACNsB,QAASA,IAAMA,EAAQE,GACvBiB,UAAWjB,EAAOkB,KAClBC,SAAUnB,EAAOmB,SACjBC,OAAQZ,EACRa,UAAWd,IAAUpC,EAAQwC,OAAS,EACtCW,SAAoB,IAAVf,EACV9B,KAAK,WACL8C,uBACY,EAAA,aAAAvB,EAAO,cACnBwB,eAAgBxB,EAAOwB,eACvB7C,gBAAiBA,EACjBC,iBAAkBA,EAClBC,iBAAkBA,EAClBC,yBAA0BA,EAC1BC,cAAeA,EACfC,cAAeA,EACfG,UAAWA,EACXjB,UAAWuD,EAAGC,EAAOC,OAAQD,EAAOE,WAAY,CAC9C,CAACF,EAAOG,UAAWrB,EACnB,CAACkB,EAAOrD,UAAWA,EACnB,CAACqD,EAAOI,gBAAiB9B,EAAO3B,SAChC,CAACqD,EAAOvC,WAAYA,EACpB,CAACuC,EAAOK,aAActB,EACtB,CAACiB,EAAOM,WAAYtB,IAAWE,IAEjCqB,sBAAuBP,EAAOQ,cAE7BlC,EAAOmC,KACM,KAGnB,CACDhE,EACAsB,EACAjB,EACAG,EACAC,EACAC,EACAC,EACAC,EACAC,EACAX,EACAc,EACAW,IAWF,OAPAsC,GAAU,KAEJ9D,IAAUsB,GAAatB,IAAUmB,GACnCC,EAAcpB,EAChB,GACC,CAACA,EAAOsB,EAAWH,EAAYC,IAGhCmB,uBACE3C,UAAWuD,EAAGC,EAAOW,YAAanE,EAAWoE,EAASZ,EAAQa,EAAU,QAAU9D,IAAQ,CACxF,CAACiD,EAAOrD,UAAWA,IAErBY,GAAIA,gBACSC,GAAcsD,EAAUC,EAAuBC,aAAczD,GAC/D,YAAA0D,EAAgBD,aAC3BtD,IAAKG,GAELsB,EAAAC,cAAA,MAAA,CACE8B,KAAK,QAAO,aACAlE,EACZR,UAAWuD,EAAGC,EAAOmB,iBAAkB,CAAE,CAACnB,EAAOvC,WAAYA,IAC9C,gBAAAd,GAEdgC,GAEFH,GAAkBA,EAAe4C,SAChCjC,EAAAC,cAAA,MAAA,CAAK5C,UAAWuD,EAAGC,EAAOqB,mBAAoB7C,EAAe4C,SAE3D"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var n={buttonGroup:"buttonGroup",subTextContainer:"subTextContainer",buttonsContainer:"buttonsContainer",fullWidth:"fullWidth",button:"button",activeButton:"activeButton",disabled:"disabled",buttonDisabled:"buttonDisabled",startBorder:"startBorder",endBorder:"endBorder",kindTertiary:"kindTertiary",optionText:"optionText",selected:"selected",wrapper:"wrapper"};!function(n){const t="s_id-
|
|
1
|
+
var n={buttonGroup:"buttonGroup",subTextContainer:"subTextContainer",buttonsContainer:"buttonsContainer",fullWidth:"fullWidth",button:"button",activeButton:"activeButton",disabled:"disabled",buttonDisabled:"buttonDisabled",startBorder:"startBorder",endBorder:"endBorder",kindTertiary:"kindTertiary",optionText:"optionText",selected:"selected",wrapper:"wrapper"};!function(n){const t="s_id-3abf5c8d9776_4_0_2";if("undefined"!=typeof document){const o=document.head||document.getElementsByTagName("head")[0];if(o.querySelector("#"+t))return;const e=document.createElement("style");e.id=t,o.firstChild?o.insertBefore(e,o.firstChild):o.appendChild(e),e.appendChild(document.createTextNode(n))}else globalThis.injectedStyles&&(globalThis.injectedStyles[t]=n)}("/* stylelint-disable */\n/* stylelint-enable */\n.buttonGroup {\n display: flex;\n flex-direction: column;\n}\n.subTextContainer {\n font: var(--font-text2-normal);\n -webkit-font-smoothing: var(--font-smoothing-webkit);\n -moz-osx-font-smoothing: var(--font-smoothing-moz);\n}\n.buttonsContainer {\n display: flex;\n align-items: center;\n justify-content: center;\n}\n.buttonsContainer.fullWidth {\n justify-content: flex-start;\n width: 100%;\n}\n.buttonsContainer .button {\n border-style: solid;\n border-width: 1px 0;\n background-color: var(--primary-background-color);\n border-color: var(--ui-border-color);\n}\n.buttonsContainer .button.activeButton {\n background-color: var(--primary-selected-color);\n border-color: var(--primary-color);\n border-inline-start-width: 1px;\n border-inline-end-width: 1px;\n}\n.buttonsContainer .button.activeButton:hover {\n background-color: var(--primary-selected-color);\n}\n.buttonsContainer .button.disabled, .buttonsContainer .button.buttonDisabled {\n background-color: var(--disabled-background-color);\n opacity: 0.5;\n cursor: not-allowed;\n}\n.buttonsContainer .button.startBorder {\n border-inline-start-width: 1px;\n}\n.buttonsContainer .button.endBorder {\n border-inline-end-width: 1px;\n}\n.buttonsContainer .button.fullWidth {\n width: 100%;\n display: flex;\n}\n.kindTertiary .buttonsContainer .button {\n border-color: transparent;\n}\n.kindTertiary .buttonsContainer .button:first-child {\n border-color: transparent;\n}\n.optionText:not(.disabled) {\n color: var(--primary-text-color);\n}\n.optionText:not(.disabled).selected {\n color: var(--primary-text-color);\n}\n.wrapper.disabled {\n cursor: not-allowed;\n}\n.fullWidth {\n flex: 1;\n}");export{n as default};
|
|
2
2
|
//# sourceMappingURL=ButtonGroup.module.scss.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vibe/button-group",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.3",
|
|
4
4
|
"description": "Vibe sub-package for ButtonGroup component",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -39,10 +39,11 @@
|
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
41
|
"@vibe/button": "4.0.5",
|
|
42
|
+
"@vibe/hooks": "4.0.5",
|
|
42
43
|
"@vibe/icon": "4.0.3",
|
|
43
44
|
"@vibe/shared": "4.0.3",
|
|
44
45
|
"@vibe/style": "4.1.0",
|
|
45
|
-
"@vibe/tooltip": "4.0.
|
|
46
|
+
"@vibe/tooltip": "4.0.9",
|
|
46
47
|
"classnames": "^2.5.1",
|
|
47
48
|
"es-toolkit": "^1.39.10"
|
|
48
49
|
},
|
|
@@ -71,5 +72,5 @@
|
|
|
71
72
|
"../../../node_modules/@vibe/config/.eslintrc.cjs"
|
|
72
73
|
]
|
|
73
74
|
},
|
|
74
|
-
"gitHead": "
|
|
75
|
+
"gitHead": "04e1b7343b56512083db864459fcdbc301fdc99c"
|
|
75
76
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export default function usePrevious<Type>(value: Type): Type;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"usePrevious.js","sources":["../../src/ButtonGroup/usePrevious.ts"],"sourcesContent":["import { useRef } from \"react\";\nimport { useIsomorphicLayoutEffect } from \"@vibe/shared\";\n\nexport default function usePrevious<Type>(value: Type): Type {\n const ref = useRef(undefined);\n useIsomorphicLayoutEffect(() => {\n ref.current = value;\n });\n return ref.current;\n}\n"],"names":["usePrevious","value","ref","useRef","undefined","useIsomorphicLayoutEffect","current"],"mappings":"wFAGwB,SAAAA,EAAkBC,GACxC,MAAMC,EAAMC,OAAOC,GAInB,OAHAC,GAA0B,KACxBH,EAAII,QAAUL,CAAK,IAEdC,EAAII,OACb"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export default function usePrevious<Type>(value: Type): Type;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"usePrevious.js","sources":["../../../src/ButtonGroup/usePrevious.ts"],"sourcesContent":["import { useRef } from \"react\";\nimport { useIsomorphicLayoutEffect } from \"@vibe/shared\";\n\nexport default function usePrevious<Type>(value: Type): Type {\n const ref = useRef(undefined);\n useIsomorphicLayoutEffect(() => {\n ref.current = value;\n });\n return ref.current;\n}\n"],"names":["usePrevious","value","ref","useRef","undefined","useIsomorphicLayoutEffect","current"],"mappings":"wFAGwB,SAAAA,EAAkBC,GACxC,MAAMC,EAAMC,OAAOC,GAInB,OAHAC,GAA0B,KACxBH,EAAII,QAAUL,CAAK,IAEdC,EAAII,OACb"}
|