diff --git a/.eslintrc.json b/.eslintrc.json index e0afe12..4a842c0 100755 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -66,5 +66,6 @@ "arrow-body-style": 0, "class-methods-use-this": 0, "max-len": 0 - } + }, + "ignorePatterns": ["**/*.css"] } diff --git a/.storybook/main.js b/.storybook/main.js index b88f609..a59f2f4 100755 --- a/.storybook/main.js +++ b/.storybook/main.js @@ -15,4 +15,5 @@ module.exports = { features: { postcss: false, }, + addons: ['storybook-css-modules-preset'], } diff --git a/next-env.d.ts b/next-env.d.ts new file mode 100644 index 0000000..8425e18 --- /dev/null +++ b/next-env.d.ts @@ -0,0 +1,2 @@ +declare module '*.css' +declare module '*.scss' diff --git a/package.json b/package.json index 7b9ecc4..9d2e550 100755 --- a/package.json +++ b/package.json @@ -35,18 +35,17 @@ }, "peerDependencies": { "@date-io/dayjs": ">= 2.10.8", - "@emotion/react": ">= 11.1.5", - "@emotion/styled": ">= 11.3.0", + "@emotion/react": "^11.10.0", + "@emotion/styled": "^11.10.0", "dayjs": ">= 1.10.4", "react": "^17.0.0", "react-dom": "^17.0.0" }, "dependencies": { "@babel/core": ">=7.11.5 <8.0.0", - "@mui/icons-material": "^5.6.1", - "@mui/lab": "^5.0.0-alpha.77", - "@mui/material": "^5.6.1", - "@mui/styles": "^5.6.1", + "@mui/icons-material": "^5.8.4", + "@mui/lab": "^5.0.0-alpha.95", + "@mui/material": "^5.10.5", "@storybook/addon-controls": "^6.5.2", "@storybook/addon-viewport": "6.5.3", "@storybook/react": "6.4.0-alpha.30", @@ -63,6 +62,7 @@ "react-is": "^17.0.2", "react-virtualized": "^9.22.3", "require-from-string": "^2.0.2", + "storybook-css-modules-preset": "^1.1.1", "tslib": "^2.4.0", "value-equal": "^1.0.1" }, diff --git a/src/columnGrid/ColumnGrid.tsx b/src/columnGrid/ColumnGrid.tsx index cc33b46..24fb9c2 100755 --- a/src/columnGrid/ColumnGrid.tsx +++ b/src/columnGrid/ColumnGrid.tsx @@ -7,7 +7,6 @@ import { ColumnGridProps } from './columnGridProps' import { CellMeasureRendererProps, MeasurerRendererProps } from '../cellMeasurer' import Tooltip from '@mui/material/Tooltip' import { ROW_SELECTION_HEADER_ID } from '../rowSelection' -import { makeStyles } from '@mui/styles' import { isFunctionType } from '../helpers' import flattenDeep from 'lodash/flattenDeep' import { createCellQueryProperties } from '../keyboard' @@ -16,41 +15,31 @@ import { SortIndicator } from './components' import { useApiEventHandler } from '../api' import KeyboardArrowRightIcon from '@mui/icons-material/KeyboardArrowRight' import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown' -import { Theme } from '@mui/material' +import styles from './styles.module.css' type SortDisabled = boolean -const useStyles = makeStyles((theme: Theme) => ({ - defaultHeader: { - display: 'flex', - justifyContent: 'center', - alignItems: 'center', - height: '100%', - width: '100%', - boxSizing: 'border-box', - background: '#efefef', - cursor: 'default', - border: '1px solid #ccc', +const defaultHeader = { + display: 'flex', + justifyContent: 'center', + alignItems: 'center', + height: '100%', + width: '100%', + boxSizing: 'border-box', + background: '#efefef', + cursor: 'default', + border: '1px solid #ccc', +} +const headerContainer = { + outline: 'none', + position: 'sticky !important' as any, + top: 0, + zIndex: 1, + 'scrollbar-width': 'none', + '&::-webkit-scrollbar': { + display: 'none', }, - headerContainer: { - outline: 'none', - position: 'sticky !important' as any, - top: 0, - zIndex: 1, - 'scrollbar-width': 'none', - '&::-webkit-scrollbar': { - display: 'none', - }, - }, - contentSpan: { - textAlign: 'center', - display: 'flex', - alignItems: 'center', - justifyContent: 'center', - width: '100%', - height: '100%', - }, -})) +} export const ColumnGrid: React.FC = React.memo( ({ @@ -75,7 +64,6 @@ export const ColumnGrid: React.FC = React.memo( sort, headerId, }) => { - const classes = useStyles() const logger = useLogger('ColumnGrid') const cache: CellMeasurerCache = useMemo(() => { /** @@ -141,7 +129,6 @@ export const ColumnGrid: React.FC = React.memo( useApiEventHandler(apiRef, 'DATA_CHANGED', recomputeSizes) useApiEventHandler(apiRef, 'GRID_RESIZE', recomputeSizes) useApiEventHandler(apiRef, 'COLUMNS_CHANGED', recomputeSizes) - const headerRendererWrapper = useCallback( ({ style, cell, ref, columnIndex, rowIndex }: CellMeasureRendererProps) => { const { title, renderer } = cell @@ -156,7 +143,7 @@ export const ColumnGrid: React.FC = React.memo( let headerClassName = '' if (!cell.dummy && cell.isNested) { headerClassName = clsx( - classes.defaultHeader, + defaultHeader, theme?.headerClass, theme?.nestedHeaderClass, cell.className, @@ -164,7 +151,7 @@ export const ColumnGrid: React.FC = React.memo( } if (!cell.dummy && !cell.isNested) { - headerClassName = clsx(classes.defaultHeader, theme?.headerClass, cell.className) + headerClassName = clsx(defaultHeader, theme?.headerClass, cell.className) } //If the cell is selected we set the column as selected too @@ -211,7 +198,7 @@ export const ColumnGrid: React.FC = React.memo( {/* eslint-disable-next-line jsx-a11y/click-events-have-key-events */} apiRef.current.toggleSort(cell.id)} - className={classes.contentSpan} + className={styles.contentSpan} > {child} {sortComponent} @@ -290,8 +277,6 @@ export const ColumnGrid: React.FC = React.memo( }, [ apiRef, - classes.contentSpan, - classes.defaultHeader, columns, coords, headersSortDisabledMap, @@ -355,10 +340,9 @@ export const ColumnGrid: React.FC = React.memo( const onRefMount = useCallback(instance => { gridRef.current = instance }, []) - return ( ({ - root: { - zIndex: 999, - }, - calendarContainer: { - border: 'none', - }, -})) +const root = { + zIndex: 999, +} export const CalendarEditor = forwardRef( ({ apiRef, stopEditing, anchorRef, value, additionalProps }: EditorProps, componentRef) => { - const classes = useStyles() const [state, setState] = useState<{ value: dayjs.Dayjs; close: boolean }>({ value: value ? dayjs(value) : dayjs(), close: false, @@ -92,7 +85,7 @@ export const CalendarEditor = forwardRef( anchorEl={anchorRef} placement={'right-start'} keepMounted={false} - className={classes.root} + sx={root} modifiers={popperModifiers} > ({ - input: { - width: '100%', - height: '100%', - resize: 'none', - overflow: 'auto', +const input = { + width: '100%', + height: '100%', + resize: 'none', + overflow: 'auto', + border: 0, + outline: 0, + '&:focus': { border: 0, outline: 0, - '&:focus': { - border: 0, - outline: 0, - }, }, -})) +} export const NumericEditor = forwardRef( ( @@ -43,7 +40,6 @@ export const NumericEditor = forwardRef( }: EditorProps, componentRef, ) => { - const classes = useStyles() const [editingValue, setEditingValue] = useState( isNaN(Number(value)) ? '0' : String(value), ) @@ -134,7 +130,7 @@ export const NumericEditor = forwardRef( aria-label="numeric apollo editor" minRows={1} maxLength={maxLength} - className={clsx(classes.input, additionalProps?.className)} + className={clsx(input, additionalProps?.className)} style={additionalProps?.style} /> diff --git a/src/editorManager/components/TextEditor.tsx b/src/editorManager/components/TextEditor.tsx index 56f7f06..c1f2360 100755 --- a/src/editorManager/components/TextEditor.tsx +++ b/src/editorManager/components/TextEditor.tsx @@ -8,27 +8,12 @@ import React, { } from 'react' import { TextareaAutosize, Theme } from '@mui/material' import { EditorProps } from '../editorProps' -import { makeStyles } from '@mui/styles' import { handleEditorKeydown } from '../utils' import clsx from 'clsx' import { GRID_RESIZE, useApiEventHandler } from '../../api' import EditorContainer from './EditorContainer' import { createDefaultPaperProps } from './createDefaultPaperProps' - -const useStyles = makeStyles((theme: Theme) => ({ - input: { - width: '100%', - height: '100%', - resize: 'none', - overflow: 'auto', - border: 0, - outline: 0, - '&:focus': { - border: 0, - outline: 0, - }, - }, -})) +import styles from './styles.module.css' export const TextEditor = forwardRef( ( @@ -43,7 +28,6 @@ export const TextEditor = forwardRef( }: EditorProps, componentRef, ) => { - const classes = useStyles() const [editingValue, setEditingValue] = useState(String(value)) const onAnchorResize = useCallback(() => { @@ -118,7 +102,7 @@ export const TextEditor = forwardRef( aria-label="text apollo editor" minRows={1} maxLength={maxLength} - className={clsx(classes.input, additionalProps?.className, theme?.editorClass)} + className={clsx(styles.input, additionalProps?.className, theme?.editorClass)} style={additionalProps?.style} /> diff --git a/src/editorManager/components/styles.module.css b/src/editorManager/components/styles.module.css new file mode 100644 index 0000000..8ea803e --- /dev/null +++ b/src/editorManager/components/styles.module.css @@ -0,0 +1,13 @@ +.input { + width: 100%; + height: 100%; + resize: none; + overflow: auto; + border: 0; + outline: 0; +} + +.input:focus { + border: 0; + outline: 0; +} diff --git a/src/gridWrapper/GridWrapper.tsx b/src/gridWrapper/GridWrapper.tsx index 0618368..ac26582 100755 --- a/src/gridWrapper/GridWrapper.tsx +++ b/src/gridWrapper/GridWrapper.tsx @@ -11,34 +11,12 @@ import clsx from 'clsx' import { GridCellProps } from 'react-virtualized/dist/es/Grid' import { MeasurerRendererProps } from '../cellMeasurer' import { GridWrapperProps } from './gridWrapperProps' -import { makeStyles } from '@mui/styles' import { StretchMode } from '../types' import { useLogger } from '../logger' import KeyboardArrowRightIcon from '@mui/icons-material/KeyboardArrowRight' import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown' import { useApiExtends, GridWrapperApi, useApiEventHandler } from '../api' -import { Theme } from '@mui/material' - -const useStyles = makeStyles((theme: Theme) => ({ - bodyContainer: { - outline: 'none', - }, - cellDefaultStyle: { - display: 'flex', - boxSizing: 'border-box', - '&:focus': { - outline: 0, - border: 0, - }, - }, - disabledCell: { - cursor: 'default', //no clickable action for this cell - pointerEvents: 'none', //no events for this cell - }, - suppressHorizontalOverflow: { - overflowX: 'hidden', - }, -})) +import styles from './styles.module.css' const GridWrapper: React.FC = React.memo( ({ @@ -96,7 +74,6 @@ const GridWrapper: React.FC = React.memo( }, [fixedRowHeight, fixedRowWidth, minColumnWidth, minRowHeight, rowHeight]) const cacheRef = useRef(cache) - const classes = useStyles() const gridRef = useRef(null) const loggerRef = useRef(logger) const coordsRef = useRef(coords) @@ -209,7 +186,7 @@ const GridWrapper: React.FC = React.memo( * of the parent because there is none visible * */ let cellClassName = clsx( - classes.cellDefaultStyle, + styles.cellDefaultStyle, theme?.cellClass, typeof column.cellClassName === 'function' ? column.cellClassName({ row, column }) @@ -220,7 +197,7 @@ const GridWrapper: React.FC = React.memo( } if (navigationDisabled && !cell.dummy && theme?.disabledCellClass) { - cellClassName = clsx(cellClassName, classes.disabledCell, theme?.disabledCellClass) + cellClassName = clsx(cellClassName, styles.disabledCell, theme?.disabledCellClass) } if (selection && selection.cellClassName) { @@ -330,8 +307,6 @@ const GridWrapper: React.FC = React.memo( rows, isCellRowActive, theme, - classes.cellDefaultStyle, - classes.disabledCell, selection, nestedRowsProps, highlightBorderColor, @@ -413,15 +388,14 @@ const GridWrapper: React.FC = React.memo( const gridWrapperApi: GridWrapperApi = { getGridRef } useApiExtends(apiRef, gridWrapperApi, 'GridWrapperApi') - return ( <> = React.memo( onSectionRendered={onSectionRendered} scrollToAlignment={scrollToAlignment} onScroll={onScroll} - scrollLeft={scrollLeft} + //scrollLeft={scrollLeft} height={height} width={width} noContentRenderer={noContentOverlay} diff --git a/src/gridWrapper/styles.module.css b/src/gridWrapper/styles.module.css new file mode 100644 index 0000000..6ed0748 --- /dev/null +++ b/src/gridWrapper/styles.module.css @@ -0,0 +1,23 @@ +.bodyContainer { + width: 100%; + height: 100%; +} +.grid { + outline: none; +} +.suppressHorizontalOverflow { + overflow-x: hidden; +} + +.cellDefaultStyle { + display: flex; + box-sizing: border-box; +} +.cellDefaultStyle:focus { + outline: 0; + border: 0; +} +.disabledCell { + cursor: default; + pointer-events: none; +} diff --git a/src/types/grid-theme.ts b/src/types/grid-theme.ts index 975791b..96a9040 100755 --- a/src/types/grid-theme.ts +++ b/src/types/grid-theme.ts @@ -1,3 +1,5 @@ +import { SxProps } from '@mui/material' + /** * @todo Theme must construct all the flows with styling * @todo Rename to ApolloTheme @@ -7,23 +9,23 @@ export interface GridTheme { * Styles the whole row where the cell is selected and * also applies styling to the highlighted cell */ - currentRowClass?: string + currentRowClass?: string | SxProps /** * Styles the active highlighted column */ - currentColumnClass?: string - headerClass?: string - nestedHeaderClass?: string - cellClass?: string - disabledCellClass?: string + currentColumnClass?: string | SxProps + headerClass?: string | SxProps + nestedHeaderClass?: string | SxProps + cellClass?: string | SxProps + disabledCellClass?: string | SxProps /** * Styles to be applied in the root container of the active editor * Not every editor behaves the same and this will only work for default editor, if you wish * a more advanced configuration, use column/header `editorProps` */ - editorClass?: string + editorClass?: string | SxProps /** * Styles the editor parent container */ - editorContainerClass?: string + editorContainerClass?: string | SxProps } diff --git a/stories/components/Budget/P&L.tsx b/stories/components/Budget/P&L.tsx index ef36760..e9a0d56 100644 --- a/stories/components/Budget/P&L.tsx +++ b/stories/components/Budget/P&L.tsx @@ -451,7 +451,7 @@ export function Financial() { return ( - + - + - + - + ({ - iconBtn: { - padding: 0, - cursor: 'default', - color: '#CCCCCC', - '&:hover': { - backgroundColor: 'transparent', - }, - }, -})) +import './styles.css' interface CustomRows { id: string @@ -44,7 +33,6 @@ const generateFakeData = () => { } export function CustomHeaders() { - const classes = useStyles() const apiRef = useApiRef() const [rows, setRows] = useState(() => { return generateFakeData() @@ -92,7 +80,7 @@ export function CustomHeaders() { width: '20%', renderer: () => { return ( - + ) @@ -106,7 +94,7 @@ export function CustomHeaders() { width: '20%', renderer: () => { return ( - + ) @@ -120,14 +108,14 @@ export function CustomHeaders() { width: '20%', renderer: () => { return ( - + ) }, }, ], - [classes.iconBtn, onCreateRowClick], + [onCreateRowClick], ) return ( diff --git a/stories/components/Headers/styles.css b/stories/components/Headers/styles.css new file mode 100644 index 0000000..0bcb197 --- /dev/null +++ b/stories/components/Headers/styles.css @@ -0,0 +1,8 @@ +.iconBtn { + padding: 0; + cursor: default; + color: #cccccc; +} +.iconBtn:hover { + background-color: transparent; +} diff --git a/stories/components/Sort/Table.tsx b/stories/components/Sort/Table.tsx index f450400..3af2e07 100755 --- a/stories/components/Sort/Table.tsx +++ b/stories/components/Sort/Table.tsx @@ -2,16 +2,8 @@ import React, { useState } from 'react' import { ApolloSpreadSheet, StretchMode, Column, useApiRef, CellChangeParams } from '../../../src' import AddCircle from '@mui/icons-material/AddCircle' import { Box, IconButton } from '@mui/material' -// eslint-disable-next-line import/no-extraneous-dependencies import faker from 'faker' -import { makeStyles } from '@mui/styles' - -const useStyles = makeStyles(() => ({ - selectedCell: { - background: '#f5f5f5', - color: '#4d4d4d', - }, -})) +import styles from './styles.module.css' interface DemoRow { id: string @@ -34,7 +26,6 @@ const generateRows = count => { } export function Table() { - const classes = useStyles() const [rows, setRows] = useState(generateRows(15)) const apiRef = useApiRef() const onHeaderIconClick = () => { @@ -133,7 +124,7 @@ export function Table() { selection={{ key: 'id', onHeaderIconClick, - cellClassName: classes.selectedCell, + cellClassName: styles.selectedCell, }} disableSort /> diff --git a/stories/components/Sort/TableSort.tsx b/stories/components/Sort/TableSort.tsx index 61a604e..7c762d0 100755 --- a/stories/components/Sort/TableSort.tsx +++ b/stories/components/Sort/TableSort.tsx @@ -2,19 +2,8 @@ import React, { useCallback, useState } from 'react' import { ApolloSpreadSheet, StretchMode, Column, useApiRef, CellChangeParams } from '../../../src' import AddCircle from '@mui/icons-material/AddCircle' import { Box, IconButton, Typography } from '@mui/material' -// eslint-disable-next-line import/no-extraneous-dependencies import faker from 'faker' -import { makeStyles } from '@mui/styles' - -const useStyles = makeStyles(() => ({ - selectedCell: { - background: '#f5f5f5', - color: '#4d4d4d', - }, - textStyle: { - margin: '10px', - }, -})) +import styles from './styles.module.css' interface DemoRow { id: string @@ -37,7 +26,6 @@ const generateRows = count => { } export function TableSort() { - const classes = useStyles() const [rows, setRows] = useState(generateRows(15)) const apiRef = useApiRef() const onHeaderIconClick = () => { @@ -125,12 +113,9 @@ export function TableSort() { return updatedRows }) } - return ( - - This table uses sort. Click on the header to test it - +

