@keenmate/web-grid 1.0.0-rc02

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +243 -0
  3. package/component-variables.manifest.json +192 -0
  4. package/dist/grid.d.ts +319 -0
  5. package/dist/index.d.ts +4 -0
  6. package/dist/modules/contextmenu/index.d.ts +10 -0
  7. package/dist/modules/datepicker/datepicker.d.ts +79 -0
  8. package/dist/modules/datepicker/formatting.d.ts +44 -0
  9. package/dist/modules/datepicker/index.d.ts +4 -0
  10. package/dist/modules/datepicker/interaction.d.ts +39 -0
  11. package/dist/modules/datepicker/navigation.d.ts +37 -0
  12. package/dist/modules/datepicker/rendering.d.ts +56 -0
  13. package/dist/modules/datepicker/types.d.ts +62 -0
  14. package/dist/modules/dropdown/index.d.ts +4 -0
  15. package/dist/modules/dropdown/input-handlers.d.ts +14 -0
  16. package/dist/modules/dropdown/interaction.d.ts +34 -0
  17. package/dist/modules/dropdown/options.d.ts +33 -0
  18. package/dist/modules/dropdown/rendering.d.ts +11 -0
  19. package/dist/modules/editing/index.d.ts +2 -0
  20. package/dist/modules/editing/lifecycle.d.ts +25 -0
  21. package/dist/modules/editing/renderers.d.ts +39 -0
  22. package/dist/modules/navigation/focus.d.ts +46 -0
  23. package/dist/modules/navigation/index.d.ts +1 -0
  24. package/dist/modules/rendering/display.d.ts +7 -0
  25. package/dist/modules/rendering/index.d.ts +3 -0
  26. package/dist/modules/rendering/table.d.ts +39 -0
  27. package/dist/modules/toolbar/index.d.ts +55 -0
  28. package/dist/modules/tooltip/index.d.ts +1 -0
  29. package/dist/modules/tooltip/tooltip.d.ts +13 -0
  30. package/dist/modules/types.d.ts +32 -0
  31. package/dist/types.d.ts +311 -0
  32. package/dist/web-component.d.ts +277 -0
  33. package/dist/web-grid.js +5370 -0
  34. package/dist/web-grid.umd.js +618 -0
  35. package/package.json +78 -0
  36. package/src/css/_cells.css +77 -0
  37. package/src/css/_dark-mode.css +51 -0
  38. package/src/css/_dialogs.css +121 -0
  39. package/src/css/_dropdown.css +193 -0
  40. package/src/css/_editors.css +184 -0
  41. package/src/css/_header.css +105 -0
  42. package/src/css/_modifiers.css +36 -0
  43. package/src/css/_navigation.css +25 -0
  44. package/src/css/_pagination.css +156 -0
  45. package/src/css/_table.css +90 -0
  46. package/src/css/_toolbar.css +139 -0
  47. package/src/css/_variables.css +265 -0
  48. package/src/css/_virtual-scroll.css +24 -0
  49. package/src/css/main.css +35 -0
