Skip to content

Commit

Permalink
incomplete - TableWithRename.jsx
Browse files Browse the repository at this point in the history
  • Loading branch information
lindapaiste committed Aug 16, 2023
1 parent a2b083b commit 88a4961
Show file tree
Hide file tree
Showing 5 changed files with 284 additions and 205 deletions.
56 changes: 56 additions & 0 deletions client/common/Table/StandardTable.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { omit } from 'lodash';
import PropTypes from 'prop-types';
import React from 'react';
import TableBase from './TableBase';

/**
* Extends TableBase, but renders each row based on the columns.
* Can provide a `Dropdown` column which gets the `row` as a prop.
*/
function StandardTable({ Dropdown, columns, ...props }) {
const renderRow = (item) => (
<tr key={item.id}>
{columns.map((column, i) => {
const value = item[column.field];
const formatted = column.formatValue
? column.formatValue(value)
: value;
if (i === 0) {
return (
<th scope="row" key={column.field}>
{formatted}
</th>
);
}
return <td key={column.field}>{formatted}</td>;
})}
{
// TODO: styled-component
Dropdown && (
<td className="sketch-list__dropdown-column">
<Dropdown row={item} />
</td>
)
}
</tr>
);
return (
<TableBase
{...props}
columns={columns}
renderRow={renderRow}
addDropdownColumn={Boolean(Dropdown)}
/>
);
}

StandardTable.propTypes = {
...omit(TableBase.propTypes, ['renderRow', 'addDropdownColumn']),
Dropdown: PropTypes.elementType
};

StandardTable.defaultProps = {
Dropdown: null
};

export default StandardTable;
2 changes: 1 addition & 1 deletion client/common/Table/TableBase.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ function TableBase({
{addDropdownColumn && <StyledHeaderCell scope="col" />}
</tr>
</thead>
<tbody>{sortedItems.map((item) => renderRow(item))}</tbody>
<tbody>{sortedItems.map((item) => renderRow(item, columns))}</tbody>
</table>
);
}
Expand Down
134 changes: 134 additions & 0 deletions client/common/Table/TableWithRename.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
import { omit } from 'lodash';
import PropTypes from 'prop-types';
import React, { useEffect, useRef, useState } from 'react';
import TableBase from './TableBase';

const RenameInput = ({ text, onSubmit, onCancel }) => {
const inputRef = useRef(null);

useEffect(() => {
inputRef.current?.focus();
}, [inputRef]);

const [renameValue, setRenameValue] = useState(text);

const handleNameChange = () => {
const newName = renameValue.trim();
if (newName.length === 0 || newName === text) {
onCancel();
} else {
onSubmit(newName);
}
};

const handleKey = (e) => {
if (e.key === 'Enter') {
handleNameChange();
} else if (e.key === 'Esc' || e.key === 'Escape') {
onCancel();
}
};

return (
<input
value={renameValue}
onChange={(e) => setRenameValue(e.target.value)}
onKeyDown={handleKey}
onBlur={handleNameChange}
// onClick={(e) => e.stopPropagation()}
ref={inputRef}
/>
);
};

RenameInput.propTypes = {
text: PropTypes.string.isRequired,
onSubmit: PropTypes.func.isRequired,
onCancel: PropTypes.func.isRequired
};

/**
* Extends TableBase, but renders each row based on the columns.
* Can provide a `Dropdown` column which gets the `row` as a prop.
*/
function TableWithRename({
Dropdown,
dropdownProps,
columns,
handleRename,
...props
}) {
const [editingRowId, setEditingRowId] = useState(null);

console.log({ editingRowId });

const renderRow = (item) => (
<tr key={item.id} className="sketches-table__row">
{columns.map((column, i) => {
const value = item[column.field];
const formatted = column.formatValue
? column.formatValue(value, item)
: value;
const content =
column.field === 'name' && editingRowId === item.id ? (
<RenameInput
text={value}
onSubmit={(newName) => {
handleRename(newName, item.id);
setEditingRowId(null);
}}
onCancel={() => {
setEditingRowId(null);
}}
/>
) : (
formatted
);
if (i === 0) {
return (
<th scope="row" key={column.field}>
{content}
</th>
);
}
return <td key={column.field}>{content}</td>;
})}
{
// TODO: styled-component
Dropdown && (
<td className="sketch-list__dropdown-column">
<Dropdown
{...dropdownProps}
row={item}
onClickRename={() => {
setTimeout(() => setEditingRowId(item.id), 0);
}}
/>
</td>
)
}
</tr>
);
return (
<TableBase
{...props}
columns={columns}
renderRow={renderRow}
addDropdownColumn={Boolean(Dropdown)}
/>
);
}

TableWithRename.propTypes = {
...omit(TableBase.propTypes, ['renderRow', 'addDropdownColumn']),
Dropdown: PropTypes.elementType.isRequired,
handleRename: PropTypes.func.isRequired,
// eslint-disable-next-line react/forbid-prop-types
dropdownProps: PropTypes.object
};

TableWithRename.defaultProps = {
dropdownProps: {}
};

export default TableWithRename;
10 changes: 8 additions & 2 deletions client/components/Dropdown/DropdownMenu.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,11 @@ const DropdownMenu = forwardRef(
};

return (
<div ref={anchorRef} className={className}>
<div
ref={anchorRef}
className={className}
style={{ position: 'relative' }}
>
<button
className={classes.button}
aria-label={ariaLabel}
Expand All @@ -50,7 +54,9 @@ const DropdownMenu = forwardRef(
<DropdownWrapper
className={classes.list}
align={align}
onMouseUp={close}
onMouseUp={() => {
setTimeout(close, 100);
}}
onBlur={handleBlur}
onFocus={handleFocus}
>
Expand Down
Loading

0 comments on commit 88a4961

Please sign in to comment.