@indico-data/design-system 3.14.1 → 3.16.0

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.
Files changed (37) hide show
  1. package/lib/components/button/enums.d.ts +1 -1
  2. package/lib/components/button/types.d.ts +1 -1
  3. package/lib/components/icons/types.d.ts +1 -1
  4. package/lib/index.css +35 -28
  5. package/lib/index.d.ts +2 -2
  6. package/lib/index.esm.css +35 -28
  7. package/lib/index.esm.js +28 -7
  8. package/lib/index.esm.js.map +1 -1
  9. package/lib/index.js +28 -7
  10. package/lib/index.js.map +1 -1
  11. package/package.json +1 -1
  12. package/src/components/button/Button.mdx +24 -1
  13. package/src/components/button/Button.stories.tsx +7 -2
  14. package/src/components/button/Button.tsx +26 -16
  15. package/src/components/button/__tests__/Button.test.tsx +64 -11
  16. package/src/components/button/enums.ts +1 -1
  17. package/src/components/button/styles/Button.scss +19 -12
  18. package/src/components/button/styles/_variables.scss +2 -9
  19. package/src/components/button/types.ts +1 -1
  20. package/src/components/floatUI/FloatUI.stories.tsx +5 -0
  21. package/src/components/floatUI/FloatUI.tsx +5 -1
  22. package/src/components/forms/input/Input.tsx +7 -2
  23. package/src/components/forms/input/styles/Input.scss +4 -2
  24. package/src/components/forms/numberInput/NumberInput.tsx +7 -2
  25. package/src/components/forms/passwordInput/PasswordInput.tsx +2 -2
  26. package/src/components/icons/Icon.mdx +1 -1
  27. package/src/components/icons/Icon.stories.tsx +2 -2
  28. package/src/components/icons/styles/Icon.scss +1 -0
  29. package/src/components/icons/types.ts +1 -1
  30. package/src/components/menu/Menu.stories.tsx +3 -0
  31. package/src/components/menu/styles/Menu.scss +2 -2
  32. package/src/components/pagination/Pagination.tsx +2 -0
  33. package/src/components/stepper/components/Legend.tsx +1 -1
  34. package/src/components/toast/Toast.stories.tsx +5 -5
  35. package/src/docs/BaseColorPalette/Swatch.tsx +2 -2
  36. package/src/docs/Primitives.mdx +7 -1
  37. package/src/styles/primitives/_iconSizes.scss +4 -4
package/lib/index.js CHANGED
@@ -5075,12 +5075,31 @@ const Button$1 = React.forwardRef((props, ref) => {
5075
5075
  'btn--loading': isLoading,
5076
5076
  'btn--pill': isPill,
5077
5077
  }, className);
5078
+ // Map button size to icon size
5079
+ // xs → xs (12px), sm → sm (16px), md → md (20px), lg → md (20px), xl → lg (24px)
5080
+ const getIconSize = (buttonSize) => {
5081
+ switch (buttonSize) {
5082
+ case 'xs':
5083
+ return 'xs';
5084
+ case 'sm':
5085
+ return 'sm';
5086
+ case 'md':
5087
+ return 'md'; // md buttons use md icons (20px)
5088
+ case 'lg':
5089
+ return 'md'; // lg buttons use md icons (20px)
5090
+ case 'xl':
5091
+ return 'lg'; // xl buttons use lg icons (24px)
5092
+ default:
5093
+ return 'md';
5094
+ }
5095
+ };
5096
+ const iconSize = getIconSize(size);
5078
5097
  const handleOnClick = (event) => {
5079
5098
  if (!isLoading && onClick) {
5080
5099
  onClick(event);
5081
5100
  }
5082
5101
  };