This table uses sort. Click on the header to test it

diff --git a/stories/components/Sort/styles.module.css b/stories/components/Sort/styles.module.css new file mode 100644 index 0000000..2e951dd --- /dev/null +++ b/stories/components/Sort/styles.module.css @@ -0,0 +1,10 @@ +.selectedCell { + background-color: #f5f5f5; + color: #222222; +} + +.textStyle { + margin: 10px; + color: red; + font-size: 10px; +} diff --git a/stories/components/Spreadsheet/Spreadsheet.tsx b/stories/components/Spreadsheet/Spreadsheet.tsx index 1510f71..8ad5784 100755 --- a/stories/components/Spreadsheet/Spreadsheet.tsx +++ b/stories/components/Spreadsheet/Spreadsheet.tsx @@ -3,7 +3,6 @@ import { createMergeCellsData } from './createMergedCells' import { orderBy } from 'lodash' import { Box } from '@mui/material' import { useTopCase } from './dataUseCases' -import { makeStyles } from '@mui/styles' import dump from './dump.json' import { ApolloSpreadSheet, @@ -14,57 +13,10 @@ import { StretchMode, useApiRef, } from '../../../src' - -const useStyles = makeStyles(() => ({ - root: { - margin: 10, - }, - currentColumnClass: { - color: '#225890', - }, - currentColumnClassDark: { - color: 'blue', - }, - currentRowClass: { - color: '#225890', - }, - currentRowClassDark: { - color: 'blue', - }, - headerClass: { - background: 'white', - border: 'none', - fontWeight: 700, - fontSize: '11px', - }, - headerClassDark: { - background: 'white !important' as any, - border: 'none !important' as any, - fontWeight: 700, - fontSize: '14px', - }, - rowClass: { - border: '1px solid white', - backgroundColor: '#E6EFED', - fontSize: '13px', - }, - rowClassDark: { - border: '1px solid white', - backgroundColor: 'black', - color: 'white', - }, - disabledCellClass: { - opacity: '0.6', - }, - checkBox: { - height: '10px', - width: '10px', - }, -})) +import styles from './styles.module.css' const MIN_COLUMN_WIDTH = 10 export function Spreadsheet() { - const classes = useStyles() const { headerData: columns } = useTopCase() const [data, setData] = useState(dump) const apiRef = useApiRef() @@ -74,11 +26,11 @@ export function Spreadsheet() { }, [data, columns]) const customTheme: GridTheme = { - currentColumnClass: classes.currentColumnClass, - currentRowClass: classes.currentRowClass, - headerClass: classes.headerClass, - disabledCellClass: classes.disabledCellClass, - cellClass: classes.rowClass, + currentColumnClass: styles.currentColumnClass, + currentRowClass: styles.CurrentRowClass, + headerClass: styles.headerClass, + disabledCellClass: styles.disabledCellClass, + cellClass: styles.rowClass, } const onCellChange = useCallback( @@ -98,7 +50,7 @@ export function Spreadsheet() { const [delayedPosition, setDelayedPosition] = useState(null) - function createRow(coords: NavigationCoords) { + const createRow = (coords: NavigationCoords) => { const mergedCellInfo = mergeCellsData.find( e => e.rowIndex === coords.rowIndex && e.colIndex === coords.colIndex, ) @@ -170,14 +122,14 @@ export function Spreadsheet() { const selection: SelectionProps = { key: 'taskId', - checkboxClass: classes.checkBox, + checkboxClass: styles.checkBox, onHeaderIconClick, } return ( ({ - formControl: { - // margin: theme.spacing(1), - minWidth: 120, - }, -})) +import './styles.css' interface Props { activeThemeIndex: number handleChange: (index: number) => void } export const ThemeSelectMenu: React.FC = memo(({ activeThemeIndex, handleChange }) => { - const classes = useStyles() const [open, setOpen] = useState(false) const handleClose = useCallback(() => { setOpen(false) @@ -32,7 +24,7 @@ export const ThemeSelectMenu: React.FC = memo(({ activeThemeIndex, handle ) return ( - + Select Theme