@operato/input 7.0.29 → 7.0.33

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.29",
5
+ "version": "7.0.33",
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": "b1438f0b1a64818d17095c382f869e5a920bd0ea"
257
+ "gitHead": "3cb252093110890ca79c2881f7f544ab159c3860"
258
258
  }
@@ -64,6 +64,7 @@ export class OxCheckbox extends OxFormField {
64
64
  color: var(--ox-checkbox-label-color, var(--md-sys-color-on-primary-container));
65
65
  line-height: var(--md-sys-typescale-label-medium-line-height, 1rem);
66
66
  }
67
+
67
68
  :host([checked]) .label {
68
69
  color: var(ox-checkbox-label-checked-color, var(--md-sys-color-primary));
69
70
  font-weight: 700;
@@ -80,7 +81,7 @@ export class OxCheckbox extends OxFormField {
80
81
 
81
82
  render() {
82
83
  return html`
83
- <div @click=${this.onClick} ?disabled=${this.disabled}>
84
+ <div ?disabled=${this.disabled} @click=${this.onClick}>
84
85
  ${this._hasInner && this.left
85
86
  ? html` <span label>
86
87
  <slot></slot>
@@ -98,12 +99,18 @@ export class OxCheckbox extends OxFormField {
98
99
  `
99
100
  }
100
101
 
101
- connectedCallback() {
102
+ connectedCallback(): void {
102
103
  super.connectedCallback()
103
104
 
104
105
  this.setAttribute('tabindex', '0')
105
- this.addEventListener('keydown', this.onKeyDown.bind(this))
106
- 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)
107
114
  }
108
115
 
109
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,7 @@ 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') as OxPopupList
128
111
  if (popupList) {
129
112
  popupList.value = this.value
130
113
  await this.requestUpdate()
@@ -184,15 +167,46 @@ export class OxSelect extends OxFormField {
184
167
  return
185
168
  }
186
169
 
187
- const popupList = this.querySelector('ox-popup-list') as OxPopupList
170
+ const slotContent = this.renderRoot.querySelector('slot')?.assignedNodes() || []
171
+
172
+ if (slotContent.length > 0) {
173
+ const popupList = slotContent.find(content => content instanceof OxPopupList) as OxPopupList
188
174
 
189
- if (popupList) {
190
- popupList.style.width = `${this.offsetWidth}px`
175
+ if (popupList) {
176
+ const { left, bottom } = this.getBoundingClientRect()
191
177
 
192
- popupList.open({
193
- left: 0,
194
- top: this.offsetHeight
195
- })
178
+ popupList.value = this.value
179
+ popupList.style.width = `${this.offsetWidth}px`
180
+ popupList.style.textWrap = 'nowrap'
181
+
182
+ const selectHandler = (e: Event) => {
183
+ this.value = (e as CustomEvent).detail
184
+ }
185
+ popupList.addEventListener('select', selectHandler)
186
+
187
+ const closeHandler = (e: Event) => {
188
+ /* popup이 close될 때 change 이벤트를 발생시킨다. */
189
+ this.dispatchEvent(
190
+ new CustomEvent('change', {
191
+ bubbles: true,
192
+ composed: true,
193
+ detail: this.value
194
+ })
195
+ )
196
+ popupList.removeEventListener('select', selectHandler)
197
+ popupList.removeEventListener('close', closeHandler)
198
+
199
+ this.appendChild(popupList)
200
+ }
201
+ popupList.addEventListener('close', closeHandler, { once: true })
202
+
203
+ document.body.appendChild(popupList)
204
+
205
+ popupList.open({
206
+ left,
207
+ top: bottom
208
+ })
209
+ }
196
210
  }
197
211
  }
198
212
  }
@@ -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