5083
- return (jsxRuntime.jsxs("button", Object.assign({ ref: ref, disabled: isLoading || isDisabled, className: buttonClasses, role: "button", onClick: handleOnClick, "aria-label": ariaLabel || 'button', "aria-disabled": isLoading || isDisabled, "aria-busy": isLoading, type: type, onMouseLeave: onMouseExit }, rest, { children: [isLoading && !iconRight && (jsxRuntime.jsx(Icon, { name: "indico-o", style: { animation: 'spin 1s linear infinite' }, className: children ? 'mr-2' : '', ariaLabel: "Loading...", size: size })), iconLeft && !isLoading && (jsxRuntime.jsx(Icon, { name: iconLeft, className: children ? 'mr-2' : '', ariaLabel: `${iconLeft} Icon`, size: size })), children, iconRight && !isLoading && (jsxRuntime.jsx(Icon, { name: iconRight, className: children ? 'ml-2' : '', ariaLabel: `${iconRight} Icon`, size: size })), isLoading && iconRight && (jsxRuntime.jsx(Icon, { name: "indico-o", style: { animation: 'spin 1s linear infinite' }, className: children ? 'ml-2' : '', ariaLabel: "Loading...", size: size }))] })));
5102
+ return (jsxRuntime.jsxs("button", Object.assign({ ref: ref, disabled: isLoading || isDisabled, className: buttonClasses, role: "button", onClick: handleOnClick, "aria-label": ariaLabel || 'button', "aria-disabled": isLoading || isDisabled, "aria-busy": isLoading, type: type, onMouseLeave: onMouseExit }, rest, { children: [isLoading && !iconRight && (jsxRuntime.jsx(Icon, { name: "indico-o", style: { animation: 'spin 1s linear infinite' }, ariaLabel: "Loading...", size: iconSize })), iconLeft && !isLoading && (jsxRuntime.jsx(Icon, { name: iconLeft, ariaLabel: `${iconLeft} Icon`, size: iconSize })), children, iconRight && !isLoading && (jsxRuntime.jsx(Icon, { name: iconRight, ariaLabel: `${iconRight} Icon`, size: iconSize })), isLoading && iconRight && (jsxRuntime.jsx(Icon, { name: "indico-o", style: { animation: 'spin 1s linear infinite' }, ariaLabel: "Loading...", size: iconSize }))] })));
5084
5103
  });
5085
5104
 
