@operato/data-grist 2.0.0-beta.3 → 2.0.0-beta.31

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 (78) hide show
  1. package/.storybook/preview.js +29 -0
  2. package/CHANGELOG.md +202 -0
  3. package/dist/src/data-card/data-card-gutter-menu.js +2 -0
  4. package/dist/src/data-card/data-card-gutter-menu.js.map +1 -1
  5. package/dist/src/data-card/record-card.js +4 -4
  6. package/dist/src/data-card/record-card.js.map +1 -1
  7. package/dist/src/data-grid/data-grid-body.js +3 -0
  8. package/dist/src/data-grid/data-grid-body.js.map +1 -1
  9. package/dist/src/data-grid/data-grid-field.d.ts +1 -0
  10. package/dist/src/data-grid/data-grid-field.js +2 -0
  11. package/dist/src/data-grid/data-grid-field.js.map +1 -1
  12. package/dist/src/data-grid/data-grid-header.d.ts +1 -0
  13. package/dist/src/data-grid/data-grid-header.js +3 -11
  14. package/dist/src/data-grid/data-grid-header.js.map +1 -1
  15. package/dist/src/data-grist.js +1 -1
  16. package/dist/src/data-grist.js.map +1 -1
  17. package/dist/src/data-list/record-partial.js +4 -4
  18. package/dist/src/data-list/record-partial.js.map +1 -1
  19. package/dist/src/editors/ox-grist-editor-date.js +1 -1
  20. package/dist/src/editors/ox-grist-editor-date.js.map +1 -1
  21. package/dist/src/editors/ox-grist-editor-datetime.js +1 -1
  22. package/dist/src/editors/ox-grist-editor-datetime.js.map +1 -1
  23. package/dist/src/filters/filter-checkbox.js +1 -1
  24. package/dist/src/filters/filter-checkbox.js.map +1 -1
  25. package/dist/src/personalizer/ox-grist-filter-personalizer.js +1 -1
  26. package/dist/src/personalizer/ox-grist-filter-personalizer.js.map +1 -1
  27. package/dist/src/personalizer/ox-grist-personalizer.js +42 -11
  28. package/dist/src/personalizer/ox-grist-personalizer.js.map +1 -1
  29. package/dist/src/record-view/record-creator.d.ts +1 -0
  30. package/dist/src/record-view/record-creator.js +6 -1
  31. package/dist/src/record-view/record-creator.js.map +1 -1
  32. package/dist/src/record-view/record-view-body.js +14 -2
  33. package/dist/src/record-view/record-view-body.js.map +1 -1
  34. package/dist/src/record-view/record-view.js +2 -3
  35. package/dist/src/record-view/record-view.js.map +1 -1
  36. package/dist/src/renderers/ox-grist-renderer-json5.js +3 -0
  37. package/dist/src/renderers/ox-grist-renderer-json5.js.map +1 -1
  38. package/dist/src/renderers/ox-grist-renderer-text.js +2 -12
  39. package/dist/src/renderers/ox-grist-renderer-text.js.map +1 -1
  40. package/dist/stories/click-event.stories.d.ts +9 -0
  41. package/dist/stories/click-event.stories.js +22 -8
  42. package/dist/stories/click-event.stories.js.map +1 -1
  43. package/dist/stories/creatable-only-column.stories.d.ts +4 -0
  44. package/dist/stories/creatable-only-column.stories.js +3 -2
  45. package/dist/stories/creatable-only-column.stories.js.map +1 -1
  46. package/dist/stories/dynamic-editable.stories.js +36 -0
  47. package/dist/stories/dynamic-editable.stories.js.map +1 -1
  48. package/dist/stories/grid-setting.stories.js +6 -1
  49. package/dist/stories/grid-setting.stories.js.map +1 -1
  50. package/dist/tsconfig.tsbuildinfo +1 -1
  51. package/package.json +13 -11
  52. package/src/data-card/data-card-gutter-menu.ts +2 -0
  53. package/src/data-card/record-card.ts +4 -4
  54. package/src/data-grid/data-grid-body.ts +4 -0
  55. package/src/data-grid/data-grid-field.ts +3 -1
  56. package/src/data-grid/data-grid-header.ts +4 -12
  57. package/src/data-grist.ts +1 -1
  58. package/src/data-list/record-partial.ts +4 -4
  59. package/src/editors/ox-grist-editor-date.ts +1 -1
  60. package/src/editors/ox-grist-editor-datetime.ts +1 -1
  61. package/src/filters/filter-checkbox.ts +1 -1
  62. package/src/personalizer/ox-grist-filter-personalizer.ts +1 -1
  63. package/src/personalizer/ox-grist-personalizer.ts +42 -11
  64. package/src/record-view/record-creator.ts +3 -1
  65. package/src/record-view/record-view-body.ts +14 -2
  66. package/src/record-view/record-view.ts +2 -3
  67. package/src/renderers/ox-grist-renderer-json5.ts +4 -0
  68. package/src/renderers/ox-grist-renderer-text.ts +2 -14
  69. package/stories/click-event.stories.ts +43 -22
  70. package/stories/creatable-only-column.stories.ts +4 -2
  71. package/stories/dynamic-editable.stories.ts +36 -0
  72. package/stories/grid-setting.stories.ts +6 -1
  73. package/themes/grist-theme.css +4 -0
  74. package/translations/en.json +3 -0
  75. package/translations/ja.json +2 -0
  76. package/translations/ko.json +2 -0
  77. package/translations/ms.json +2 -0
  78. package/translations/zh.json +2 -0
