Skip to content

Commit

Permalink
feat(Datagrid): add opt out ability for editable cells (#5425)
Browse files Browse the repository at this point in the history
* feat(Datagrid): add opt out support for inline editing at cell level

* chore: cleanup

* chore: add note in story about editing opt out for cell

* chore: use em dash for static cell

* chore: add docs

* fix: prevent non-edit cells from going into edit mode

---------

Co-authored-by: kennylam <909118+kennylam@users.noreply.github.com>
  • Loading branch information
matthewgallo and kennylam committed Jun 20, 2024
1 parent ea48b9e commit 648571e
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -487,14 +487,32 @@ export const InlineEditCell = ({
);
};

const getLabel = () => {
const checkStaticCell = (val) => {
if (typeof val === 'object' && val?.isStaticCell) {
return val?.value;
}
};
switch (type) {
case 'selection':
checkStaticCell(value);
return value?.text ?? value;
case 'date':
checkStaticCell(value);
return buildDate(value);
default:
return checkStaticCell(value) ?? value;
}
};

return (
// eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions
<div
ref={outerButtonElement}
data-cell-id={cellId}
data-column-index={columnIndex}
data-row-index={cell.row.index}
data-disabled={disabledCell}
data-disabled={disabledCell || nonEditCell}
data-inline-type={type}
onClick={!nonEditCell ? handleInlineCellClick : addActiveState}
onKeyDown={!nonEditCell ? handleKeyDown : null}
Expand All @@ -511,13 +529,7 @@ export const InlineEditCell = ({
<InlineEditButton
isActiveCell={cellId === activeCellId}
renderIcon={setRenderIcon()}
label={
type === 'selection'
? value?.text ?? value
: type === 'date'
? buildDate(value)
: value
}
label={getLabel()}
disabledCell={disabledCell}
labelIcon={value?.icon || null}
placeholder={placeholder}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,19 @@ const MyInlineEditDatagrid = () => {
},
story: InlineEditUsageStory,
},
{
title: 'Opt out of editing at cell level',
description: `In some cases you may want to disable editing per cell. This is possible by providing the following structure for the cell value within your row data:`,
source: {
code: `
{
value: '\u2014', // Value displayed for static cell
isStaticCell: true,
columnId: 'lastName',
}
`,
},
},
]}
/>
);
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { makeData } from '../../utils/makeData';
import { ARG_TYPES } from '../../utils/getArgTypes';
import { getInlineEditColumns } from '../../utils/getInlineEditColumns';
import { WithFeatureFlags } from '../../../../../../core/.storybook/WithFeatureFlags';
import { ListItem, UnorderedList } from '@carbon/react';

const blockClass = `${pkg.prefix}--datagrid`;
const storybookBlockClass = `storybook-${blockClass}__validation-code-snippet`;
Expand Down Expand Up @@ -92,7 +93,9 @@ const sharedDatagridProps = {
};

const EditableCellUsage = ({ ...args }) => {
const [data, setData] = useState(makeData(10));
const [data, setData] = useState(
makeData(10, { includeNonEditableCell: true, column: 'lastName' })
);
const columns = React.useMemo(() => getInlineEditColumns(), []);

const datagridState = useDatagrid(
Expand All @@ -112,13 +115,24 @@ const EditableCellUsage = ({ ...args }) => {
}}
>
<Datagrid datagridState={datagridState} />
<p>
The following inline edit columns incorporate validation:
<code className={storybookBlockClass}>{'first_name'}</code>
<code className={storybookBlockClass}>{'last_name'}</code>
<code className={storybookBlockClass}>{'age'}</code>
<code className={storybookBlockClass}>{'visits'}</code>
</p>
<UnorderedList>
<ListItem>
<p>
The following inline edit columns incorporate validation:
<code className={storybookBlockClass}>{'first_name'}</code>
<code className={storybookBlockClass}>{'last_name'}</code>
<code className={storybookBlockClass}>{'age'}</code>
<code className={storybookBlockClass}>{'visits'}</code>
</p>
</ListItem>
<ListItem>
<p>
The second row's{' '}
<code className={storybookBlockClass}>{'lastName'}</code> cell is an
example of opting out of editing on a per cell basis.
</p>
</ListItem>
</UnorderedList>
</WithFeatureFlags>
);
};
Expand Down
27 changes: 23 additions & 4 deletions packages/ibm-products/src/components/Datagrid/useInlineEdit.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ const useInlineEdit = (hooks: Hooks) => {
const columnInlineEditConfig = cell.column.inlineEdit;
const inlineEditType = cell.column?.inlineEdit?.type;
const isDisabled = cell.column?.isDisabled;
const staticCell =
typeof cell.value === 'object' &&
cell.column.id === cell.value?.columnId &&
cell.value?.isStaticCell;

const renderInlineEditComponent = (type) => (
<InlineEditCell
Expand Down Expand Up @@ -48,15 +52,30 @@ const useInlineEdit = (hooks: Hooks) => {
role: 'gridcell',
children: (
<>
{inlineEditType === 'text' &&
{!staticCell &&
inlineEditType === 'text' &&
renderInlineEditComponent(inlineEditType)}
{inlineEditType === 'number' &&
{!staticCell &&
inlineEditType === 'number' &&
renderInlineEditComponent(inlineEditType)}
{inlineEditType === 'selection' &&
{!staticCell &&
inlineEditType === 'selection' &&
renderInlineEditComponent(inlineEditType)}
{inlineEditType === 'date' &&
{!staticCell &&
inlineEditType === 'date' &&
renderInlineEditComponent(inlineEditType)}
{/* Render default inline edit cell button, if it's column doesn't have an inline edit configuration */}
{staticCell && (
<InlineEditCell
config={columnInlineEditConfig}
tabIndex={-1}
value={cell.value?.value}
cell={cell}
instance={instance}
nonEditCell
type="text"
/>
)}
{!inlineEditType && (
<InlineEditCell
config={columnInlineEditConfig}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,14 @@ const newPerson = (index, config) => {
return {
disabledColumn: namor.generate({ words: 1, numbers: 0 }),
firstName: namor.generate({ words: 1, numbers: 0 }),
lastName: namor.generate({ words: 1, numbers: 0 }),
lastName:
index === 1 && config?.includeNonEditableCell && config?.column
? {
value: '\u2014',
isStaticCell: true,
columnId: config?.column,
}
: namor.generate({ words: 1, numbers: 0 }),
age: Math.floor(Math.random() * 30),
visits: Math.floor(Math.random() * 100),
progress: Math.floor(Math.random() * 100),
Expand Down

0 comments on commit 648571e

Please sign in to comment.