@@ -0,0 +1,105 @@
1
+ /* ==============================================================================
2
+ HEADER
3
+ ==============================================================================
4
+ Table header, sorting indicators, and filter row
5
+ */
6
+
7
+ .wg__header {
8
+ position: sticky;
9
+ top: 0;
10
+ z-index: 1;
11
+ background: var(--wg-header-bg);
12
+ color: var(--wg-header-color);
13
+ font-weight: var(--wg-header-font-weight);
14
+ padding: var(--wg-header-padding);
15
+ border-bottom: var(--wg-header-border);
16
+ text-align: left;
17
+ user-select: none;
18
+ }
19
+
20
+ .wg__header--sortable {
21
+ cursor: pointer;
22
+ }
23
+
24
+ .wg__header--sortable:hover {
25
+ background: var(--wg-header-bg-hover);
26
+ }
27
+
28
+ .wg__header--sorted {
29
+ background: var(--wg-header-bg-sorted);
30
+ }
31
+
32
+ /* Header Content Layout */
33
+ .wg__header-content {
34
+ display: flex;
35
+ align-items: center;
36
+ gap: 4px;
37
+ justify-content: space-between;
38
+ }
39
+
40
+ .wg__header-title {
41
+ flex: 1;
42
+ }
43
+
44
+ /* Sort Indicator */
45
+ .wg__sort-indicator {
46
+ font-size: var(--wg-sort-indicator-size);
47
+ opacity: var(--wg-sort-indicator-opacity);
48
+ min-width: 16px;
49
+ text-align: center;
50
+ display: inline-flex;
51
+ align-items: center;
52
+ }
53
+
54
+ .wg__sort-placeholder {
55
+ opacity: var(--wg-sort-placeholder-opacity);
56
+ }
57
+
58
+ .wg__sort-priority {
59
+ font-size: var(--wg-sort-priority-size);
60
+ font-weight: 600;
61
+ margin-left: 2px;
62
+ vertical-align: super;
63
+ line-height: 1;
64
+ }
65
+
66
+ /* Header Info Icon */
67
+ .wg__header-info {
68
+ display: inline-flex;
69
+ align-items: center;
70
+ color: var(--wg-accent-color);
71
+ cursor: help;
72
+ opacity: 0.7;
73
+ margin-left: 4px;
74
+ vertical-align: middle;
75
+ }
76
+
77
+ .wg__header-info:hover {
78
+ opacity: 1;
79
+ }
80
+
81
+ /* ==============================================================================
82
+ FILTER ROW
83
+ ============================================================================== */
84
+ .wg__filter-row th {
85
+ padding: var(--wg-filter-padding);
86
+ background: var(--wg-filter-bg);
87
+ border-bottom: var(--wg-filter-border);
88
+ }
89
+
90
+ .wg__filter-input {
91
+ width: 100%;
92
+ padding: var(--wg-filter-input-padding);
93
+ border: var(--wg-filter-input-border);
94
+ border-radius: var(--wg-filter-input-border-radius);
95
+ background: var(--wg-surface-1);
96
+ color: var(--wg-text-color-1);
97
+ font-size: var(--wg-filter-input-font-size);
98
+ box-sizing: border-box;
99
+ }
100
+
101
+ .wg__filter-input:focus {
102
+ outline: none;
103
+ border: var(--wg-filter-input-border-focus);
104
+ box-shadow: 0 0 0 1px var(--wg-accent-color);
105
+ }
@@ -0,0 +1,36 @@
1
+ /* ==============================================================================
2
+ MODIFIERS
3
+ ==============================================================================
4
+ Table style modifiers: striped rows, hoverable rows, empty state
5
+ */
6
+
7
+ /* Striped rows */
8
+ .wg--striped tbody tr:nth-child(even) {
9
+ background: var(--wg-row-bg-even);
10
+ }
11
+
12
+ /* Hoverable rows */
13
+ .wg--hoverable tbody tr:hover {
14
+ background: var(--wg-row-bg-hover);
15
+ }
16
+
17
+ /* ==============================================================================
18
+ EMPTY STATE
19
+ ============================================================================== */
20
+ .wg__empty {
21
+ text-align: center;
22
+ padding: var(--wg-empty-padding);
23
+ color: var(--wg-empty-color);
24
+ font-style: italic;
25
+ }
26
+
27
+ /* ==============================================================================
28
+ LOADING STATE
29
+ ============================================================================== */
30
+ /* Loading indicator at the bottom (optional - consumer can style their own) */
31
+ .wg__loading-more {
32
+ text-align: center;
33
+ padding: var(--wg-cell-padding);
34
+ color: var(--wg-text-color-2);
35
+ font-size: var(--wg-font-size-sm);
36
+ }
@@ -0,0 +1,25 @@
1
+ /* ==============================================================================
2
+ NAVIGATE MODE (keyboard navigation)
3
+ ==============================================================================
4
+ Excel-like keyboard navigation and focus states
5
+ */
6
+
7
+ .wg--navigate-mode .wg__cell {
8
+ cursor: cell;
9
+ }
10
+
11
+ /* Remove browser default focus outline - we handle it with .wg__cell--focused */
12
+ .wg--navigate-mode .wg__cell:focus {
13
+ outline: none;
14
+ }
15
+
16
+ /* Focused cell styling - Excel-like green border for ALL cells */
17
+ .wg--navigate-mode .wg__cell.wg__cell--focused {
18
+ outline: 2px solid var(--wg-focus-border-color, #217346);
19
+ outline-offset: -2px;
20
+ }
21
+
22
+ /* Hide hover border when cell is focused */
23
+ .wg__cell--focused::after {
24
+ display: none;
25
+ }
@@ -0,0 +1,156 @@
1
+ /* ==============================================================================
2
+ PAGINATION
3
+ ==============================================================================
4
+ Pagination controls, summary, and footer wrapper
5
+ */
6
+
7
+ .wg__pagination {
8
+ display: flex;
9
+ align-items: center;
10
+ justify-content: center;
11
+ gap: var(--wg-pagination-gap);
12
+ padding: var(--wg-pagination-padding);
13
+ border-top: var(--wg-pagination-border);
14
+ background: var(--wg-pagination-bg);
15
+ }
16
+
17
+ .wg__pagination-btn {
18
+ padding: var(--wg-pagination-btn-padding);
19
+ background: var(--wg-pagination-btn-bg);
20
+ border: var(--wg-pagination-btn-border);
21
+ border-radius: var(--wg-pagination-btn-border-radius);
22
+ color: var(--wg-cell-color);
23
+ font-size: var(--wg-font-size-base);
24
+ cursor: pointer;
25
+ transition: all var(--wg-transition-fast);
26
+ }
27
+
28
+ .wg__pagination-btn:hover:not(:disabled) {
29
+ background: var(--wg-pagination-btn-bg-hover);
30
+ border: var(--wg-pagination-btn-border-hover);
31
+ }
32
+
33
+ .wg__pagination-btn:active:not(:disabled) {
34
+ background: var(--wg-pagination-btn-bg-active);
35
+ }
36
+
37
+ .wg__pagination-btn:disabled {
38
+ opacity: var(--wg-pagination-btn-disabled-opacity);
39
+ cursor: not-allowed;
40
+ }
41
+
42
+ .wg__pagination-info {
43
+ font-size: var(--wg-font-size-base);
44
+ color: var(--wg-cell-color);
45
+ }
46
+
47
+ .wg__pagination-count {
48
+ font-size: var(--wg-font-size-sm);
49
+ color: var(--wg-text-color-3);
50
+ margin-left: 4px;
51
+ }
52
+
53
+ .wg__pagination-pagesize {
54
+ display: flex;
55
+ align-items: center;
56
+ gap: 6px;
57
+ }
58
+
59
+ .wg__pagination-select {
60
+ padding: 4px 8px;
61
+ background: var(--wg-pagination-btn-bg);
62
+ border: var(--wg-pagination-btn-border);
63
+ border-radius: var(--wg-pagination-btn-border-radius);
64
+ color: var(--wg-cell-color);
65
+ font-size: var(--wg-font-size-base);
66
+ cursor: pointer;
67
+ }
68
+
69
+ .wg__pagination-select:hover {
70
+ background: var(--wg-pagination-btn-bg-hover);
71
+ border: var(--wg-pagination-btn-border-hover);
72
+ }
73
+
74
+ .wg__pagination-select:focus {
75
+ outline: 2px solid var(--wg-accent-color);
76
+ outline-offset: -2px;
77
+ }
78
+
79
+ .wg__pagination-label {
80
+ font-size: var(--wg-font-size-sm);
81
+ color: var(--wg-text-color-3);
82
+ }
83
+
84
+ /* Pagination alignment modifiers */
85
+ .wg__pagination--left {
86
+ justify-content: flex-start;
87
+ }
88
+
89
+ .wg__pagination--right {
90
+ justify-content: flex-end;
91
+ }
92
+
93
+ /* Top pagination: border on bottom instead of top */
94
+ .wg__pagination--top {
95
+ border-top: none;
96
+ border-bottom: var(--wg-pagination-border);
97
+ }
98
+
99
+ /* ==============================================================================
100
+ SUMMARY
101
+ ============================================================================== */
102
+ .wg__summary {
103
+ display: flex;
104
+ align-items: center;
105
+ padding: var(--wg-pagination-padding);
106
+ border-top: var(--wg-pagination-border);
107
+ background: var(--wg-pagination-bg);
108
+ font-size: var(--wg-font-size-base);
109
+ color: var(--wg-cell-color);
110
+ }
111
+
112
+ .wg__summary--left {
113
+ justify-content: flex-start;
114
+ }
115
+
116
+ .wg__summary--right {
117
+ justify-content: flex-end;
118
+ }
119
+
120
+ .wg__summary--top {
121
+ border-top: none;
122
+ border-bottom: var(--wg-pagination-border);
123
+ }
124
+
125
+ /* ==============================================================================
126
+ FOOTER (wrapper for summary + pagination at same position)
127
+ ============================================================================== */
128
+ .wg__footer {
129
+ display: flex;
130
+ align-items: center;
131
+ justify-content: space-between;
132
+ border-top: var(--wg-pagination-border);
133
+ background: var(--wg-pagination-bg);
134
+ }
135
+
136
+ .wg__footer--top {
137
+ border-top: none;
138
+ border-bottom: var(--wg-pagination-border);
139
+ }
140
+
141
+ /* When inside footer, remove individual borders */
142
+ .wg__footer .wg__summary,
143
+ .wg__footer .wg__pagination {
144
+ border: none;
145
+ }
146
+
147
+ /* Summary is on left in footer */
148
+ .wg__footer .wg__summary {
149
+ flex: 0 0 auto;
150
+ }
151
+
152
+ /* Pagination aligns to right in footer */
153
+ .wg__footer .wg__pagination {
154
+ flex: 0 0 auto;
155
+ margin-left: auto;
156
+ }
@@ -0,0 +1,90 @@
1
+ /* ==============================================================================
2
+ TABLE STRUCTURE
3
+ ==============================================================================
4
+ Core table container and layout
5
+ */
6
+
7
+ /* ==============================================================================
8
+ FOUC PREVENTION
9
+ ==============================================================================
10
+ Prevent Flash of Unstyled Content by hiding undefined custom elements
11
+ Keep element visible to prevent layout shift, but hide any text content
12
+ */
13
+ web-grid:not(:defined) {
14
+ display: block;
15
+ min-height: calc(10 * var(--wg-rem));
16
+ color: transparent !important;
17
+ background: transparent;
18
+ }
19
+
20
+ /* ==============================================================================
21
+ CONTAINER
22
+ ============================================================================== */
23
+ .wg {
24
+ position: relative;
25
+ width: 100%;
26
+ max-height: inherit;
27
+ overflow: auto;
28
+ overscroll-behavior: contain;
29
+ border: var(--wg-table-border);
30
+ }
31
+
32
+ /* ==============================================================================
33
+ TABLE
34
+ ============================================================================== */
35
+ .wg__table {
36
+ width: max-content;
37
+ min-width: 100%;
38
+ border-collapse: collapse;
39
+ table-layout: fixed;
40
+ background: var(--wg-table-bg);
41
+ font-size: var(--wg-font-size-base);
42
+ line-height: var(--wg-line-height-base);
43
+ }
44
+
45
+ /* ==============================================================================
46
+ ROWS
47
+ ============================================================================== */
48
+ .wg__table tbody tr {
49
+ border-bottom: var(--wg-row-border);
50
+ }
51
+
52
+ /* ==============================================================================
53
+ ROW NUMBER COLUMN
54
+ ============================================================================== */
55
+ .wg__row-number-header,
56
+ .wg__row-number {
57
+ width: 40px;
58
+ min-width: 40px;
59
+ max-width: 40px;
60
+ text-align: center;
61
+ color: var(--wg-text-color-secondary);
62
+ background: var(--wg-header-bg);
63
+ user-select: none;
64
+ font-size: var(--wg-font-size-sm);
65
+ }
66
+
67
+ .wg__row-number {
68
+ border-right: var(--wg-cell-border);
69
+ }
70
+
71
+ /* ==============================================================================
72
+ ACTIONS COLUMN (for button trigger mode)
73
+ ============================================================================== */
74
+ .wg__actions-column {
75
+ width: 32px;
76
+ min-width: 32px;
77
+ max-width: 32px;
78
+ padding: 0 !important;
79
+ text-align: center;
80
+ }
81
+
82
+ thead .wg__actions-column {
83
+ background: var(--wg-header-bg);
84
+ border-bottom: var(--wg-header-border);
85
+ }
86
+
87
+ .wg__filter-row .wg__actions-column {
88
+ background: var(--wg-filter-bg);
89
+ border-bottom: var(--wg-filter-border);
90
+ }
@@ -0,0 +1,139 @@
1
+ /* ==============================================================================
2
+ ROW TOOLBAR STYLES
3
+ Floating row action toolbar
4
+ ============================================================================== */
5
+
6
+ .wg__toolbar-container {
7
+ position: fixed;
8
+ z-index: var(--wg-z-toolbar, 1000);
9
+ }
10
+
11
+ .wg__toolbar {
12
+ display: flex;
13
+ flex-direction: column-reverse;
14
+ gap: 0;
15
+ padding: 0;
16
+ background: var(--wg-toolbar-bg);
17
+ border: var(--wg-toolbar-border);
18
+ border-radius: var(--wg-toolbar-border-radius);
19
+ box-shadow: var(--wg-toolbar-shadow);
20
+ }
21
+
22
+ .wg__toolbar-row {
23
+ display: flex;
24
+ gap: 2px;
25
+ align-items: center;
26
+ /* Match grid row height: vertical padding (design-unit * 2 * 2) + line-height (~21px) */
27
+ height: calc(var(--wg-design-unit, 4) * 4px + 21px);
28
+ padding: 0 4px;
29
+ }
30
+
31
+ .wg__toolbar-row + .wg__toolbar-row {
32
+ border-top: 1px solid var(--wg-toolbar-divider-color);
33
+ }
34
+
35
+ .wg__toolbar-divider {
36
+ width: 1px;
37
+ height: 16px;
38
+ background: var(--wg-toolbar-divider-color);
39
+ margin: 0 4px;
40
+ flex-shrink: 0;
41
+ }
42
+
43
+ .wg__toolbar-btn {
44
+ min-width: var(--wg-toolbar-btn-min-width);
45
+ height: 100%;
46
+ border: none;
47
+ border-radius: var(--wg-toolbar-btn-border-radius);
48
+ background: transparent;
49
+ color: var(--wg-toolbar-btn-color);
50
+ cursor: pointer;
51
+ display: flex;
52
+ align-items: center;
53
+ justify-content: center;
54
+ gap: 4px;
55
+ font-size: var(--wg-font-size-base);
56
+ font-weight: 500;
57
+ padding: var(--wg-toolbar-btn-padding);
58
+ transition: background 0.1s ease;
59
+ }
60
+
61
+ .wg__toolbar-btn:hover {
62
+ background: var(--wg-toolbar-btn-bg-hover);
63
+ }
64
+
65
+ .wg__toolbar-btn:active {
66
+ background: var(--wg-toolbar-btn-bg-active);
67
+ }
68
+
69
+ .wg__toolbar-btn:disabled {
70
+ opacity: 0.5;
71
+ cursor: not-allowed;
72
+ }
73
+
74
+ .wg__toolbar-btn:disabled:hover {
75
+ background: transparent;
76
+ }
77
+
78
+ .wg__toolbar-btn--danger:hover {
79
+ background: var(--wg-danger-bg-light);
80
+ color: var(--wg-danger-color);
81
+ }
82
+
83
+ .wg__toolbar-label {
84
+ font-size: 12px;
85
+ white-space: nowrap;
86
+ }
87
+
88
+ /* ==========================================================================
89
+ ACTIONS COLUMN (for button trigger mode)
90
+ ========================================================================== */
91
+
92
+ .wg__actions-column {
93
+ width: 24px;
94
+ min-width: 24px;
95
+ max-width: 24px;
96
+ padding: 0 !important;
97
+ text-align: center;
98
+ }
99
+
100
+ .wg__header .wg__actions-column {
101
+ background: var(--wg-header-bg);
102
+ }
103
+
104
+ .wg__filter-row .wg__actions-column {
105
+ background: var(--wg-filter-bg);
106
+ }
107
+
108
+ /* ==========================================================================
109
+ TOOLBAR TRIGGER BUTTON (in each row for button mode)
110
+ ========================================================================== */
111
+
112
+ .wg__toolbar-trigger {
113
+ position: relative;
114
+ padding: 0;
115
+ background: transparent;
116
+ border: none;
117
+ border-radius: var(--wg-border-radius-sm);
118
+ cursor: pointer;
119
+ font-size: var(--wg-font-size-base);
120
+ line-height: 1;
121
+ color: var(--wg-toolbar-trigger-color);
122
+ }
123
+
124
+ /* Larger invisible hitbox for easier clicking */
125
+ .wg__toolbar-trigger::before {
126
+ content: "";
127
+ position: absolute;
128
+ top: 50%;
129
+ left: 50%;
130
+ transform: translate(-50%, -50%);
131
+ width: var(--wg-dropdown-toggle-hitbox);
132
+ height: 48px;
133
+ }
134
+
135
+ .wg__toolbar-trigger:hover,
136
+ .wg__toolbar-trigger--active {
137
+ color: var(--wg-toolbar-trigger-color-hover);
138
+ background: var(--wg-toolbar-trigger-bg-hover);
139
+ }