package/package.json CHANGED
@@ -1,11 +1,12 @@
1
1
  {
2
2
  "name": "@operato/data-grist",
3
- "version": "2.0.0-beta.3",
3
+ "version": "2.0.0-beta.31",
4
4
  "description": "User interface for grid (desktop) and list (mobile)",
5
5
  "author": "heartyoh",
6
6
  "main": "dist/index.js",
7
7
  "module": "dist/index.js",
8
8
  "license": "MIT",
9
+ "operato": true,
9
10
  "publishConfig": {
10
11
  "access": "public",
11
12
  "@operato:registry": "https://registry.npmjs.org"
@@ -17,6 +18,7 @@
17
18
  },
18
19
  "exports": {
19
20
  ".": "./dist/src/index.js",
21
+ "./package.json": "./package.json",
20
22
  "./ox-grist.js": "./dist/src/data-grist.js",
21
23
  "./ox-report.js": "./dist/src/data-report.js",
22
24
  "./ox-filters-form.js": "./dist/src/filters/filters-form.js",
@@ -59,16 +61,16 @@
59
61
  "storybook:build": "tsc && build-storybook"
60
62
  },
61
63
  "dependencies": {
62
- "@material/web": "^1.4.0",
63
- "@operato/headroom": "^2.0.0-beta.0",
64
- "@operato/input": "^2.0.0-beta.3",
65
- "@operato/p13n": "^2.0.0-beta.3",
66
- "@operato/popup": "^2.0.0-beta.0",
67
- "@operato/pull-to-refresh": "^2.0.0-beta.0",
68
- "@operato/styles": "^2.0.0-beta.0",
64
+ "@material/web": "^1.5.0",
65
+ "@operato/headroom": "^2.0.0-beta.23",
66
+ "@operato/input": "^2.0.0-beta.31",
67
+ "@operato/p13n": "^2.0.0-beta.31",
68
+ "@operato/popup": "^2.0.0-beta.31",
69
+ "@operato/pull-to-refresh": "^2.0.0-beta.23",
70
+ "@operato/styles": "^2.0.0-beta.23",
69
71
  "@operato/time-calculator": "^2.0.0-beta.0",
70
- "@operato/utils": "^2.0.0-beta.0",
71
- "i18next": "^21.5.4",
72
+ "@operato/utils": "^2.0.0-beta.23",
73
+ "i18next": "^21.6.3",
72
74
  "json5": "^2.2.0",
73
75
  "lit": "^3.1.2",
74
76
  "lodash-es": "^4.17.21"
@@ -106,5 +108,5 @@
106
108
  "prettier --write"
107
109
  ]
108
110
  },
109
- "gitHead": "f784d266745412a10887dd5163da8c8d7a4fe423"
111
+ "gitHead": "beb2772f3deb798c8b875a4dc0967fb47ca5390a"
110
112
  }
@@ -26,6 +26,8 @@ class DataCardGutterMenu extends LitElement {
26
26
  border-radius: var(--data-card-item-btn-border-radius);
27
27
  padding: var(--data-card-item-btn-padding);
28
28
  font-size: var(--md-sys-typescale-label-large-size, 0.875rem);
29
+ background-color: transparent;
30
+ color: var(--grid-record-color);
29
31
  }
30
32
 
