@operato/input 7.0.30 → 7.0.35

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.
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@operato/input",
3
3
  "description": "Webcomponents for input following open-wc recommendations",
4
4
  "author": "heartyoh@hatiolab.com",
5
- "version": "7.0.30",
5
+ "version": "7.0.35",
6
6
  "main": "dist/src/index.js",
7
7
  "module": "dist/src/index.js",
8
8
  "license": "MIT",
@@ -208,7 +208,7 @@
208
208
  "@material/web": "^1.5.0",
209
209
  "@operato/color-picker": "^7.0.0",
210
210
  "@operato/i18n": "^7.0.0",
211
- "@operato/popup": "^7.0.28",
211
+ "@operato/popup": "^7.0.33",
212
212
  "@operato/styles": "^7.0.20",
213
213
  "@operato/utils": "^7.0.5",
214
214
  "@polymer/paper-dropdown-menu": "^3.2.0",
@@ -254,5 +254,5 @@
254
254
  "prettier --write"
255
255
  ]
256
256
  },
257
- "gitHead": "865d9fb09f315d1239884e4bf2c0205e8818aca1"
257
+ "gitHead": "c23cae1e362ea1637f0c87a78f58a8672dbf55ef"
258
258
  }
@@ -81,7 +81,7 @@ export class OxCheckbox extends OxFormField {
81
81
 
82
82
  render() {
83
83
  return html`
84
- <div ?disabled=${this.disabled}>
84
+ <div ?disabled=${this.disabled} @click=${this.onClick}>
85
85
  ${this._hasInner && this.left
86
86
  ? html` <span label>
87
87
  <slot></slot>
@@ -99,12 +99,18 @@ export class OxCheckbox extends OxFormField {
99
99
  `
100
100
  }
101
101
 
102
- connectedCallback() {
102
+ connectedCallback(): void {
103
103
  super.connectedCallback()
104
104
 
105
105
  this.setAttribute('tabindex', '0')
106
- this.addEventListener('keydown', this.onKeyDown.bind(this))
107
- this.addEventListener('click', this.onClick.bind(this))
106
+ this.addEventListener('keydown', this.onKeyDown)
107
+ }
108
+
109
+ disconnectedCallback(): void {
110
+ super.disconnectedCallback()
111
+
112
+ this.setAttribute('tabindex', '-1')
113
+ this.removeEventListener('keydown', this.onKeyDown)
108
114
  }
109
115
 
110
116
  onClick() {
@@ -9,6 +9,9 @@ import { i18next } from '@operato/i18n'
9
9
 
10
10
  import { OxFormField } from './ox-form-field'
11
11
 
12
+ import '@material/web/fab/fab.js'
13
+ import '@material/web/icon/icon.js'
14
+
12
15
  function createCronRegex(type: 'sec' | 'min' | 'hour' | 'day' | 'month' | 'dayOfWeek') {
13
16
  // https://gist.github.com/dkandalov/a2aed17cfdeb65243022
14
17
  var regexByField = {} as any
@@ -82,6 +85,7 @@ function createCronRegex(type: 'sec' | 'min' | 'hour' | 'day' | 'month' | 'dayOf
82
85
  export class OxInputCrontab extends OxFormField {
83
86
  static styles = css`
84
87
  :host {
88
+ position: relative;
85
89
  display: block;
86
90
  width: 100%;
87
91
  height: 100%;
@@ -140,6 +144,7 @@ export class OxInputCrontab extends OxFormField {
140
144
  font-size: var(--md-sys-typescale-label-large-size, 0.875rem);
141
145
  color: var(--md-sys-color-on-primary-container);
142
146
  }
147
+
143
148
  input:focus {
144
149
  outline: none;
145
150
  border-color: var(--md-sys-color-secondary-fixed-dim);
@@ -202,7 +207,7 @@ export class OxInputCrontab extends OxFormField {
202
207
 
203
208
  #tooltip > .crontab-description {
204
209
  text-align: left;
205
- color: var(--md-sys-color-on-primary-container);
210
+ color: var (--md-sys-color-on-primary-container);
206
211
  }
207
212
 
208
213
  #button-wrapper {
@@ -213,13 +218,16 @@ export class OxInputCrontab extends OxFormField {
213
218
  margin: -0.25rem;
214
219
  }
215
220
 
216
- button {
217
- border-radius: var(--button-border-radius);
221
+ md-fab {
218
222
  margin: 0.25rem;
223
+ position: absolute;
224
+ bottom: 1rem;
225
+ left: 1rem;
226
+ color: var(--md-sys-color-on-primary);
219
227
  }
220
- button:hover,
221
- button:active {
222
- background-color: var(--md-sys-color-on-primary-container);
228
+
229
+ md-icon {
230
+ font-size: 24px;
223
231
  }
224
232
  `
225
233
 
@@ -377,23 +385,25 @@ export class OxInputCrontab extends OxFormField {
377
385
  `
378
386
  )}
379
387
  </div>
380
- <button
381
- id="clear"
382
- @click=${(e: Event) => {
383
- e.preventDefault()
384
- e.stopPropagation()
385
- this.value = ''
386
- this.dispatchEvent(
387
- new CustomEvent('change', {
388
- bubbles: true,
389
- composed: true,
390
- detail: this.value
391
- })
392
- )
393
- }}
394
- >
395
- Clear
396
- </button>
388
+ <div id="button-wrapper">
389
+ <md-fab
390
+ title="clear"
391
+ @click=${(e: Event) => {
392
+ e.preventDefault()
393
+ e.stopPropagation()
394
+ this.value = ''
395
+ this.dispatchEvent(
396
+ new CustomEvent('change', {
397
+ bubbles: true,
398
+ composed: true,
399
+ detail: this.value
400
+ })
401
+ )
402
+ }}
403
+ >
404
+ <md-icon slot="icon">delete</md-icon>
405
+ </md-fab>
406
+ </div>
397
407
  </form>
398
408
  `
399
409
  }
package/src/ox-select.ts CHANGED
@@ -6,7 +6,7 @@ import '@material/web/icon/icon.js'
6
6
  import '@operato/popup/ox-popup-list.js'
7
7
  import './ox-checkbox.js'
8
8
 
9
- import { css, html, render, PropertyValues, nothing } from 'lit'
9
+ import { css, html, render, PropertyValues } from 'lit'
10
10
  import { customElement, property, query, state } from 'lit/decorators.js'
11
11
 
12
12
  import { OxPopupList } from '@operato/popup'
@@ -62,10 +62,6 @@ export class OxSelect extends OxFormField {
62
62
  div:hover md-icon {
63
63
  color: var(--md-sys-color-on-primary-container);
64
64
  }
65
-
66
- ::slotted(ox-popup-list) {
67
- width: 100%;
68
- }
69
65
  `
70
66
  ]
71
67
 
@@ -73,6 +69,8 @@ export class OxSelect extends OxFormField {
73
69
  @property({ type: String }) placeholder: string = ''
74
70
 
75
71
  @state() label: string | string[] = ''
72
+ @state() popupContainer: HTMLElement | null = null
73
+ @state() observer: MutationObserver | null = null
76
74
 
77
75
  render() {
78
76
  const label =
@@ -96,21 +94,6 @@ export class OxSelect extends OxFormField {
96
94
 
97
95
  this.setAttribute('tabindex', '0')
98
96
 
99
- this.addEventListener('select', (e: Event) => {
100
- this.value = (e as CustomEvent).detail
101
- })
102
-
103
- this.addEventListener('close', e => {
104
- /* popup이 close될 때 change 이벤트를 발생시킨다. */
105
- this.dispatchEvent(
106
- new CustomEvent('change', {
107
- bubbles: true,
108
- composed: true,
109
- detail: this.value
110
- })
111
- )
112
- })
113
-
114
97
  this.addEventListener('keydown', (e: KeyboardEvent) => {
115
98
  e.preventDefault()
116
99
 
@@ -124,7 +107,9 @@ export class OxSelect extends OxFormField {
124
107
 
125
108
  async updated(changes: PropertyValues<this>) {
126
109
  if (changes.has('value')) {
127
- const popupList = this.querySelector('ox-popup-list') as OxPopupList
110
+ const popupList = (this.popupContainer?.querySelector('ox-popup-list') ||
111
+ this.querySelector('ox-popup-list')) as OxPopupList
112
+
128
113
  if (popupList) {
129
114
  popupList.value = this.value
130
115
  await this.requestUpdate()
@@ -184,15 +169,51 @@ export class OxSelect extends OxFormField {
184
169
  return
185
170
  }
186
171
 
187
- const popupList = this.querySelector('ox-popup-list') as OxPopupList
172
+ const slotContent = this.renderRoot.querySelector('slot')?.assignedNodes() || []
188
173
 
189
- if (popupList) {
190
- popupList.style.width = `${this.offsetWidth}px`
174
+ if (slotContent.length > 0) {
175
+ const popupList = slotContent.find(content => content instanceof OxPopupList) as OxPopupList
176
+
177
+ if (popupList) {
178
+ const { left, bottom } = this.getBoundingClientRect()
191
179
 
192
- popupList.open({
193
- left: 0,
194
- top: this.offsetHeight
195
- })
180
+ popupList.value = this.value
181
+ popupList.style.width = `${this.offsetWidth}px`
182
+ popupList.style.textWrap = 'nowrap'
183
+
184
+ const selectHandler = async (e: Event) => {
185
+ this.value = (e as CustomEvent).detail
186
+
187
+ if (popupList) {
188
+ await this.requestUpdate()
189
+ this.label = popupList.getSelectedLabels()
190
+ }
191
+ }
192
+ popupList.addEventListener('select', selectHandler)
193
+
194
+ const closeHandler = (e: Event) => {
195
+ /* popup이 close될 때 change 이벤트를 발생시킨다. */
196
+ this.dispatchEvent(
197
+ new CustomEvent('change', {
198
+ bubbles: true,
199
+ composed: true,
200
+ detail: this.value
201
+ })
202
+ )
203
+ popupList.removeEventListener('select', selectHandler)
204
+ popupList.removeEventListener('close', closeHandler)
205
+
206
+ this.appendChild(popupList)
207
+ }
208
+ popupList.addEventListener('close', closeHandler, { once: true })
209
+
210
+ document.body.appendChild(popupList)
211
+
212
+ popupList.open({
213
+ left,
214
+ top: bottom
215
+ })
216
+ }
196
217
  }
197
218
  }
198
219
  }
@@ -60,7 +60,7 @@ const Template: Story<ArgTypes> = ({
60
60
 
61
61
  <style>
62
62
  .container {
63
- height: 500px;
63
+ height: 250px;
64
64
  text-align: center;
65
65
  padding: 20px;
66
66
 
@@ -154,9 +154,17 @@ MultipleWithCheckbox.args = {
154
154
  option => !option.hasAttribute('hidden')
155
155
  )
156
156
  options.forEach(option => ((option as HTMLInputElement).checked = target.checked))
157
- ;(target.closest('ox-select') as any)!.value = options
157
+ const value = options
158
158
  .map(option => ((option as HTMLInputElement).checked ? (option as HTMLInputElement).value : undefined))
159
159
  .filter(Boolean)
160
+
161
+ ;(target.closest('ox-popup-list') as any)!.dispatchEvent(
162
+ new CustomEvent('select', {
163
+ bubbles: true,
164
+ composed: true,
165
+ detail: value
166
+ })
167
+ )
160
168
  }}
161
169
  >set all</ox-checkbox
162
170
  >