diff --git a/cosmoz-omnitable-column-mixin.js b/cosmoz-omnitable-column-mixin.js index 5fa2aa68..356afec9 100644 --- a/cosmoz-omnitable-column-mixin.js +++ b/cosmoz-omnitable-column-mixin.js @@ -64,6 +64,15 @@ export const getString = ({ valuePath }, item) => get(item, valuePath), renderCell: { type: Function }, renderEditCell: { type: Function }, renderGroup: { type: Function }, + + /** + * The priority of the column in the mini mode. If missing the column is disabled in the mini mode. + */ + mini: { type: Number, value: null }, + /** + * An alternative render to use in mini mode. Takes the same params as `renderCell`. + */ + renderMini: { type: Function }, }; } @@ -82,7 +91,7 @@ export const getString = ({ valuePath }, item) => get(item, valuePath), state: this.legacyFilterToState(filter), }, bubbles: true, - }) + }), ); } @@ -135,7 +144,7 @@ export const getString = ({ valuePath }, item) => get(item, valuePath), _propertiesChanged(currentProps, changedProps, oldProps) { super._propertiesChanged(currentProps, changedProps, oldProps); this.dispatchEvent( - new CustomEvent('cosmoz-column-prop-changed', { bubbles: true }) + new CustomEvent('cosmoz-column-prop-changed', { bubbles: true }), ); } }; diff --git a/cosmoz-omnitable-item-expand-line.js b/cosmoz-omnitable-item-expand-line.js index 49d7906b..53ab2c42 100644 --- a/cosmoz-omnitable-item-expand-line.js +++ b/cosmoz-omnitable-item-expand-line.js @@ -1,33 +1,39 @@ import { component, html } from '@pionjs/pion'; +import { css, sheet } from '@neovici/cosmoz-utils'; -const OmnitableItemExpandLine = ({ column }) => html` - -
- `; + }, + ); -customElements.define('cosmoz-omnitable-item-row', component(ItemRow, { useShadowDOM: false })); +customElements.define( + 'cosmoz-omnitable-item-row', + component(ItemRow, { useShadowDOM: false }), +); diff --git a/cosmoz-omnitable-styles.js b/cosmoz-omnitable-styles.js index 08ebe94f..7968cd15 100644 --- a/cosmoz-omnitable-styles.js +++ b/cosmoz-omnitable-styles.js @@ -162,6 +162,7 @@ export default css` --cosmoz-input-padding: 0; --cosmoz-input-label-text-transform: var(--cosmoz-omnitable-header-text-transform, none); --cosmoz-input-label-font-weight: var(--cosmoz-omnitable-header-font-weight, normal); + --cosmoz-input-padding: 0; } cosmoz-omnitable-header-row { @@ -317,11 +318,6 @@ export default css` left: 0; } - .item-row-wrapper { - display: block; - width: 100%; - } - .itemRow { border-bottom-color: var(--cosmoz-omnitable-border-color, #e1e2e5); border-bottom-width: 1px; @@ -330,10 +326,12 @@ export default css` solid ); /* set a min-height for rows so that rows with empty values are visible */ - min-height: var(--item-row-min-height, 24px); - padding-right: 8px; + } + .itemRow-wrapper { display: flex; align-items: center; + min-height: var(--item-row-min-height, 39px); + padding-right: 8px; } .itemRow[selected] { @@ -357,9 +355,8 @@ export default css` background-color: #fafafa; } - cosmoz-omnitable-item-expand[hidden], cosmoz-omnitable-item-expand:not([expanded]) { - display: none !important; + display: none; } .groupRow { @@ -447,7 +444,7 @@ export default css` .itemRow:hover { box-shadow: inset 1px 0 0 #dadce0, inset -1px 0 0 #dadce0, 0 1px 2px 0 rgb(60 64 67 / 30%), 0 1px 3px 1px rgb(60 64 67 / 15%); - background: var(--cosmoz-omnitable-hover-color); + /* background: var(--cosmoz-omnitable-hover-color); */ } .groupRow:hover .checkbox:not(:checked):not(:hover), .itemRow:hover .checkbox:not(:checked):not(:hover) { @@ -530,4 +527,32 @@ export default css` min-width: 0; flex: auto; } + + :host([mini]) .itemRow .expand, + :host([mini]) cosmoz-omnitable-item-expand { + display: none; + } + + .itemRow-minis { + display: flex; + justify-content: space-between; + margin: 0 8px 8px 8px; + } + + :host([mini]) .itemRow { + border-radius: 8px; + border: 1px solid var(--cosmoz-omnitable-border-color, #e1e2e5); + margin: 4px 8px; + } + :host([mini]) .itemRow:not([selected]) { + background: var(--cosmoz-omnitable-mini-item-background, #fdfdfd); + } + + :host([mini]) .itemRow:hover { + box-shadow: none; + } + + :host([mini]) .header { + margin: 0 8px; + } `; diff --git a/cosmoz-omnitable.js b/cosmoz-omnitable.js index afb718fd..4e86310a 100644 --- a/cosmoz-omnitable.js +++ b/cosmoz-omnitable.js @@ -63,6 +63,7 @@ customElements.define( 'no-local-sort', 'no-local-filter', 'loading', + 'mini-breakpoint', ], }) { connectedCallback() { @@ -71,7 +72,7 @@ customElements.define( notifyProperty(this, 'visibleData', []); notifyProperty(this, 'sortedFilteredGroupedItems', []); } - } + }, ); const tmplt = ` diff --git a/lib/settings/style.css.js b/lib/settings/style.css.js index 9284f5b9..48ac6522 100644 --- a/lib/settings/style.css.js +++ b/lib/settings/style.css.js @@ -12,7 +12,8 @@ export default css` } .headline { - box-shadow: inset 0px -1px 0px rgba(0, 0, 0, 0.15), + box-shadow: + inset 0px -1px 0px rgba(0, 0, 0, 0.15), inset 0px 1px 0px rgba(0, 0, 0, 0.15); font-weight: 500; font-size: 16px; @@ -63,7 +64,8 @@ export default css` transform: scaleY(-1); } cosmoz-collapse[opened] + .heading { - box-shadow: inset 0px -1px 0px rgba(0, 0, 0, 0.15), + box-shadow: + inset 0px -1px 0px rgba(0, 0, 0, 0.15), inset 0px 1px 0px rgba(0, 0, 0, 0.15); } diff --git a/lib/use-canvas-width.js b/lib/use-canvas-width.js index 263d5d45..77c7c54d 100644 --- a/lib/use-canvas-width.js +++ b/lib/use-canvas-width.js @@ -1,8 +1,10 @@ import { useState } from '@pionjs/pion'; import { useTrackSize } from './use-track-size'; -export const useCanvasWidth = host => { - const [canvasWidth, setCanvasWidth] = useState(() => host.getBoundingClientRect().width); +export const useCanvasWidth = (host) => { + const [canvasWidth, setCanvasWidth] = useState( + () => host.getBoundingClientRect().width, + ); useTrackSize(host, setCanvasWidth); diff --git a/lib/use-dom-columns.js b/lib/use-dom-columns.js index 6bbc3c9f..205e10f2 100644 --- a/lib/use-dom-columns.js +++ b/lib/use-dom-columns.js @@ -88,6 +88,9 @@ const columnSymbol = Symbol('column'), noLocalFilter: column.noLocalFilter, + mini: column.mini, + renderMini: column.renderMini, + // @deprecated loading: column.loading, externalValues: column.externalValues, diff --git a/lib/use-fast-layout.js b/lib/use-fast-layout.js index dc1858c7..05fd991c 100644 --- a/lib/use-fast-layout.js +++ b/lib/use-fast-layout.js @@ -5,6 +5,7 @@ import { useCanvasWidth } from './use-canvas-width'; import { useTweenArray } from './use-tween-array'; import { useLayout } from './use-layout'; import { useStyleSheet } from '@neovici/cosmoz-utils/hooks/use-stylesheet'; +import { useMini } from './use-mini'; export const useFastLayout = ({ host, @@ -15,10 +16,12 @@ export const useFastLayout = ({ sortAndGroupOptions, }) => { const canvasWidth = useCanvasWidth(host), + { miniColumn, miniColumns } = useMini({ host, canvasWidth, columns }), { groupOnColumn } = sortAndGroupOptions, layout = useLayout({ canvasWidth, groupOnColumn, + miniColumn, config: settings.columns, }), tweenedlayout = useTweenArray(layout, resizeSpeedFactor), @@ -49,5 +52,5 @@ export const useFastLayout = ({ useStyleSheet(layoutCss); - return { collapsedColumns }; + return { collapsedColumns, miniColumns }; }; diff --git a/lib/use-layout.js b/lib/use-layout.js index 29003215..eb07d440 100644 --- a/lib/use-layout.js +++ b/lib/use-layout.js @@ -1,28 +1,32 @@ import { useMemo } from '@pionjs/pion'; import { computeLayout } from './compute-layout'; -export const useLayout = ({ canvasWidth, groupOnColumn, config }) => useMemo(() => { - if (!Array.isArray(config) || canvasWidth == null || canvasWidth === 0) { - return []; - } +export const useLayout = ({ canvasWidth, groupOnColumn, config, miniColumn }) => + useMemo(() => { + if (!Array.isArray(config) || canvasWidth == null || canvasWidth === 0) { + return []; + } - const columnConfigs = config - .map((c, index) => ({ - minWidth: c.minWidth, - width: c.width, - flex: c.flex, - priority: c.priority, - name: c.name, - index, - hidden: c.name === groupOnColumn?.name || c.disabled - })) - .sort( - ( - { index: aIndex, priority: aPriority }, - { index: bIndex, priority: bPriority } - ) => - aPriority === bPriority ? bIndex - aIndex : aPriority - bPriority - ); + const columnConfigs = config + .map((c, index) => ({ + minWidth: c.minWidth, + width: c.width, + flex: c.flex, + priority: c.priority, + name: c.name, + index, + hidden: c.name === groupOnColumn?.name || c.disabled, + })) + .map((c) => + miniColumn ? { ...c, hidden: miniColumn.name !== c.name } : c, + ) + .sort( + ( + { index: aIndex, priority: aPriority }, + { index: bIndex, priority: bPriority }, + ) => + aPriority === bPriority ? bIndex - aIndex : aPriority - bPriority, + ); - return computeLayout(columnConfigs, canvasWidth, columnConfigs.length); -}, [canvasWidth, groupOnColumn, config]); + return computeLayout(columnConfigs, canvasWidth, columnConfigs.length); + }, [canvasWidth, groupOnColumn, config]); diff --git a/lib/use-list.js b/lib/use-list.js index a57cc6fe..7488553f 100644 --- a/lib/use-list.js +++ b/lib/use-list.js @@ -1,7 +1,8 @@ /* eslint-disable max-lines-per-function */ import { html, useCallback, useEffect, useMemo, useRef } from '@pionjs/pion'; -import { indexSymbol } from './utils'; +import { when } from 'lit-html/directives/when.js'; import { isEmpty } from '@neovici/cosmoz-utils/template'; +import { indexSymbol } from './utils'; import { onItemChange as _onItemChange } from './utils-data'; const arrow = html` @@ -19,10 +20,26 @@ const arrow = html` const _getGroupRowClasses = (folded) => folded ? 'groupRow groupRow-folded' : 'groupRow'; +const renderMinis = (item) => (columns) => + when( + columns?.length > 0, + () => html` +