31
33
  md-icon:hover {
@@ -59,7 +59,7 @@ export class RecordCard extends LitElement {
59
59
  text-indent: 1px;
60
60
  left: var(--spacing-none);
61
61
  top: var(--spacing-none);
62
- color: var(--grid-record-dirty-color);
62
+ color: var(--grid-record-dirty-color, var(--md-sys-color-error));
63
63
  }
64
64
 
65
65
  [thumbnail] {
@@ -102,17 +102,17 @@ export class RecordCard extends LitElement {
102
102
 
103
103
  ox-card-field {
104
104
  font: var(--data-card-item-etc-font);
105
- color: var(--data-card-item-etc-color);
105
+ color: var(--data-card-item-etc-color, var(--md-sys-color-on-surface));
106
106
  }
107
107
 
108
108
  ox-card-field[name] {
109
109
  font: var(--data-card-item-name-font);
110
- color: var(--data-card-item-name-color);
110
+ color: var(--data-card-item-name-color, var(--md-sys-color-secondary));
111
111
  }
112
112
 
113
113
  ox-card-field[desc] {
114
114
  font: var(--data-card-item-disc-font);
115
- color: var(--data-card-item-disc-color);
115
+ color: var(--data-card-item-disc-color, var(--md-sys-color-tertiary));
116
116
  }
117
117
  `
118
118
  ]
@@ -545,6 +545,10 @@ export class DataGridBody extends LitElement {
545
545
  const opacity = selectBlock.style.opacity
546
546
 
547
547
  selectBlock.setAttribute('data-tooltip', 'copied to clipboard!')
548
+ const rect = selectBlock.getBoundingClientRect()
549
+ selectBlock.style.setProperty('--tooltip-top', `${rect.top}px`)
550
+ selectBlock.style.setProperty('--tooltip-left', `${rect.left}px`)
551
+
548
552
  selectBlock.style.backgroundColor = 'red'
549
553
  selectBlock.style.opacity = '0.5'
550
554
  await sleep(500)
@@ -3,10 +3,10 @@ import { css, html, LitElement, PropertyValues, TemplateResult } from 'lit'
3
3
  import { customElement, property } from 'lit/decorators.js'
4
4
 
5
5
  import { TooltipStyles } from '@operato/styles'
6
+ import { TooltipReactiveController } from '@operato/utils'
6
7
 
7
8
  import { ZERO_COLUMN } from '../configure/zero-config'
8
9
  import { ColumnConfig, GristRecord } from '../types'
9
- import { getRenderer } from '../renderers'
10
10
 
11
11
  const DEFAULT_TEXT_ALIGN = 'left'
12
12
 
@@ -103,6 +103,8 @@ export class DataGridField extends LitElement {
103
103
  private _onFieldChange: (e: Event) => void = e => {}
104
104
  private _onKeydownInEditingMode: (e: KeyboardEvent) => void = e => {}
105
105
 
106
+ private tooltipController?: TooltipReactiveController = new TooltipReactiveController(this)
107
+
106
108
  render(): TemplateResult {
107
109
  if (!this.column) {
108
110
  return html``
@@ -8,7 +8,7 @@ import throttle from 'lodash-es/throttle'
8
8
 
9
9
  import { OxPopup } from '@operato/popup'
10
10
  import { TooltipStyles } from '@operato/styles'
11
- import { closestElement, detectOverflow } from '@operato/utils'
11
+ import { TooltipReactiveController, closestElement } from '@operato/utils'
12
12
 
13
13
  import { ZERO_COLUMNS, ZERO_DATA } from '../configure/zero-config'
14
14
  import { FilterStyles } from '../filters/filter-styles'
@@ -163,6 +163,8 @@ export class DataGridHeader extends LitElement {
163
163
  private _lastAccVal?: number
164
164
  private _throttledNotifier?: any
165
165
 
166
+ private tooltipController?: TooltipReactiveController = new TooltipReactiveController(this)
167
+
166
168
  connectedCallback() {
167
169
  super.connectedCallback()
168
170
 
@@ -232,19 +234,9 @@ export class DataGridHeader extends LitElement {
232
234
  >
233
235
  <span
234
236
  for-title
237
+ data-reactive-tooltip
235
238
  style="text-align:${align || column.record.align || 'left'};"
236
239
  @click=${(e: MouseEvent) => this._changeSort(column)}
237
- @mouseover=${(e: MouseEvent) => {
238
- const element = e.target as HTMLSpanElement
239
-
240
- if (detectOverflow(element)) {
241
- element.setAttribute('data-tooltip', element.textContent!.trim())
242
- }
243
- }}
244
- @mouseout=${(e: MouseEvent) => {
245
- const element = e.target as HTMLSpanElement
246
- element.removeAttribute('data-tooltip')
247
- }}
248
240
  >${this._renderHeader(column)}
249
241
  </span>
250
242
 
package/src/data-grist.ts CHANGED
@@ -392,7 +392,7 @@ export class DataGrist extends LitElement implements DataConsumer {
392
392
  column =>
393
393
  column.filter &&
394
394
  'value' in (column.filter as FilterConfigObject) &&
395
- (column.filter as FilterConfigObject).value
395
+ (column.filter as FilterConfigObject).value !== undefined
396
396
  )
397
397
  .map(column => {
398
398
  const filter = column.filter as FilterConfigObject
@@ -62,7 +62,7 @@ export class RecordPartial extends LitElement {
62
62
  text-indent: 1px;
63
63
  left: var(--spacing-none);
64
64
  top: var(--spacing-none);
65
- color: var(--grid-record-dirty-color);
65
+ color: var(--grid-record-dirty-color, var(--md-sys-color-error));
66
66
  }
67
67
 
68
68
  [content] {
@@ -88,17 +88,17 @@ export class RecordPartial extends LitElement {
88
88
 
89
89
  ox-list-field {
90
90
  font: var(--data-list-item-etc-font);
91
- color: var(--data-list-item-etc-color);
91
+ color: var(--data-list-item-etc-color, var(--md-sys-color-on-surface));
92
92
  }
93
93
 
94
94
  ox-list-field[name] {
95
95
  font: var(--data-list-item-name-font);
96
- color: var(--data-list-item-name-color);
96
+ color: var(--data-list-item-name-color, var(--md-sys-color-secondary));
97
97
  }
98
98
 
99
99
  ox-list-field[desc] {
100
100
  font: var(--data-list-item-disc-font);
101
- color: var(--data-list-item-disc-color);
101
+ color: var(--data-list-item-disc-color, var(--md-sys-color-tertiary));
102
102
  }
103
103
  `
104
104
  ]
@@ -5,6 +5,6 @@ import { html } from 'lit'
5
5
  @customElement('ox-grist-editor-date')
6
6
  export class OxGristEditorDate extends OxGristEditor {
7
7
  get editorTemplate() {
8
- return html` <input type="date" .value=${this.value} /> `
8
+ return html` <input type="date" .value=${this.value} max="9999-12-31" /> `
9
9
  }
10
10
  }
@@ -22,6 +22,6 @@ export class OxGristEditorDateTime extends OxGristEditor {
22
22
  }
23
23
 
24
24
  get editorTemplate() {
25
- return html` <input type="datetime-local" .value=${this.value} /> `
25
+ return html` <input type="datetime-local" .value=${this.value} max="9999-12-31T23:59" /> `
26
26
  }
27
27
  }
@@ -21,7 +21,7 @@ export const FilterCheckbox: FilterSelectRenderer = (column, value, owner) => {
21
21
  name=${column.name}
22
22
  ?checked=${value}
23
23
  indeterminatable
24
- ?indeterminate=${value == null}
24
+ ?indeterminate=${value === undefined}
25
25
  left-label
26
26
  @change=${(e: CustomEvent) => {
27
27
  ;(e.target as HTMLElement).dispatchEvent(
@@ -107,7 +107,7 @@ export class OxGristFilterPersonalizer extends LitElement {
107
107
  ${this.preference?.filters!.map(
108
108
  filter => html`
109
109
  <ox-checkbox label="checkbox" ?checked=${!filter.hidden} value=${filter.name} option
110
- >${filter.name}<span style="position: absolute; right: 10px; cursor: move;" handle
110
+ >${filter.name}<span style="position: absolute; right: 10px; cursor: row-resize;opacity:.5" handle
111
111
  >☰</span
112
112
  ></ox-checkbox
113
113
  >
@@ -22,10 +22,11 @@ export class OxGristPersonalizer extends LitElement {
22
22
  background-color: var(--ox-grist-p13n-background-color, var(--md-sys-color-primary));
23
23
  border-radius: 0px 0px 7px 7px;
24
24
  cursor: pointer;
25
+ padding-top:var(--spacing-small);
25
26
 
26
27
  &:hover {
27
- color: var(--ox-grist-p13n-hover-color, var(--md-sys-color-primary));
28
- background-color: var(--ox-grist-p13n-hover-background-color, var(--md-sys-color-on-primary));
28
+ color: var(--ox-grist-p13n-hover-color, var(--md-sys-color-on-primary));
29
+ background-color: var(--ox-grist-p13n-hover-background-color, var(--md-sys-color-surface-tint));
29
30
  }
30
31
  }
31
32
  `
@@ -69,8 +70,18 @@ export class OxGristPersonalizer extends LitElement {
69
70
 
70
71
  const template = html`
71
72
  <div class="personalizer-header" slot="header">
72
- <md-icon
73
- style="margin-left: auto;"
73
+ <div
74
+ style=${`
75
+ display: flex;
76
+ align-items: center;
77
+ margin: 0 0 0 auto;
78
+ min-height: 1.4em;
79
+ color: var(--ox-grist-p13n-button-color, var(--md-sys-color-on-primary));
80
+ background-color: var(--ox-grist-p13n-button-background-color, var(--md-sys-color-primary));
81
+ border-radius: var(--md-sys-shape-corner-small);
82
+ padding: 0 var(--spacing-small);
83
+ cursor: pointer;
84
+ `}
74
85
  @click=${async (e: MouseEvent) => {
75
86
  if (grist.personalConfigProvider) {
76
87
  const { mode, columns, sorters, pagination } = this.preference || {}
@@ -83,9 +94,21 @@ export class OxGristPersonalizer extends LitElement {
83
94
  }
84
95
  popup.close()
85
96
  }}
86
- title=${String(i18next.t('button.save'))}
87
- >keep</md-icon
88
- ><md-icon
97
+ >
98
+ ${String(i18next.t('button.save'))}
99
+ </div>
100
+ <div
101
+ style=${`
102
+ display: flex;
103
+ align-items: center;
104
+ margin: 0 0 0 var(--spacing-small, 4px);
105
+ min-height: 1.4em;
106
+ color: var(--ox-grist-p13n-button-color, var(--md-sys-color-on-primary));
107
+ background-color: var(--ox-grist-p13n-button-background-color, var(--md-sys-color-primary));
108
+ border-radius: var(--md-sys-shape-corner-small);
109
+ padding: 0 var(--spacing-small);
110
+ cursor: pointer;
111
+ `}
89
112
  @click=${async (e: MouseEvent) => {
90
113
  if (grist.personalConfigProvider) {
91
114
  grist.personalConfig = this.preference = {}
@@ -93,9 +116,17 @@ export class OxGristPersonalizer extends LitElement {
93
116
  }
94
117
  popup.close()
95
118
  }}
96
- title=${String(i18next.t('button.delete'))}
97
- >keep_off</md-icon
98
- ><md-icon @click=${async (e: MouseEvent) => popup.close()} title=${String(i18next.t('button.close'))}
119
+ >
120
+ ${String(i18next.t('button.delete'))}
121
+ </div>
122
+ <md-icon
123
+ style=${`
124
+ --md-icon-size: 1.2em;
125
+ margin-left: var(--spacing-tiny, 2px);
126
+ cursor: pointer;
127
+ `}
128
+ @click=${async (e: MouseEvent) => popup.close()}
129
+ title=${String(i18next.t('button.close'))}
99
130
  >close</md-icon
100
131
  >
101
132
  </div>
@@ -103,7 +134,7 @@ export class OxGristPersonalizer extends LitElement {
103
134
  ${columns.map(
104
135
  column => html`
105
136
  <ox-checkbox label="checkbox" ?checked=${!column.hidden} value=${column.name} option
106
- >${column.header.renderer(column)}<span style="position: absolute; right: 10px; cursor: move;" handle
137
+ >${column.header.renderer(column)}<span style="position: absolute; right: 10px; cursor: row-resize;opacity:.5" handle
107
138
  >☰</span
108
139
  ></ox-checkbox
109
140
  >
@@ -16,6 +16,7 @@ export class RecordCreator extends LitElement {
16
16
 
17
17
  @property({ type: Object }) callback?: (operation: { [key: string]: any }) => boolean
18
18
  @property({ type: Boolean, attribute: 'light-popup' }) lightPopup: boolean = false
19
+ @property({ type: Boolean, attribute: 'prevent-close-on-blur' }) preventCloseOnBlur = false
19
20
 
20
21
  constructor() {
21
22
  super()
@@ -101,7 +102,8 @@ export class RecordCreator extends LitElement {
101
102
  }}
102
103
  ></ox-record-view>
103
104
  `,
104
- parent: document.body
105
+ parent: document.body,
106
+ preventCloseOnBlur: this.preventCloseOnBlur
105
107
  })
106
108
  }
107
109
 
@@ -15,7 +15,7 @@ export class RecordViewBody extends LitElement {
15
15
  css`
16
16
  :host {
17
17
  display: grid;
18
- grid-template-columns: 33% 67%;
18
+ grid-template-columns: 2fr 3fr 2fr 3fr;
19
19
  grid-auto-rows: min-content;
20
20
  grid-gap: var(--record-view-gap);
21
21
  padding: var(--record-view-padding);
@@ -54,7 +54,7 @@ export class RecordViewBody extends LitElement {
54
54
  border-bottom: var(--record-view-border-bottom);
55
55
  font: var(--record-view-font);
56
56
  color: var(--record-view-color);
57
- background-color: transparent;
57
+ background-color: var(--record-view-grid-field-background-color, var(--md-sys-color-surface-variant));
58
58
  }
59
59
 
60
60
  ox-grid-field[editing='true'] {
@@ -65,6 +65,18 @@ export class RecordViewBody extends LitElement {
65
65
  color: var(--record-view-focus-color);
66
66
  font-weight: bold;
67
67
  }
68
+
69
+ @media only screen and (max-width: 460px) {
70
+ :host {
71
+ grid-template-columns: 2fr 3fr;
72
+ }
73
+ }
74
+
75
+ @media (min-width: 1200px) {
76
+ :host {
77
+ grid-template-columns: 2fr 3fr 2fr 3fr 2fr 3fr;
78
+ }
79
+ }
68
80
  `
69
81
  ]
70
82
 
@@ -54,9 +54,8 @@ export class RecordView extends LitElement {
54
54
  }
55
55
 
56
56
  [footer] button md-icon {
57
- margin-top: -3px;
58
- margin-right: 5px;
59
- font-size: var(--record-view-footer-iconbutton-size);
57
+ --md-icon-size: var(--record-view-footer-iconbutton-size);
58
+ margin-right: var(--spacing-small, 4px);
60
59
  }
61
60
 
62
61
  [footer] button[ok] {
@@ -11,6 +11,10 @@ function onmouseover(e: Event) {
11
11
  } catch {}
12
12
 
13
13
  element.setAttribute('data-tooltip', JSON5.stringify(parsed, null, 2))
14
+
15
+ const rect = element.getBoundingClientRect()
16
+ element.style.setProperty('--tooltip-top', `${rect.top + rect.height}px`)
17
+ element.style.setProperty('--tooltip-left', `${rect.left}px`)
14
18
  }
15
19
 
16
20
  function onmouseout(e: Event) {
@@ -1,21 +1,9 @@
1
1
  import { html } from 'lit'
2
2
 
3
- import { detectOverflow, format as formatter } from '@operato/utils'
3
+ import { format as formatter } from '@operato/utils'
4
4
 
5
5
  import { FieldRenderer } from '../types'
6
6
 
7
- function onmouseover(e: Event) {
8
- const element = e.target as HTMLSpanElement
9
- if (detectOverflow(element)) {
10
- element.setAttribute('data-tooltip', element.textContent!)
11
- }
12
- }
13
-
14
- function onmouseout(e: Event) {
15
- const element = e.target as HTMLSpanElement
16
- element.removeAttribute('data-tooltip')
17
- }
18
-
19
7
  export const OxGristRendererText: FieldRenderer = (value, column, record, rowIndex, field) => {
20
8
  var { format } = column.record || {}
21
9
 
@@ -24,5 +12,5 @@ export const OxGristRendererText: FieldRenderer = (value, column, record, rowInd
24
12
  text = formatter(format, text)
25
13
  }
26
14
 
27
- return html`<span @mouseover=${onmouseover} @mouseout=${onmouseout}>${text}&nbsp;</span>`
15
+ return html`<span data-reactive-tooltip>${text}&nbsp;</span>`
28
16
  }
@@ -6,12 +6,9 @@ import '@operato/popup/ox-popup-list.js'
6
6
  import '@material/web/icon/icon.js'
7
7
 
8
8
  import { html, TemplateResult } from 'lit'
9
+ import { styles as MDTypeScaleStyles } from '@material/web/typography/md-typescale-styles'
9
10
 
10
- import {
11
- FetchHandler,
12
- FetchOption,
13
- GristEventHandler,
14
- } from '../src/types.js'
11
+ import { FetchHandler, FetchOption, GristEventHandler } from '../src/types.js'
15
12
 
16
13
  import { CommonHeaderStyles, CommonGristStyles } from '@operato/styles'
17
14
 
@@ -60,10 +57,14 @@ const config = {
60
57
  icon: 'add',
61
58
  title: 'add',
62
59
  handlers: {
63
- click: ((columns, data, column, record, rowIndex, target, e) => console.log('column - clicked')) as GristEventHandler,
64
- dblclick: ((columns, data, column, record, rowIndex, target, e) => console.log('column - dblclicked')) as GristEventHandler,
65
- contextmenu: ((columns, data, column, record, rowIndex, target, e) => console.log('column - contextmenued')) as GristEventHandler,
66
- focus: ((columns, data, column, record, rowIndex, target, e) => console.log('column - focused')) as GristEventHandler,
60
+ click: ((columns, data, column, record, rowIndex, target, e) =>
61
+ console.log('column - clicked')) as GristEventHandler,
62
+ dblclick: ((columns, data, column, record, rowIndex, target, e) =>
63
+ console.log('column - dblclicked')) as GristEventHandler,
64
+ contextmenu: ((columns, data, column, record, rowIndex, target, e) =>
65
+ console.log('column - contextmenued')) as GristEventHandler,
66
+ focus: ((columns, data, column, record, rowIndex, target, e) =>
67
+ console.log('column - focused')) as GristEventHandler
67
68
  }
68
69
  },
69
70
  {
@@ -162,11 +163,14 @@ const config = {
162
163
  multiple: false
163
164
  },
164
165
  handlers: {
165
- click: ((columns, data, column, record, rowIndex, target, e) => console.log('row - clicked')) as GristEventHandler,
166
- dblclick: ((columns, data, column, record, rowIndex, target, e) => console.log('row - dblclicked')) as GristEventHandler,
167
- contextmenu: ((columns, data, column, record, rowIndex, target, e) => console.log('row - contextmenued')) as GristEventHandler,
168
- focus: ((columns, data, column, record, rowIndex, target, e) => console.log('row - focused')) as GristEventHandler,
169
- },
166
+ click: ((columns, data, column, record, rowIndex, target, e) =>
167
+ console.log('row - clicked')) as GristEventHandler,
168
+ dblclick: ((columns, data, column, record, rowIndex, target, e) =>
169
+ console.log('row - dblclicked')) as GristEventHandler,
170
+ contextmenu: ((columns, data, column, record, rowIndex, target, e) =>
171
+ console.log('row - contextmenued')) as GristEventHandler,
172
+ focus: ((columns, data, column, record, rowIndex, target, e) => console.log('row - focused')) as GristEventHandler
173
+ },
170
174
  accumulator: true
171
175
  },
172
176
  sorters: [
@@ -187,7 +191,9 @@ export default {
187
191
  config: { control: 'object' },
188
192
  mode: { control: 'select', options: ['GRID', 'LIST', 'CARD'] },
189
193
  urlParamsSensitive: { control: 'boolean' },
190
- withoutSearch: { control: 'boolean' }
194
+ withoutSearch: { control: 'boolean' },
195
+ preventCloseOnBlur: { control: 'boolean' },
196
+ theme: { control: 'select', options: ['light', 'dark'] }
191
197
  }
192
198
  }
193
199
 
@@ -199,10 +205,12 @@ interface Story<T> {
199
205
 
200
206
  interface ArgTypes {
201
207
  config: object
202
- mode: 'GRID'|'LIST'|'CARD'
208
+ mode: 'GRID' | 'LIST' | 'CARD'
203
209
  urlParamsSensitive: boolean
204
210
  withoutSearch: boolean
211
+ preventCloseOnBlur: boolean
205
212
  fetchHandler: FetchHandler
213
+ theme: 'light' | 'dark'
206
214
  }
207
215
 
208
216
  const Template: Story<ArgTypes> = ({
@@ -210,9 +218,18 @@ const Template: Story<ArgTypes> = ({
210
218
  mode = 'GRID',
211
219
  urlParamsSensitive = false,
212
220
  withoutSearch = false,
213
- fetchHandler
221
+ preventCloseOnBlur = false,
222
+ fetchHandler,
223
+ theme = 'light'
214
224
  }: ArgTypes) =>
215
- html` <link
225
+ html` <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;700&display=swap" rel="stylesheet" />
226
+
227
+ <link href="/themes/light.css" rel="stylesheet" />
228
+ <link href="/themes/dark.css" rel="stylesheet" />
229
+ <link href="/themes/spacing.css" rel="stylesheet" />
230
+ <link href="/themes/grist-theme.css" rel="stylesheet" />
231
+
232
+ <link
216
233
  href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL@20..48,100..700,0..1"
217
234
  rel="stylesheet"
218
235
  />
@@ -225,15 +242,19 @@ const Template: Story<ArgTypes> = ({
225
242
  rel="stylesheet"
226
243
  />
227
244
 
228
- <link href="/themes/app-theme.css" rel="stylesheet" />
229
- <link href="/themes/oops-theme.css" rel="stylesheet" />
230
- <link href="/themes/grist-theme.css" rel="stylesheet" />
245
+ <style>
246
+ ${MDTypeScaleStyles.cssText}
247
+ </style>
231
248
 
232
249
  <style>
233
250
  ${CommonGristStyles.cssText}
234
251
  ${CommonHeaderStyles.cssText}
235
252
  </style>
236
253
 
254
+ <script>
255
+ document.body.classList.add('${theme}')
256
+ </script>
257
+
237
258
  <style>
238
259
  ox-grist {
239
260
  height: 600px;
@@ -254,7 +275,7 @@ const Template: Story<ArgTypes> = ({
254
275
  <div slot="headroom" class="header">
255
276
  <div class="filters">
256
277
  <ox-filters-form ?without-search=${withoutSearch} autofocus></ox-filters-form>
257
- <ox-record-creator id="add" light-popup>
278
+ <ox-record-creator id="add" light-popup ?prevent-close-on-blur=${preventCloseOnBlur}>
258
279
  <button><md-icon>add</md-icon></button>
259
280
  </ox-record-creator>
260
281
  </div>
@@ -156,6 +156,7 @@ export default {
156
156
  component: 'ox-grist',
157
157
  argTypes: {
158
158
  headerFilter: { control: 'boolean' },
159
+ preventCloseOnBlur: { control: 'boolean' },
159
160
  theme: { control: 'select', options: ['light', 'dark'] }
160
161
  }
161
162
  }
@@ -168,10 +169,11 @@ interface Story<T> {
168
169
 
169
170
  interface ArgTypes {
170
171
  headerFilter: boolean
172
+ preventCloseOnBlur: boolean
171
173
  theme: 'light' | 'dark'
172
174
  }
173
175
 
174
- const Template: Story<ArgTypes> = ({ headerFilter, theme = 'light' }: ArgTypes) =>
176
+ const Template: Story<ArgTypes> = ({ headerFilter, preventCloseOnBlur, theme = 'light' }: ArgTypes) =>
175
177
  html` <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;700&display=swap" rel="stylesheet" />
176
178
 
177
179
  <link href="/themes/light.css" rel="stylesheet" />
@@ -246,7 +248,7 @@ const Template: Story<ArgTypes> = ({ headerFilter, theme = 'light' }: ArgTypes)
246
248
  </ox-popup>
247
249
  </div>
248
250
 
249
- <ox-record-creator id="add" light-popup>
251
+ <ox-record-creator id="add" light-popup ?prevent-close-on-blur=${preventCloseOnBlur}>
250
252
  <button><md-icon>add</md-icon></button>
251
253
  </ox-record-creator>
252
254
  </div>
@@ -28,6 +28,8 @@ const fetchHandler: FetchHandler = async ({ sorters = [], filters, page, limit }
28
28
  number: idx,
29
29
  float: 1.3,
30
30
  date: '2023-09-20',
31
+ active: idx % 2 === 0,
32
+ role: 'admin',
31
33
  routing: {
32
34
  id: '006dc64d-4fb9-4afc-a9ea-962bd1b9e110',
33
35
  name: '조림>세척'
@@ -136,6 +138,40 @@ function buildConfig({ headerFilter }: { headerFilter: boolean }) {
136
138
  header: 'date',
137
139
  width: 120
138
140
  },
141
+ {
142
+ type: 'boolean',
143
+ name: 'active',
144
+ header: 'active',
145
+ record: {
146
+ editable: true
147
+ },
148
+ filter: {
149
+ value: false
150
+ },
151
+ sortable: true,
152
+ width: 60
153
+ },
154
+ {
155
+ type: 'select',
156
+ name: 'role',
157
+ label: true,
158
+ header: 'role',
159
+ record: {
160
+ // options: ['', 'admin', 'worker', 'tester'],
161
+ options: [
162
+ { display: 'admin', value: 'admin' },
163
+ { display: 'worker', value: 'worker' },
164
+ { display: 'tester', value: 'tester' }
165
+ ],
166
+ editable: true
167
+ },
168
+ filter: {
169
+ operator: 'in',
170
+ value: ['worker']
171
+ },
172
+ sortable: true,
173
+ width: 120
174
+ },
139
175
  {
140
176
  type: 'object',
141
177
  name: 'routing',