diff --git a/ts_web/elements/dees-table.demo.ts b/ts_web/elements/dees-table.demo.ts index c831546..28be021 100644 --- a/ts_web/elements/dees-table.demo.ts +++ b/ts_web/elements/dees-table.demo.ts @@ -1,6 +1,6 @@ import { type ITableAction } from './dees-table.js'; import * as plugins from './00plugins.js'; -import { html } from '@design.estate/dees-element'; +import { html, css, cssManager } from '@design.estate/dees-element'; interface ITableDemoData { date: string; @@ -10,120 +10,423 @@ interface ITableDemoData { export const demoFunc = () => html`
- { - return { - ...itemArg, - onlyDisplayProp: 'onlyDisplay', - }; - }} - >This is a slotted Text + { + document.body.classList.toggle('bright'); + document.body.classList.toggle('dark'); + }}>Toggle Theme + +
+
+

Basic Table with Actions

+

A standard table with row actions, editable fields, and context menu support. Double-click on descriptions to edit. Grid lines are enabled by default.

+ +
+ +
+

Table with Vertical Lines

+

Enhanced column separation for better data tracking.

+ +
+ +
+

Table with Full Grid

+

Complete grid lines for maximum readability and structure.

+ +
+ +
+

Table with Horizontal Lines Only

+

Emphasis on row separation without column dividers.

+ +
+ +
+

Simple Table (No Grid)

+

Clean, minimal design without grid lines. Set showGrid to false to disable the default grid.

+ +
+ +
+

Table with Custom Display Function

+

Transform data for display using custom formatting.

+ ({ + Product: item.product, + 'Units Sold': item.units.toLocaleString(), + Revenue: '$' + item.revenue.toLocaleString(), + Growth: (item.growth * 100).toFixed(1) + '%', + 'Q1 2024 Forecast': '$' + item.forecast.toLocaleString() + })} + dataName="products" + > +
+ +
+

Empty Table State

+

How the table looks when no data is available.

+ +
+
-`; +`; \ No newline at end of file diff --git a/ts_web/elements/dees-table.ts b/ts_web/elements/dees-table.ts index 06c56d9..4f1fe2d 100644 --- a/ts_web/elements/dees-table.ts +++ b/ts_web/elements/dees-table.ts @@ -1,4 +1,3 @@ -import * as colors from './00colors.js'; import * as plugins from './00plugins.js'; import { demoFunc } from './dees-table.demo.js'; import { cssGeistFontFamily } from './00fonts.js'; @@ -10,9 +9,6 @@ import { type TemplateResult, cssManager, css, - unsafeCSS, - type CSSResult, - state, directives, } from '@design.estate/dees-element'; @@ -114,7 +110,7 @@ export class DeesTable extends DeesElement { get value() { return this.data; } - set value(valueArg) {} + set value(_valueArg) {} public changeSubject = new domtools.plugins.smartrx.rxjs.Subject>(); // end dees-form compatibility ----------------------------------------- @@ -158,6 +154,27 @@ export class DeesTable extends DeesElement { }) public editableFields: string[] = []; + @property({ + type: Boolean, + reflect: true, + attribute: 'show-vertical-lines' + }) + public showVerticalLines: boolean = false; + + @property({ + type: Boolean, + reflect: true, + attribute: 'show-horizontal-lines' + }) + public showHorizontalLines: boolean = false; + + @property({ + type: Boolean, + reflect: true, + attribute: 'show-grid' + }) + public showGrid: boolean = true; + public files: File[] = []; public fileWeakMap = new WeakMap(); @@ -170,238 +187,350 @@ export class DeesTable extends DeesElement { public static styles = [ cssManager.defaultStyles, css` + :host { + display: block; + width: 100%; + } + .mainbox { - color: ${cssManager.bdTheme('#333', '#fff')}; + color: ${cssManager.bdTheme('hsl(0 0% 3.9%)', 'hsl(0 0% 98%)')}; font-family: ${cssGeistFontFamily}; font-weight: 400; font-size: 14px; - padding: 16px; display: block; width: 100%; - min-height: 50px; - background: ${cssManager.bdTheme('#ffffff', '#222222')}; - border-radius: 3px; - border-top: 1px solid ${cssManager.bdTheme('#fff', '#ffffff10')}; - box-shadow: 0px 1px 4px rgba(0, 0, 0, 0.3); - overflow-x: auto; + background: ${cssManager.bdTheme('hsl(0 0% 100%)', 'hsl(0 0% 3.9%)')}; + border: 1px solid ${cssManager.bdTheme('hsl(0 0% 89.8%)', 'hsl(0 0% 14.9%)')}; + border-radius: 8px; + overflow: hidden; cursor: default; } .header { display: flex; - justify-content: flex-end; + justify-content: space-between; align-items: center; - font-family: ${cssGeistFontFamily}; + padding: 16px 24px; + min-height: 64px; + border-bottom: 1px solid ${cssManager.bdTheme('hsl(0 0% 89.8%)', 'hsl(0 0% 14.9%)')}; } .headingContainer { + flex: 1; } .heading { + line-height: 1.5; } .heading1 { + font-size: 18px; font-weight: 600; + color: ${cssManager.bdTheme('hsl(0 0% 9%)', 'hsl(0 0% 95%)')}; + letter-spacing: -0.025em; } + .heading2 { - opacity: 0.6; + font-size: 14px; + color: ${cssManager.bdTheme('hsl(215.4 16.3% 56.9%)', 'hsl(215 20.2% 55.1%)')}; + margin-top: 2px; } .headingSeparation { - margin-top: 7px; - border-bottom: 1px solid ${cssManager.bdTheme('#bcbcbc', '#444444')}; + display: none; } .headerActions { user-select: none; display: flex; flex-direction: row; - margin-left: auto; + gap: 8px; } + .headerAction { display: flex; - flex-direction: row; - color: ${cssManager.bdTheme('#333', '#ccc')}; - margin-left: 16px; + align-items: center; + gap: 6px; + padding: 6px 12px; + font-size: 14px; + font-weight: 500; + color: ${cssManager.bdTheme('hsl(0 0% 45.1%)', 'hsl(0 0% 63.9%)')}; + background: transparent; + border: 1px solid ${cssManager.bdTheme('hsl(0 0% 89.8%)', 'hsl(0 0% 14.9%)')}; + border-radius: 6px; + cursor: pointer; + transition: all 0.15s ease; } .headerAction:hover { - color: ${cssManager.bdTheme('#555', '#fff')}; + color: ${cssManager.bdTheme('hsl(0 0% 9%)', 'hsl(0 0% 95%)')}; + background: ${cssManager.bdTheme('hsl(0 0% 95.1%)', 'hsl(0 0% 14.9%)')}; + border-color: ${cssManager.bdTheme('hsl(0 0% 79.8%)', 'hsl(0 0% 20.9%)')}; } .headerAction dees-icon { - margin-right: 8px; + width: 14px; + height: 14px; } .searchGrid { - background: ${cssManager.bdTheme('#fff', '#111111')}; display: grid; grid-gap: 16px; grid-template-columns: 1fr 200px; - margin-top: 16px; - padding: 0px 16px; - border-top: 1px solid ${cssManager.bdTheme('#fff', '#ffffff20')}; - border-radius: 8px; + padding: 16px 24px; + background: ${cssManager.bdTheme('hsl(210 40% 98%)', 'hsl(0 0% 3.9%)')}; + border-bottom: 1px solid ${cssManager.bdTheme('hsl(0 0% 89.8%)', 'hsl(0 0% 14.9%)')}; + transition: all 0.2s ease; } .searchGrid.hidden { height: 0px; opacity: 0; overflow: hidden; - margin-top: 0px; + padding: 0px 24px; + border-bottom-width: 0px; } - table, - .noDataSet { - margin-top: 16px; - color: ${cssManager.bdTheme('#333', '#fff')}; - border-collapse: collapse; + table { width: 100%; + caption-side: bottom; + font-size: 14px; + border-collapse: separate; + border-spacing: 0; } + .noDataSet { + padding: 48px 24px; text-align: center; + color: ${cssManager.bdTheme('hsl(215.4 16.3% 56.9%)', 'hsl(215 20.2% 55.1%)')}; } - tr { - border-bottom: 1px dashed ${cssManager.bdTheme('#999', '#808080')}; - text-align: left; + + thead { + background: ${cssManager.bdTheme('hsl(210 40% 96.1%)', 'hsl(0 0% 9%)')}; + border-bottom: 1px solid ${cssManager.bdTheme('hsl(0 0% 79.8%)', 'hsl(0 0% 20.9%)')}; } - tr:last-child { + + tbody tr { + transition: background-color 0.15s ease; + position: relative; + } + + /* Default horizontal lines (bottom border only) */ + tbody tr { + border-bottom: 1px solid ${cssManager.bdTheme('hsl(0 0% 89.8%)', 'hsl(0 0% 14.9%)')}; + } + + tbody tr:last-child { border-bottom: none; - text-align: left; } - tr:hover { + + /* Full horizontal lines when enabled */ + :host([show-horizontal-lines]) tbody tr { + border-top: 1px solid ${cssManager.bdTheme('hsl(0 0% 89.8%)', 'hsl(0 0% 14.9%)')}; + border-bottom: 1px solid ${cssManager.bdTheme('hsl(0 0% 89.8%)', 'hsl(0 0% 14.9%)')}; } - tr:hover td { - background: ${cssManager.bdTheme('#22222210', '#ffffff10')}; + + :host([show-horizontal-lines]) tbody tr:first-child { + border-top: none; } - tr:first-child:hover { - cursor: auto; + + :host([show-horizontal-lines]) tbody tr:last-child { + border-bottom: 1px solid ${cssManager.bdTheme('hsl(0 0% 89.8%)', 'hsl(0 0% 14.9%)')}; } - tr:first-child:hover .innerCellContainer { - background: none; + + tbody tr:hover { + background: ${cssManager.bdTheme('hsl(210 40% 96.1% / 0.5)', 'hsl(0 0% 14.9% / 0.5)')}; } - tr.selected td { - background: ${cssManager.bdTheme('#22222220', '#ffffff20')}; + + /* Column hover effect for better traceability */ + td { + position: relative; + } + + td::after { + content: ''; + position: absolute; + top: -1000px; + bottom: -1000px; + left: 0; + right: 0; + background: ${cssManager.bdTheme('hsl(210 40% 96.1% / 0.3)', 'hsl(0 0% 14.9% / 0.3)')}; + opacity: 0; + pointer-events: none; + transition: opacity 0.15s ease; + z-index: -1; + } + + td:hover::after { + opacity: 1; + } + + /* Grid mode - shows both vertical and horizontal lines */ + :host([show-grid]) th { + border: 1px solid ${cssManager.bdTheme('hsl(0 0% 89.8%)', 'hsl(0 0% 14.9%)')}; + border-left: none; + border-top: none; + } + + :host([show-grid]) td { + border: 1px solid ${cssManager.bdTheme('hsl(0 0% 89.8%)', 'hsl(0 0% 14.9%)')}; + border-left: none; + border-top: none; + } + + :host([show-grid]) th:first-child, + :host([show-grid]) td:first-child { + border-left: 1px solid ${cssManager.bdTheme('hsl(0 0% 89.8%)', 'hsl(0 0% 14.9%)')}; + } + + :host([show-grid]) tbody tr:first-child td { + border-top: none; + } + + tbody tr.selected { + background: ${cssManager.bdTheme('hsl(210 40% 96.1%)', 'hsl(0 0% 14.9%)')}; } - tr.hasAttachment td { - background: ${cssManager.bdTheme('#0098847c', '#0098847c')}; + tbody tr.hasAttachment { + background: ${cssManager.bdTheme('hsl(142.1 76.2% 36.3% / 0.1)', 'hsl(142.1 76.2% 36.3% / 0.1)')}; } th { - text-transform: none; - font-family: ${cssGeistFontFamily}; + height: 48px; + padding: 12px 24px; + text-align: left; font-weight: 500; + color: ${cssManager.bdTheme('hsl(215.4 16.3% 46.9%)', 'hsl(215 20.2% 65.1%)')}; + letter-spacing: -0.01em; } - th, + + :host([show-vertical-lines]) th { + border-right: 1px solid ${cssManager.bdTheme('hsl(0 0% 89.8%)', 'hsl(0 0% 14.9%)')}; + } + td { - position: relative; - vertical-align: top; - - padding: 0px; - border-right: 1px dashed ${cssManager.bdTheme('#999', '#808080')}; + padding: 12px 24px; + vertical-align: middle; + color: ${cssManager.bdTheme('hsl(0 0% 3.9%)', 'hsl(0 0% 98%)')}; } - .innerCellContainer { - min-height: 36px; - position: relative; - height: 100%; - width: 100%; - padding: 6px 8px; - line-height: 24px; + + :host([show-vertical-lines]) td { + border-right: 1px solid ${cssManager.bdTheme('hsl(0 0% 89.8%)', 'hsl(0 0% 14.9%)')}; } - th:first-child .innerCellContainer, - td:first-child .innerCellContainer { - padding-left: 0px; - } - th:last-child .innerCellContainer, - td:last-child .innerCellContainer { - padding-right: 0px; + + th:first-child, + td:first-child { + padding-left: 24px; } + th:last-child, td:last-child { + padding-right: 24px; + } + + :host([show-vertical-lines]) th:last-child, + :host([show-vertical-lines]) td:last-child { border-right: none; } + + .innerCellContainer { + position: relative; + min-height: 24px; + line-height: 24px; + } td input { - width: 100%; - height: 100%; - outline: none; - border: 2px solid #fa6101; - top: 0px; - bottom: 0px; - right: 0px; - left: 0px; position: absolute; - background: #fa610140; - color: ${cssManager.bdTheme('#333', '#fff')}; + top: 2px; + bottom: 2px; + left: 2px; + right: 2px; + width: calc(100% - 4px); + height: calc(100% - 4px); + padding: 0px 8px; + outline: none; + border: 2px solid ${cssManager.bdTheme('hsl(222.2 47.4% 51.2%)', 'hsl(217.2 91.2% 59.8%)')}; + border-radius: 4px; + background: ${cssManager.bdTheme('hsl(0 0% 100%)', 'hsl(0 0% 9%)')}; + color: ${cssManager.bdTheme('hsl(0 0% 3.9%)', 'hsl(0 0% 98%)')}; font-family: inherit; font-size: inherit; font-weight: inherit; - padding: 0px 6px; + box-shadow: 0 0 0 3px ${cssManager.bdTheme('hsl(222.2 47.4% 51.2% / 0.1)', 'hsl(217.2 91.2% 59.8% / 0.1)')}; } .actionsContainer { display: flex; flex-direction: row; - height: 24px; - transform: translateY(-4px); - margin-left: -6px; + gap: 4px; } + .action { - position: relative; - padding: 8px 10px; - line-height: 24px; + display: flex; + align-items: center; + justify-content: center; + width: 32px; height: 32px; - size: 16px; - border-radius: 8px; + border-radius: 6px; + color: ${cssManager.bdTheme('hsl(215.4 16.3% 46.9%)', 'hsl(215 20.2% 65.1%)')}; + cursor: pointer; + transition: all 0.15s ease; } .action:hover { - background: ${cssManager.bdTheme(colors.bright.blue, colors.dark.blue)}; + background: ${cssManager.bdTheme('hsl(210 40% 96.1%)', 'hsl(0 0% 14.9%)')}; + color: ${cssManager.bdTheme('hsl(0 0% 9%)', 'hsl(0 0% 95%)')}; } .action:active { - background: ${cssManager.bdTheme(colors.bright.blue, colors.dark.blueActive)}; + background: ${cssManager.bdTheme('hsl(210 40% 96.1%)', 'hsl(0 0% 11.8%)')}; } - - .action:hover dees-icon { - filter: ${cssManager.bdTheme('invert(1) brightness(3)', '')}; + + .action dees-icon { + width: 16px; + height: 16px; } .footer { - font-family: ${cssGeistFontFamily}; - font-size: 14px; - color: ${cssManager.bdTheme('#111', '#ffffff90')}; - background: ${cssManager.bdTheme('#eeeeeb', '#00000050')}; - margin: 16px -16px -16px -16px; - border-bottom-left-radius: 3px; - border-bottom-right-radius: 3px; display: flex; + align-items: center; + justify-content: space-between; + height: 52px; + padding: 0 24px; + font-size: 14px; + color: ${cssManager.bdTheme('hsl(215.4 16.3% 46.9%)', 'hsl(215 20.2% 65.1%)')}; + background: ${cssManager.bdTheme('hsl(210 40% 96.1%)', 'hsl(0 0% 9%)')}; + border-top: 1px solid ${cssManager.bdTheme('hsl(0 0% 89.8%)', 'hsl(0 0% 14.9%)')}; } .tableStatistics { - padding: 8px 16px; + font-weight: 500; } .footerActions { - margin-left: auto; + display: flex; + gap: 8px; } .footerActions .footerAction { - padding: 8px 16px; display: flex; + align-items: center; + gap: 6px; + padding: 6px 12px; + font-weight: 500; + color: ${cssManager.bdTheme('hsl(215.4 16.3% 46.9%)', 'hsl(215 20.2% 65.1%)')}; + border-radius: 6px; + cursor: pointer; user-select: none; + transition: all 0.15s ease; } .footerActions .footerAction:hover { - background: ${cssManager.bdTheme(colors.bright.blue, colors.dark.blue)}; - color: #fff; + background: ${cssManager.bdTheme('hsl(0 0% 95.1%)', 'hsl(0 0% 14.9%)')}; + color: ${cssManager.bdTheme('hsl(0 0% 9%)', 'hsl(0 0% 95%)')}; } .footerActions .footerAction dees-icon { - display: flex; - margin-right: 8px; - } - - .footerActions .footerAction:hover dees-icon { + width: 14px; + height: 14px; } `, ]; @@ -479,24 +608,23 @@ export class DeesTable extends DeesElement { const headings: string[] = Object.keys(firstTransformedItem); return html` - - ${headings.map( - (headingArg) => html` - - ` - )} - ${(() => { - if (this.dataActions && this.dataActions.length > 0) { - return html` - - `; - } - })()} - + + + ${headings.map( + (headingArg) => html` + + ` + )} + ${(() => { + if (this.dataActions && this.dataActions.length > 0) { + return html` + + `; + } + })()} + + + ${this.data.map((itemArg) => { const transformedItem = this.displayFunction(itemArg); const getTr = (elementArg: HTMLElement): HTMLElement => { @@ -593,10 +721,9 @@ export class DeesTable extends DeesElement { if (this.dataActions && this.dataActions.length > 0) { return html` `; @@ -624,6 +750,7 @@ export class DeesTable extends DeesElement { `; })} +
-
${headingArg}
-
-
Actions
-
${headingArg}Actions
-
-
- ${this.getActionsForType('inRow').map( - (actionArg) => html` +
+ ${this.getActionsForType('inRow').map( + (actionArg) => html`
@@ -615,7 +742,6 @@ export class DeesTable extends DeesElement {
` )} -
`; })() @@ -744,7 +871,7 @@ export class DeesTable extends DeesElement { } async handleCellEditing(event: Event, itemArg: T, key: string) { - const domtools = await this.domtoolsPromise; + await this.domtoolsPromise; const target = event.target as HTMLElement; const originalColor = target.style.color; target.style.color = 'transparent';