5086
5105
  var l;function r$1(e,t){return e[t]}function i(e=[],t,n=0){return [...e.slice(0,n),t,...e.slice(n)]}function s(e=[],t,n="id"){const o=e.slice(),a=r$1(t,n);return a?o.splice(o.findIndex((e=>r$1(e,n)===a)),1):o.splice(o.findIndex((e=>e===t)),1),o}function d(e){return e.map(((e,t)=>{const n=Object.assign(Object.assign({},e),{sortable:e.sortable||!!e.sortFunction||void 0});return e.id||(n.id=t+1),n}))}function c(e,t){return Math.ceil(e/t)}function g(e,t){return Math.min(e,t)}!function(e){e.ASC="asc",e.DESC="desc";}(l||(l={}));const u=()=>null;function p(e,t=[],n=[]){let o={},a=[...n];return t.length&&t.forEach((t=>{if(!t.when||"function"!=typeof t.when)throw new Error('"when" must be defined in the conditional style object and must be function');t.when(e)&&(o=t.style||{},t.classNames&&(a=[...a,...t.classNames]),"function"==typeof t.style&&(o=t.style(e)||{}));})),{conditionalStyle:o,classNames:a.join(" ")}}function b$1(e,t=[],n="id"){const o=r$1(e,n);return o?t.some((e=>r$1(e,n)===o)):t.some((t=>t===e))}function m(e,t){return t?e.findIndex((e=>h$1(e.id,t))):-1}function h$1(e,t){return e==t}function w$1(e,t){const n=!e.toggleOnSelectedRowsChange;switch(t.type){case"SELECT_ALL_ROWS":{const{keyField:n,rows:o,rowCount:a,mergeSelections:l}=t,r=!e.allSelected,i=!e.toggleOnSelectedRowsChange;if(l){const t=r?[...e.selectedRows,...o.filter((t=>!b$1(t,e.selectedRows,n)))]:e.selectedRows.filter((e=>!b$1(e,o,n)));return Object.assign(Object.assign({},e),{allSelected:r,selectedCount:t.length,selectedRows:t,toggleOnSelectedRowsChange:i})}return Object.assign(Object.assign({},e),{allSelected:r,selectedCount:r?a:0,selectedRows:r?o:[],toggleOnSelectedRowsChange:i})}case"SELECT_SINGLE_ROW":{const{keyField:o,row:a,isSelected:l,rowCount:r,singleSelect:d}=t;return d?l?Object.assign(Object.assign({},e),{selectedCount:0,allSelected:!1,selectedRows:[],toggleOnSelectedRowsChange:n}):Object.assign(Object.assign({},e),{selectedCount:1,allSelected:!1,selectedRows:[a],toggleOnSelectedRowsChange:n}):l?Object.assign(Object.assign({},e),{selectedCount:e.selectedRows.length>0?e.selectedRows.length-1:0,allSelected:!1,selectedRows:s(e.selectedRows,a,o),toggleOnSelectedRowsChange:n}):Object.assign(Object.assign({},e),{selectedCount:e.selectedRows.length+1,allSelected:e.selectedRows.length+1===r,selectedRows:i(e.selectedRows,a),toggleOnSelectedRowsChange:n})}case"SELECT_MULTIPLE_ROWS":{const{keyField:o,selectedRows:a,totalRows:l,mergeSelections:r}=t;if(r){const t=[...e.selectedRows,...a.filter((t=>!b$1(t,e.selectedRows,o)))];return Object.assign(Object.assign({},e),{selectedCount:t.length,allSelected:!1,selectedRows:t,toggleOnSelectedRowsChange:n})}return Object.assign(Object.assign({},e),{selectedCount:a.length,allSelected:a.length===l,selectedRows:a,toggleOnSelectedRowsChange:n})}case"CLEAR_SELECTED_ROWS":{const{selectedRowsFlag:n}=t;return Object.assign(Object.assign({},e),{allSelected:!1,selectedCount:0,selectedRows:[],selectedRowsFlag:n})}case"SORT_CHANGE":{const{sortDirection:o,selectedColumn:a,clearSelectedOnSort:l}=t;return Object.assign(Object.assign(Object.assign({},e),{selectedColumn:a,sortDirection:o,currentPage:1}),l&&{allSelected:!1,selectedCount:0,selectedRows:[],toggleOnSelectedRowsChange:n})}case"CHANGE_PAGE":{const{page:o,paginationServer:a,visibleOnly:l,persistSelectedOnPageChange:r}=t,i=a&&r,s=a&&!r||l;return Object.assign(Object.assign(Object.assign(Object.assign({},e),{currentPage:o}),i&&{allSelected:!1}),s&&{allSelected:!1,selectedCount:0,selectedRows:[],toggleOnSelectedRowsChange:n})}case"CHANGE_ROWS_PER_PAGE":{const{rowsPerPage:n,page:o}=t;return Object.assign(Object.assign({},e),{currentPage:o,rowsPerPage:n})}}}const f=n.css`
@@ -5502,7 +5521,7 @@ const Input = React__namespace.default.forwardRef((_a, ref) => {
5502
5521
  error: hasErrors,
5503
5522
  'input--has-icon': iconName,
5504
5523
  }, className);
5505
- return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs("div", { className: "input-wrapper", children: [iconName && (jsxRuntime.jsx(Icon, { name: iconName, "data-testid": `${name}-embedded-icon`, className: "embedded-icon" })), jsxRuntime.jsx("input", Object.assign({ ref: ref, tabIndex: tabIndex, id: id, "data-testid": `form-input-${name}`, name: name, type: "text", disabled: isDisabled, placeholder: placeholder, readOnly: readonly, onChange: onChange, onBlur: onBlur, maxLength: maxLength, onKeyDown: onKeyDown, className: inputClasses, "aria-invalid": hasErrors ? true : undefined, "aria-describedby": hasErrors || helpText ? `${name}-helper` : undefined, "aria-required": isRequired }, rest)), isClearable && !isDisabled && (jsxRuntime.jsx(Icon, { name: "x-close", "data-testid": `${name}-clearable-icon`, size: "sm", onClick: handleClear, className: "clearable-icon" }))] }), hasErrors && jsxRuntime.jsx(DisplayFormError, { "data-testid": `${name}-error`, message: errorMessage }), helpText && (jsxRuntime.jsx("div", { "data-testid": `${name}-help-text`, className: "help-text", id: `${name}-helper`, children: helpText }))] }));
5524
+ return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs("div", { className: "input-wrapper", children: [iconName && (jsxRuntime.jsx(Icon, { name: iconName, "data-testid": `${name}-embedded-icon`, className: "embedded-icon", size: "sm" })), jsxRuntime.jsx("input", Object.assign({ ref: ref, tabIndex: tabIndex, id: id, "data-testid": `form-input-${name}`, name: name, type: "text", disabled: isDisabled, placeholder: placeholder, readOnly: readonly, onChange: onChange, onBlur: onBlur, maxLength: maxLength, onKeyDown: onKeyDown, className: inputClasses, "aria-invalid": hasErrors ? true : undefined, "aria-describedby": hasErrors || helpText ? `${name}-helper` : undefined, "aria-required": isRequired }, rest)), isClearable && !isDisabled && (jsxRuntime.jsx(Icon, { name: "x-close", "data-testid": `${name}-clearable-icon`, size: "xs", onClick: handleClear, className: "clearable-icon" }))] }), hasErrors && jsxRuntime.jsx(DisplayFormError, { "data-testid": `${name}-error`, message: errorMessage }), helpText && (jsxRuntime.jsx("div", { "data-testid": `${name}-help-text`, className: "help-text", id: `${name}-helper`, children: helpText }))] }));
5506
5525
  });
5507
5526
  const LabeledInput = withLabel(Input);
5508
5527
 
@@ -5541,7 +5560,7 @@ const Pagination = (_a) => {
5541
5560
  const isNextButtonDisabled = currentPage === totalPages;
5542
5561
  const isPreviousButtonDisabled = currentPage === 1;
5543
5562
  const hasError = Number(inputValue) > totalPages || Number(inputValue) < 1;
5544
- return (jsxRuntime.jsx("div", Object.assign({ className: classes }, rest, { children: jsxRuntime.jsx(Container, { children: jsxRuntime.jsxs(Row, { gutterWidth: 12, align: "center", children: [jsxRuntime.jsx(Col, { xs: "content", children: jsxRuntime.jsx("div", { className: "pagination__previous", children: jsxRuntime.jsx(Button$1, { "data-testid": "pagination-previous-button", ariaLabel: "Previous Page", variant: "link", onClick: handlePreviousPage, iconLeft: "chevron-left", isDisabled: isPreviousButtonDisabled || totalPages === 0 }) }) }), jsxRuntime.jsx(Col, { xs: "content", children: jsxRuntime.jsx("div", { className: "pagination__current-page", children: jsxRuntime.jsx(LabeledInput, { "data-testid": "pagination-current-page-input", className: classNames('pagination__current-page-input', {
5563
+ return (jsxRuntime.jsx("div", Object.assign({ className: classes }, rest, { children: jsxRuntime.jsx(Container, { children: jsxRuntime.jsxs(Row, { gutterWidth: 12, align: "center", children: [jsxRuntime.jsx(Col, { xs: "content", children: jsxRuntime.jsx("div", { className: "pagination__previous", children: jsxRuntime.jsx(Button$1, { "data-testid": "pagination-previous-button", ariaLabel: "Previous Page", variant: "link", onClick: handlePreviousPage, iconLeft: "chevron-left", size: "sm", isDisabled: isPreviousButtonDisabled || totalPages === 0 }) }) }), jsxRuntime.jsx(Col, { xs: "content", children: jsxRuntime.jsx("div", { className: "pagination__current-page", children: jsxRuntime.jsx(LabeledInput, { "data-testid": "pagination-current-page-input", className: classNames('pagination__current-page-input', {
5545
5564
  'has-error': hasError,
5546
5565
  }), value: totalPages === 0 ? '0' : inputValue, name: "currentPage", label: "Current Page", hasHiddenLabel: true, onKeyDown: (e) => {
5547
5566
  if (e.key === 'Enter') {
@@ -5553,7 +5572,7 @@ const Pagination = (_a) => {
5553
5572
  if (value === '' || /^\d*$/.test(value)) {
5554
5573
  setInputValue(value);
5555
5574
  }
5556
- }, onBlur: (e) => validateAndUpdatePage(e.currentTarget.value) }) }) }), jsxRuntime.jsx(Col, { xs: "content", children: jsxRuntime.jsx("p", { className: "pagination__page-total", children: totalPagesText }) }), jsxRuntime.jsx(Col, { xs: "content", children: jsxRuntime.jsx("div", { className: "pagination__next", children: jsxRuntime.jsx(Button$1, { "data-testid": "pagination-next-button", ariaLabel: "Next Page", variant: "link", onClick: handleNextPage, iconLeft: "chevron-right", isDisabled: isNextButtonDisabled || totalPages === 0 }) }) })] }) }) })));
5575
+ }, onBlur: (e) => validateAndUpdatePage(e.currentTarget.value) }) }) }), jsxRuntime.jsx(Col, { xs: "content", children: jsxRuntime.jsx("p", { className: "pagination__page-total", children: totalPagesText }) }), jsxRuntime.jsx(Col, { xs: "content", children: jsxRuntime.jsx("div", { className: "pagination__next", children: jsxRuntime.jsx(Button$1, { "data-testid": "pagination-next-button", ariaLabel: "Next Page", variant: "link", onClick: handleNextPage, iconLeft: "chevron-right", isDisabled: isNextButtonDisabled || totalPages === 0, size: "sm" }) }) })] }) }) })));
5557
5576
  };
5558
5577
 
5559
5578
  const TablePagination$1 = ({ rowsPerPage, rowCount, onChangePage, currentPage, totalEntriesText, }) => {
@@ -5832,7 +5851,7 @@ const PasswordInput = React__namespace.default.forwardRef((_a, ref) => {
5832
5851
  const inputClasses = classNames('password-input', {
5833
5852
  error: hasErrors,
5834
5853
  }, 'password-input--has-icon');
5835
- return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs("div", { className: "password-input-wrapper", children: [jsxRuntime.jsx(Icon, { name: "lock", "data-testid": `${name}-embedded-icon`, className: "embedded-icon" }), jsxRuntime.jsx("input", Object.assign({ ref: ref, "data-testid": `form-password-input-${name}`, name: name, type: showPassword ? 'text' : 'password', disabled: isDisabled, placeholder: placeholder, onChange: onChange, onBlur: onBlur, onKeyDown: onKeyDown, className: inputClasses, "aria-invalid": hasErrors ? 'true' : 'false', "aria-describedby": hasErrors || helpText ? `${name}-helper` : undefined, "aria-required": isRequired }, rest)), hasShowPassword && (jsxRuntime.jsx(Icon, { name: showPassword ? 'fa-eye-slash' : 'eye', "data-testid": `${name}-${showPassword ? 'hide' : 'show'}-password-icon`, size: "md", onClick: handleShowPassword, className: "toggle-show-password-icon" }))] }), hasErrors && jsxRuntime.jsx(DisplayFormError, { message: errorMessage }), helpText && (jsxRuntime.jsx("div", { "data-testid": `${name}-help-text`, className: "help-text", id: `${name}-helper`, children: helpText }))] }));
5854
+ return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs("div", { className: "password-input-wrapper", children: [jsxRuntime.jsx(Icon, { name: "lock", "data-testid": `${name}-embedded-icon`, className: "embedded-icon", size: "sm" }), jsxRuntime.jsx("input", Object.assign({ ref: ref, "data-testid": `form-password-input-${name}`, name: name, type: showPassword ? 'text' : 'password', disabled: isDisabled, placeholder: placeholder, onChange: onChange, onBlur: onBlur, onKeyDown: onKeyDown, className: inputClasses, "aria-invalid": hasErrors ? 'true' : 'false', "aria-describedby": hasErrors || helpText ? `${name}-helper` : undefined, "aria-required": isRequired }, rest)), hasShowPassword && (jsxRuntime.jsx(Icon, { name: showPassword ? 'fa-eye-slash' : 'eye', "data-testid": `${name}-${showPassword ? 'hide' : 'show'}-password-icon`, size: "sm", onClick: handleShowPassword, className: "toggle-show-password-icon" }))] }), hasErrors && jsxRuntime.jsx(DisplayFormError, { message: errorMessage }), helpText && (jsxRuntime.jsx("div", { "data-testid": `${name}-help-text`, className: "help-text", id: `${name}-helper`, children: helpText }))] }));
5836
5855
  });
5837
5856
  const LabeledPasswordInput = withLabel(PasswordInput);
5838
5857
 
@@ -13852,6 +13871,7 @@ const defaultOptions$1 = {
13852
13871
  middleware: [offset$2(5), flip$2(), shift$2()],
13853
13872
  };
13854
13873
  function FloatUI({ children, ariaLabel, isOpen: controlledIsOpen, setIsOpen: controlledSetIsOpen, isPortal = false, portalOptions = {}, floatingOptions = defaultOptions$1, className, hover = false, onOpenChange, }) {
13874
+ var _a;
13855
13875
  const [internalIsOpen, setInternalIsOpen] = React.useState(false);
13856
13876
  // Determine whether the component is controlled or uncontrolled
13857
13877
  const isControlled = controlledIsOpen !== undefined && controlledSetIsOpen !== undefined;
@@ -13867,11 +13887,12 @@ function FloatUI({ children, ariaLabel, isOpen: controlledIsOpen, setIsOpen: con
13867
13887
  if (!React.isValidElement(trigger) || !React.isValidElement(content)) {
13868
13888
  throw new Error('Both children of FloatUI must be valid React elements.');
13869
13889
  }
13890
+ const referenceElement = ((_a = floatingOptions.elements) === null || _a === void 0 ? void 0 : _a.reference) || referenceElementRef.current;
13870
13891
  const { refs, floatingStyles, context } = useFloating(Object.assign(Object.assign({}, floatingOptions), { open: isOpen, onOpenChange: (isOpen) => {
13871
13892
  setIsOpen(isOpen);
13872
13893
  onOpenChange === null || onOpenChange === void 0 ? void 0 : onOpenChange(isOpen);
13873
13894
  }, elements: {
13874
- reference: referenceElementRef.current,
13895
+ reference: referenceElement,
13875
13896
  } }));
13876
13897
  // Can't call hooks conditionally so this enabled option is needed.
13877
13898
  const click = useClick(context, { enabled: !hover });
@@ -43493,7 +43514,7 @@ const Legend = ({ currentStep, steps, onStepClick }) => {
43493
43514
  return (jsxRuntime.jsxs("div", { children: [jsxRuntime.jsxs(Row, { nogutter: true, align: "center", children: [jsxRuntime.jsx(Col, { xs: "content", children: jsxRuntime.jsx("div", { className: classNames('stepper-legend-circle', {
43494
43515
  completed: isCompleted,
43495
43516
  current: isCurrent,
43496
- }), children: isCompleted ? jsxRuntime.jsx(Icon, { name: "check" }) : index + 1 }) }), jsxRuntime.jsx(Col, { children: jsxRuntime.jsx("div", { className: classNames('stepper-legend-step', {
43517
+ }), children: isCompleted ? jsxRuntime.jsx(Icon, { name: "check", size: "sm" }) : index + 1 }) }), jsxRuntime.jsx(Col, { children: jsxRuntime.jsx("div", { className: classNames('stepper-legend-step', {
43497
43518
  'stepper-legend-step--current-step': isCurrent,
43498
43519
  'stepper-legend-step--completed-step': isCompleted,
43499
43520
  'stepper-legend-step--disabled-step': !isSidebarEnabled,