@operato/popup 2.0.0-alpha.99 → 2.0.0-beta.12

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 (68) hide show
  1. package/CHANGELOG.md +246 -0
  2. package/dist/src/ox-floating-overlay.js +17 -14
  3. package/dist/src/ox-floating-overlay.js.map +1 -1
  4. package/dist/src/ox-popup-list.d.ts +17 -3
  5. package/dist/src/ox-popup-list.js +109 -31
  6. package/dist/src/ox-popup-list.js.map +1 -1
  7. package/dist/src/ox-popup-menu.js +21 -16
  8. package/dist/src/ox-popup-menu.js.map +1 -1
  9. package/dist/src/ox-popup-menuitem.js +5 -5
  10. package/dist/src/ox-popup-menuitem.js.map +1 -1
  11. package/dist/src/ox-popup.d.ts +1 -0
  12. package/dist/src/ox-popup.js +19 -9
  13. package/dist/src/ox-popup.js.map +1 -1
  14. package/dist/src/ox-prompt.js +68 -28
  15. package/dist/src/ox-prompt.js.map +1 -1
  16. package/dist/stories/open-popup.stories.d.ts +6 -0
  17. package/dist/stories/open-popup.stories.js +26 -6
  18. package/dist/stories/open-popup.stories.js.map +1 -1
  19. package/dist/stories/ox-popup-list-sortable.stories.d.ts +24 -0
  20. package/dist/stories/ox-popup-list-sortable.stories.js +169 -0
  21. package/dist/stories/ox-popup-list-sortable.stories.js.map +1 -0
  22. package/dist/stories/ox-popup-list.stories.d.ts +8 -2
  23. package/dist/stories/ox-popup-list.stories.js +52 -32
  24. package/dist/stories/ox-popup-list.stories.js.map +1 -1
  25. package/dist/stories/ox-popup-menu.stories.d.ts +8 -2
  26. package/dist/stories/ox-popup-menu.stories.js +26 -7
  27. package/dist/stories/ox-popup-menu.stories.js.map +1 -1
  28. package/dist/stories/ox-popup.stories.d.ts +8 -1
  29. package/dist/stories/ox-popup.stories.js +47 -13
  30. package/dist/stories/ox-popup.stories.js.map +1 -1
  31. package/dist/stories/ox-prompt-icon.stories.d.ts +6 -0
  32. package/dist/stories/ox-prompt-icon.stories.js +24 -9
  33. package/dist/stories/ox-prompt-icon.stories.js.map +1 -1
  34. package/dist/stories/ox-prompt-normal.stories.d.ts +8 -1
  35. package/dist/stories/ox-prompt-normal.stories.js +25 -7
  36. package/dist/stories/ox-prompt-normal.stories.js.map +1 -1
  37. package/dist/stories/ox-prompt.stories.d.ts +7 -1
  38. package/dist/stories/ox-prompt.stories.js +26 -9
  39. package/dist/stories/ox-prompt.stories.js.map +1 -1
  40. package/dist/tsconfig.tsbuildinfo +1 -1
  41. package/package.json +5 -4
  42. package/src/ox-floating-overlay.ts +17 -14
  43. package/src/ox-popup-list.ts +133 -34
  44. package/src/ox-popup-menu.ts +21 -16
  45. package/src/ox-popup-menuitem.ts +5 -5
  46. package/src/ox-popup.ts +17 -9
  47. package/src/ox-prompt.ts +71 -28
  48. package/stories/open-popup.stories.ts +28 -6
  49. package/stories/ox-popup-list-sortable.stories.ts +188 -0
  50. package/stories/ox-popup-list.stories.ts +55 -34
  51. package/stories/ox-popup-menu.stories.ts +29 -8
  52. package/stories/ox-popup.stories.ts +51 -16
  53. package/stories/ox-prompt-icon.stories.ts +30 -9
  54. package/stories/ox-prompt-normal.stories.ts +28 -8
  55. package/stories/ox-prompt.stories.ts +30 -10
  56. package/themes/dark-hc.css +151 -0
  57. package/themes/dark-mc.css +151 -0
  58. package/themes/dark.css +151 -0
  59. package/themes/grist-theme.css +173 -0
  60. package/themes/light-hc.css +151 -0
  61. package/themes/light-mc.css +151 -0
  62. package/themes/light.css +151 -0
  63. package/themes/md-typescale-styles.css +100 -0
  64. package/themes/spacing.css +43 -0
  65. package/themes/state-color.css +6 -0
  66. package/themes/app-theme.css +0 -145
  67. package/themes/input-theme.css +0 -19
  68. package/themes/material-theme.css +0 -88
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@operato/popup",
3
3
  "description": "Webcomponent popup following open-wc recommendations",
4
4
  "author": "heartyoh",
5
- "version": "2.0.0-alpha.99",
5
+ "version": "2.0.0-beta.12",
6
6
  "main": "dist/src/index.js",
7
7
  "module": "dist/src/index.js",
8
8
  "exports": {
@@ -60,8 +60,8 @@
60
60
  },
61
61
  "dependencies": {
62
62
  "@material/web": "^1.4.0",
63
- "@operato/styles": "^2.0.0-alpha.99",
64
- "@operato/utils": "^2.0.0-alpha.68",
63
+ "@operato/styles": "^2.0.0-beta.5",
64
+ "@operato/utils": "^2.0.0-beta.0",
65
65
  "lit": "^3.1.2"
66
66
  },
67
67
  "devDependencies": {
@@ -80,6 +80,7 @@
80
80
  "husky": "^9.0.11",
81
81
  "lint-staged": "^15.2.2",
82
82
  "prettier": "^3.2.5",
83
+ "sortablejs": "^1.15.2",
83
84
  "tslib": "^2.3.1",
84
85
  "typescript": "^5.0.4"
85
86
  },
@@ -96,5 +97,5 @@
96
97
  "prettier --write"
97
98
  ]
98
99
  },
99
- "gitHead": "8641cdd871ffdbef9e5b2a79bbf3862fb0422e3e"
100
+ "gitHead": "08cd1f9bacfca1f0559ee61089a26087cc1876ba"
100
101
  }
@@ -38,6 +38,7 @@ export class OxFloatingOverlay extends LitElement {
38
38
  :host {
39
39
  position: relative;
40
40
  z-index: var(--z-index, 10);
41
+ box-shadow: 2px 3px 10px 5px rgba(0, 0, 0, 0.15);
41
42
  }
42
43
 
43
44
  :host([hovering='edge']) {
@@ -54,7 +55,8 @@ export class OxFloatingOverlay extends LitElement {
54
55
  height: 100vh;
55
56
  height: 100dvh;
56
57
 
57
- background-color: var(--overlay-background-color);
58
+ background-color: var(--md-sys-color-primary);
59
+ opacity: 0.2;
58
60
  }
59
61
 
60
62
  [overlayed] {
@@ -63,7 +65,6 @@ export class OxFloatingOverlay extends LitElement {
63
65
  display: flex;
64
66
  flex-direction: column;
65
67
  overflow: hidden;
66
- background: transparent;
67
68
  }
68
69
 
69
70
  [overlayed][hovering='center'] {
@@ -97,8 +98,8 @@ export class OxFloatingOverlay extends LitElement {
97
98
  }
98
99
 
99
100
  [header] {
100
- --help-icon-color: #fff;
101
- --help-icon-hover-color: #fff;
101
+ --help-icon-color: var(--md-sys-color-on-primary-container);
102
+ --help-icon-hover-color: var(--md-sys-color-on-primary-container);
102
103
 
103
104
  pointer-events: initial;
104
105
  }
@@ -185,9 +186,9 @@ export class OxFloatingOverlay extends LitElement {
185
186
  display: flex;
186
187
  flex-direction: row;
187
188
  align-items: center;
188
-
189
- background-color: var(--overlay-header-background-color);
190
- color: var(--overlay-header-color);
189
+ background-color: var(--md-sys-color-primary-container);
190
+ font-weight: var(--md-sys-typescale-label-large-weight, var(--md-ref-typeface-weight-medium, 500));
191
+ color: var(--md-sys-color-on-primary-container);
191
192
  }
192
193
 
193
194
  slot[name='header'] {
@@ -197,6 +198,7 @@ export class OxFloatingOverlay extends LitElement {
197
198
  flex-direction: row;
198
199
  align-items: center;
199
200
  justify-content: center;
201
+ text-transform: capitalize;
200
202
  }
201
203
 
202
204
  [name='header']::slotted(*) {
@@ -204,18 +206,18 @@ export class OxFloatingOverlay extends LitElement {
204
206
  }
205
207
 
206
208
  [name='header'] > h1 {
207
- text-transform: capitalize;
208
- font: var(--overlay-header-font);
209
+ font-size: var(--md-sys-typescale-title-medium-size, 1rem);
210
+ margin-block: 0.4rem;
209
211
  }
210
212
 
211
213
  [historyback] {
212
- margin-left: 10px;
214
+ margin-left: var(--spacing-medium);
213
215
  margin-right: auto;
214
216
  }
215
217
 
216
218
  [close] {
217
219
  margin-left: auto;
218
- margin-right: 10px;
220
+ margin-right: var(--spacing-medium);
219
221
  }
220
222
 
221
223
  [historyback],
@@ -225,10 +227,11 @@ export class OxFloatingOverlay extends LitElement {
225
227
 
226
228
  [closable][close] {
227
229
  display: block;
230
+ cursor: pointer;
228
231
  }
229
232
 
230
233
  [search] ox-help-icon {
231
- color: var(--secondary-color);
234
+ color: var(--md-sys-color-on-secondary-container);
232
235
  }
233
236
 
234
237
  [search] {
@@ -237,10 +240,10 @@ export class OxFloatingOverlay extends LitElement {
237
240
  align-items: center;
238
241
 
239
242
  align-self: center;
240
- color: var(--secondary-color);
243
+ color: var(--md-sys-color-on-secondary-container);
241
244
  background-color: var(--opacity-light-color);
242
245
  border-radius: 999em;
243
- padding: 0 10px;
246
+ padding: 0 var(--spacing-medium);
244
247
  }
245
248
 
246
249
  [search] > * {
@@ -1,13 +1,14 @@
1
1
  import '@material/web/icon/icon.js'
2
2
 
3
- import { css, html, PropertyValues } from 'lit'
3
+ import { css, CSSResult, html, PropertyValues } from 'lit'
4
4
  import { render } from 'lit-html'
5
5
  import { customElement, property, query, state } from 'lit/decorators.js'
6
+ import Sortable from 'sortablejs'
6
7
 
7
8
  import { OxPopup } from './ox-popup'
8
9
 
9
10
  function guaranteeFocus(element: HTMLElement) {
10
- // 1. 옵션 엘리먼트의 하위 첫번째 focusible 엘리먼트에 focus 기회를 준다.
11
+ // 1. Give focus opportunity to the first focusable element within the option element.
11
12
  const focusible = element.querySelector('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])')
12
13
 
13
14
  if (focusible) {
@@ -15,7 +16,7 @@ function guaranteeFocus(element: HTMLElement) {
15
16
  return
16
17
  }
17
18
 
18
- // 2. 자신을 포함해서 가장 가까운 부모에게 focus 기회를 준다.
19
+ // 2. Give focus opportunity to the closest parent, including itself.
19
20
  const closest = element.closest(
20
21
  'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
21
22
  ) as HTMLElement
@@ -33,13 +34,14 @@ export class OxPopupList extends OxPopup {
33
34
  css`
34
35
  :host {
35
36
  display: none;
36
- flex-direction: column;
37
37
  align-items: stretch;
38
- background-color: var(--theme-white-color, #fff);
38
+ background-color: var(--ox-popup-list-background-color, var(--md-sys-color-surface));
39
39
  z-index: 100;
40
40
  box-shadow: 2px 3px 10px 5px rgba(0, 0, 0, 0.15);
41
- padding: 4px 0;
42
- color: var(--theme-primary-text-color, #3c3938);
41
+ padding: var(--spacing-small) 0;
42
+
43
+ color: var(--ox-popup-list-color, var(--md-sys-color-primary-container));
44
+ font-size: var(--md-sys-typescale-label-large-size, 0.875rem);
43
45
  font:
44
46
  normal 14px 'Roboto',
45
47
  sans-serif;
@@ -47,6 +49,7 @@ export class OxPopupList extends OxPopup {
47
49
 
48
50
  :host([active]) {
49
51
  display: flex;
52
+ flex-direction: column;
50
53
  }
51
54
 
52
55
  :host(*:focus) {
@@ -62,10 +65,11 @@ export class OxPopupList extends OxPopup {
62
65
  }
63
66
 
64
67
  ::slotted(*) {
65
- padding: 5px 10px;
66
- border-bottom: 1px solid rgba(0, 0, 0, 0.05);
68
+ padding: var(--spacing-medium);
69
+ border-bottom: 1px solid var(--md-sys-color-surface-variant);
67
70
  cursor: pointer;
68
71
  outline: none;
72
+ color: var(--ox-popup-list-color, var(--md-sys-color-on-surface-variant));
69
73
  }
70
74
 
71
75
  ::slotted(*:focus) {
@@ -74,22 +78,20 @@ export class OxPopupList extends OxPopup {
74
78
 
75
79
  ::slotted([option][active]),
76
80
  ::slotted([option]:hover) {
77
- background-color: #f6f6f6;
81
+ background-color: var(--ox-popup-list-background-color-variant, var(--md-sys-color-primary-container));
82
+ color: var(--ox-popup-list-color-variant, var(--md-sys-color-primary));
78
83
  }
79
84
 
80
85
  ::slotted([option][selected]) {
81
- border-left: 3px solid var(--primary-color, #38a25b);
82
- font-weight: bold;
86
+ border-left: 3px solid var(--md-sys-color-primary);
87
+ font-weight: var(--md-sys-typescale-label-large-weight, var(--md-ref-typeface-weight-medium, 500));
83
88
  }
84
89
 
85
90
  ::slotted([separator]) {
86
91
  height: 1px;
87
92
  width: 100%;
88
93
  padding: 0;
89
- background-color: rgba(0, 0, 0, 0.15);
90
- }
91
- ::slotted([option] > input) {
92
- border: var(--border-dark-color, 1px solid rgba(0, 0, 0, 0.3));
94
+ background-color: var(--ox-popup-menu-separator-color, var(--md-sys-color-surface-variant));
93
95
  }
94
96
 
95
97
  ::slotted([hidden]) {
@@ -100,22 +102,22 @@ export class OxPopupList extends OxPopup {
100
102
  display: flex;
101
103
  position: relative;
102
104
  align-items: center;
103
- padding: 5px 10px;
105
+ padding: var(--spacing-small) var(--spacing-medium);
104
106
 
105
- --md-icon-size: 20px;
107
+ --md-icon-size: var(--icon-size-small);
106
108
  }
107
109
 
108
110
  [search] [type='text'] {
109
111
  flex: 1;
110
112
  background-color: transparent;
111
113
  border: 0;
112
- padding: 0 0 0 25px;
114
+ padding: 0 0 0 var(--spacing-huge);
113
115
  outline: none;
114
116
  width: 50px;
115
117
  }
116
118
 
117
119
  [search] md-icon {
118
- color: var(--secondary-color);
120
+ color: var(--md-sys-color-secondary);
119
121
  }
120
122
 
121
123
  [search] md-icon[search-icon] {
@@ -124,13 +126,22 @@ export class OxPopupList extends OxPopup {
124
126
 
125
127
  [search] md-icon[delete-icon] {
126
128
  opacity: 0.5;
127
- --md-icon-size: 14px;
129
+ --md-icon-size: var(--icon-size-tiny);
128
130
  }
129
131
 
130
132
  [nothing] {
131
133
  opacity: 0.5;
132
134
  text-align: center;
133
135
  }
136
+
137
+ div[body] {
138
+ flex: 1;
139
+ display: flex;
140
+ flex-direction: column;
141
+ margin: 0;
142
+ padding: 0;
143
+ overflow: auto;
144
+ }
134
145
  `
135
146
  ]
136
147
 
@@ -138,20 +149,27 @@ export class OxPopupList extends OxPopup {
138
149
  * A boolean property that, when set to true, allows multiple options to be selected in the popup list.
139
150
  * @type {boolean}
140
151
  */
141
- @property({ type: Boolean }) multiple: boolean = false
152
+ @property({ type: Boolean, attribute: true, reflect: true }) multiple: boolean = false
142
153
 
143
154
  /**
144
155
  * An optional attribute that specifies the name of the attribute used to mark selected options in the list.
145
156
  * @type {string|undefined}
146
157
  */
147
- @property({ type: String, attribute: 'attr-selected' }) attrSelected?: string
158
+ @property({ type: String, attribute: 'attr-selected', reflect: true }) attrSelected?: string
148
159
 
149
160
  /**
150
161
  * A boolean property that, when set to true, enables the search functionality in the popup list.
151
162
  * Users can search/filter options by typing in a search bar.
152
163
  * @type {boolean|undefined}
153
164
  */
154
- @property({ type: Boolean, attribute: 'with-search' }) withSearch?: boolean
165
+ @property({ type: Boolean, attribute: 'with-search', reflect: true }) withSearch?: boolean
166
+
167
+ /**
168
+ * A boolean property that, when set to true, enables the drag-and-drop sorting functionality within the popup list.
169
+ * This allows users to reorder the options in the list by dragging them into new positions.
170
+ * @type {boolean|undefined}
171
+ */
172
+ @property({ type: Boolean, attribute: 'sortable', reflect: true }) sortable?: boolean = false
155
173
 
156
174
  /**
157
175
  * The value(s) of the selected option(s) in the popup list.
@@ -165,6 +183,10 @@ export class OxPopupList extends OxPopup {
165
183
  @state() nothingToSelect: boolean = false
166
184
 
167
185
  @query('[search] input') searchInput!: HTMLInputElement
186
+ @query('div[body]') body!: HTMLDivElement
187
+
188
+ private sortableObject?: Sortable
189
+ private locked: boolean = false
168
190
 
169
191
  render() {
170
192
  return html`
@@ -193,12 +215,15 @@ export class OxPopupList extends OxPopup {
193
215
  `
194
216
  : html``}
195
217
 
196
- <slot
197
- @change=${(e: Event) => {
198
- e.stopPropagation()
199
- }}
200
- >
201
- </slot>
218
+ <div body>
219
+ <slot
220
+ @change=${(e: Event) => {
221
+ e.stopPropagation()
222
+ }}
223
+ >
224
+ </slot>
225
+ </div>
226
+
202
227
  ${this.nothingToSelect ? html`<label nothing>nothing to select</label>` : html``}
203
228
  `
204
229
  }
@@ -258,15 +283,20 @@ export class OxPopupList extends OxPopup {
258
283
  const to = e.relatedTarget as HTMLElement
259
284
 
260
285
  if (!this.contains(to)) {
261
- /* 분명히 범위가 아닌 엘리먼트로 포커스가 옮겨졌다면, ox-popup-list 닫혀야 한다. */
286
+ /* If the focus has clearly moved to an element outside of my range, the ox-popup-list should be closed. */
262
287
  // @ts-ignore for debug
263
- !window.POPUP_DEBUG && this.close()
288
+ !this.debug && !window.POPUP_DEBUG && this.close()
264
289
  }
265
290
  }.bind(this)
266
291
 
267
292
  protected _onclick: (e: MouseEvent) => void = function (this: OxPopupList, e: MouseEvent) {
268
293
  e.stopPropagation()
269
294
 
295
+ // Check if the click event target is a checkbox
296
+ if ((e.target as HTMLElement).closest('input[type="checkbox"]')) {
297
+ return // Do not proceed if it's a checkbox click
298
+ }
299
+
270
300
  const option = (e.target as HTMLElement)?.closest('[option]')
271
301
  if (option) {
272
302
  this.setActive(option, true)
@@ -279,6 +309,35 @@ export class OxPopupList extends OxPopup {
279
309
  this.activeIndex !== undefined && this.setActive(this.activeIndex)
280
310
  }
281
311
 
312
+ if (changes.has('sortable')) {
313
+ this.sortableObject && this.sortableObject.destroy()
314
+
315
+ if (this.sortable) {
316
+ this.sortableObject = Sortable.create(this, {
317
+ handle: '[option]',
318
+ draggable: '[option]',
319
+ direction: 'vertical',
320
+ animation: 150,
321
+ touchStartThreshold: 10,
322
+ onEnd: e => {
323
+ this.locked = false
324
+ this.dispatchEvent(
325
+ new CustomEvent('sorted', {
326
+ detail: Array.from(this.querySelectorAll('[option]'))
327
+ })
328
+ )
329
+ },
330
+ onMove: e => {
331
+ // Check if the drag event target is a checkbox
332
+ if ((e.dragged as HTMLElement).querySelector('input[type="checkbox"]')) {
333
+ return false // Prevent sorting if it's a checkbox drag
334
+ }
335
+ this.locked = true
336
+ }
337
+ })
338
+ }
339
+ }
340
+
282
341
  if (changes.has('searchKeyword')) {
283
342
  const attrSelected = this.attrSelected || 'selected'
284
343
  this.querySelectorAll(`[option]`).forEach(item => {
@@ -412,7 +471,8 @@ export class OxPopupList extends OxPopup {
412
471
  super.open(params)
413
472
 
414
473
  if (this.activeIndex === undefined) {
415
- this.activeIndex = 0
474
+ const activeElement = this.querySelector(`[${this.attrSelected || 'selected'}]`)
475
+ this.setActive(activeElement || 0)
416
476
  } else {
417
477
  this.setActive(this.activeIndex)
418
478
  }
@@ -424,6 +484,10 @@ export class OxPopupList extends OxPopup {
424
484
  * or logic in the application.
425
485
  */
426
486
  override close() {
487
+ if (this.locked) {
488
+ return
489
+ }
490
+
427
491
  if (this.hasAttribute('active')) {
428
492
  this.dispatchEvent(
429
493
  new CustomEvent('close', {
@@ -447,7 +511,12 @@ export class OxPopupList extends OxPopup {
447
511
  left,
448
512
  right,
449
513
  bottom,
450
- parent
514
+ parent,
515
+ multiple,
516
+ sortable,
517
+ attrSelected,
518
+ styles,
519
+ debug
451
520
  }: {
452
521
  template: unknown
453
522
  top?: number
@@ -455,9 +524,39 @@ export class OxPopupList extends OxPopup {
455
524
  right?: number
456
525
  bottom?: number
457
526
  parent?: Element | null
527
+ multiple?: boolean
528
+ sortable?: boolean
529
+ debug?: boolean
530
+ attrSelected?: string
531
+ styles: CSSResult
458
532
  }): OxPopupList {
459
533
  const owner = parent || document.body
460
534
  const target = document.createElement('ox-popup-list') as OxPopupList
535
+
536
+ if (styles) {
537
+ const style = document.createElement('style')
538
+ style.textContent = styles.cssText
539
+
540
+ const shadow = target.attachShadow({ mode: 'open' })
541
+ shadow.appendChild(style)
542
+ }
543
+
544
+ if (!!debug) {
545
+ target.setAttribute('debug', '')
546
+ }
547
+
548
+ if (!!multiple) {
549
+ target.setAttribute('multiple', '')
550
+ }
551
+
552
+ if (!!sortable) {
553
+ target.setAttribute('sortable', '')
554
+ }
555
+
556
+ if (attrSelected) {
557
+ target.setAttribute('attr-selected', attrSelected)
558
+ }
559
+
461
560
  render(template, target)
462
561
 
463
562
  target._parent = owner
@@ -27,13 +27,13 @@ export class OxPopupMenu extends OxPopup {
27
27
  display: none;
28
28
  flex-direction: column;
29
29
  align-items: stretch;
30
- background-color: var(--theme-white-color, #fff);
30
+ background-color: var(--ox-popup-menu-background-color, var(--md-sys-color-surface));
31
31
  z-index: 100;
32
32
  box-shadow: 2px 3px 10px 5px rgba(0, 0, 0, 0.15);
33
- padding: 4px 0;
33
+ padding: var(--spacing-small) 0;
34
34
 
35
- color: var(--theme-primary-text-color, #3c3938);
36
- font: normal 14px 'Roboto', sans-serif;
35
+ color: var(--ox-popup-list-color, var(--md-sys-color-primary-container));
36
+ font-size: var(--md-sys-typescale-label-large-size, 0.875rem);
37
37
  }
38
38
 
39
39
  :host([active]) {
@@ -45,37 +45,42 @@ export class OxPopupMenu extends OxPopup {
45
45
  }
46
46
 
47
47
  ::slotted(*) {
48
- padding: 5px 10px;
48
+ padding: var(--spacing-medium);
49
+ border-bottom: 1px solid var(--md-sys-color-surface-variant);
49
50
  cursor: pointer;
51
+ color: var(--ox-popup-list-color, var(--md-sys-color-outline-variant));
50
52
  }
51
53
 
52
54
  ::slotted(*:focus) {
55
+ cursor: pointer;
53
56
  outline: none;
54
57
  }
55
58
 
56
- ::slotted([menu][active]),
57
- ::slotted([menu]:hover) {
58
- background-color: #f6f6f6;
59
- }
60
-
61
59
  ::slotted([menu]),
62
60
  ::slotted(ox-popup-menuitem) {
63
61
  border-left: 3px solid transparent;
62
+ background-color: var(--ox-popup-menu-background-color, var(--md-sys-color-surface));
63
+ color: var(--ox-popup-menu-color, var(--md-sys-color-on-surface));
64
+ }
65
+
66
+ ::slotted([menu][active]),
67
+ ::slotted([menu]:hover),
68
+ ::slotted(ox-popup-menuitem[active]),
69
+ ::slotted(ox-popup-menuitem:hover) {
70
+ background-color: var(--ox-popup-list-background-color-variant, var(--md-sys-color-primary-container));
71
+ color: var(--ox-popup-list-color-variant, var(--md-sys-color-primary));
64
72
  }
65
73
 
66
74
  ::slotted(ox-popup-menuitem[active]) {
67
- border-left: 3px solid var(--primary-color, #38a25b);
68
- font-weight: bold;
75
+ border-left: 3px solid var(--md-ref-palette-primary50);
76
+ font-weight: var(--md-sys-typescale-label-large-weight, var(--md-ref-typeface-weight-medium, 500));
69
77
  }
70
78
 
71
79
  ::slotted([separator]) {
72
80
  height: 1px;
73
81
  width: 100%;
74
82
  padding: 0;
75
- background-color: rgba(0, 0, 0, 0.15);
76
- }
77
- ::slotted([menu] > input) {
78
- border: var(--border-dark-color, 1px solid rgba(0, 0, 0, 0.3));
83
+ background-color: var(--ox-popup-menu-separator-color, var(--md-sys-color-surface-variant));
79
84
  }
80
85
  `
81
86
  ]
@@ -23,7 +23,7 @@ export class OxPopupMenuItem extends LitElement {
23
23
  display: flex;
24
24
  flex-direction: row;
25
25
  padding: 0;
26
- margin: 0 4px 0 0;
26
+ margin: 0 var(--spacing-small) 0 0;
27
27
  align-items: center;
28
28
  justify-content: center;
29
29
  }
@@ -38,16 +38,16 @@ export class OxPopupMenuItem extends LitElement {
38
38
  }
39
39
 
40
40
  ::slotted(*[slot='icon']) {
41
- color: var(--secondary-color, #476172);
42
- font-size: 18px;
41
+ color: var(--ox-popup-menu-color-variant, var(--md-sys-color-on-surface-variant));
42
+ font-size: var(--icon-size-small);
43
43
  }
44
44
 
45
45
  md-icon {
46
46
  display: block;
47
47
  width: 24px;
48
48
  text-align: right;
49
- font-size: 18px;
50
- color: var(--theme-primary-text-color, #3c3938);
49
+ font-size: var(--icon-size-small);
50
+ color: var(--ox-popup-menu-color-variant, var(--md-sys-color-primary));
51
51
  opacity: 0.7;
52
52
  }
53
53
  `
package/src/ox-popup.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { css, html, LitElement } from 'lit'
2
2
  import { render } from 'lit-html'
3
- import { customElement, state } from 'lit/decorators.js'
3
+ import { customElement, property, state } from 'lit/decorators.js'
4
4
 
5
5
  import { ScrollbarStyles } from '@operato/styles'
6
6
 
@@ -21,7 +21,6 @@ export class OxPopup extends LitElement {
21
21
  :host {
22
22
  position: absolute;
23
23
  display: none;
24
- background-color: var(--theme-white-color, #fff);
25
24
  z-index: 100;
26
25
  padding: 0;
27
26
  box-shadow: 2px 3px 10px 5px rgba(0, 0, 0, 0.15);
@@ -29,10 +28,12 @@ export class OxPopup extends LitElement {
29
28
  min-width: fit-content;
30
29
  line-height: initial;
31
30
  text-align: initial;
31
+ background-color: var(--ox-popup-list-background-color, var(--md-sys-color-surface));
32
+ color: var(--ox-popup-list-color, var(--md-sys-color-primary-container));
32
33
  }
33
34
 
34
35
  :host([active]) {
35
- display: block;
36
+ display: flex;
36
37
  }
37
38
 
38
39
  :host(*:focus) {
@@ -41,6 +42,8 @@ export class OxPopup extends LitElement {
41
42
  `
42
43
  ]
43
44
 
45
+ @property({ type: Boolean }) debug: boolean = false
46
+
44
47
  @state() _parent: Element | null = null
45
48
 
46
49
  private lastActive: HTMLElement = document.activeElement as HTMLElement
@@ -55,7 +58,7 @@ export class OxPopup extends LitElement {
55
58
  if (!this.contains(to)) {
56
59
  /* 분명히 내 범위가 아닌 엘리먼트로 포커스가 옮겨졌다면, ox-popup은 닫혀야 한다. */
57
60
  // @ts-ignore for debug
58
- !window.POPUP_DEBUG && this.close()
61
+ !this.debug && !window.POPUP_DEBUG && this.close()
59
62
  }
60
63
  }.bind(this)
61
64
 
@@ -102,7 +105,7 @@ export class OxPopup extends LitElement {
102
105
 
103
106
  protected _onwindowblur: (e: Event) => void = function (this: OxPopup, e: Event) {
104
107
  // @ts-ignore for debug
105
- !window.POPUP_DEBUG && this.close()
108
+ !this.debug && !window.POPUP_DEBUG && this.close()
106
109
  }.bind(this)
107
110
 
108
111
  connectedCallback() {
@@ -249,19 +252,24 @@ export class OxPopup extends LitElement {
249
252
  const computedStyle = getComputedStyle(this)
250
253
 
251
254
  if (t < 0) {
252
- this.style.top = '0'
255
+ this.style.top = '10px'
253
256
  this.style.bottom = ''
254
257
  } else if (vh < t + h) {
255
- this.style.top = `calc(${computedStyle.top} - ${t + h - vh}px)` // 현재의 top 값에 차감한다.
258
+ this.style.top = `calc(${computedStyle.top} - ${t + h - vh + 10}px)` // 현재의 top 값에 차감한다.
256
259
  this.style.bottom = ''
260
+ // this.style.top = ''
261
+ // this.style.bottom = '10px'
257
262
  }
258
263
 
259
264
  if (l < 0) {
260
- this.style.left = `calc(${computedStyle.left} - ${l}px)` // 현재의 left 값에 l를 차감한다. (왼쪽으로 이탈했기 때문에 오른쪽으로 가야 화면에 보임)
265
+ this.style.left = `calc(${computedStyle.left} - ${l - 10}px)` // 현재의 left 값에 l를 차감한다. (왼쪽으로 이탈했기 때문에 오른쪽으로 가야 화면에 보임)
266
+ // this.style.left = '10px'
261
267
  this.style.right = ''
262
268
  } else if (vw < l + w) {
263
- this.style.left = `calc(${computedStyle.left} - ${l + w - vw}px)` // 현재의 left 값에 차감한다.
269
+ this.style.left = `calc(${computedStyle.left} - ${l + w - vw + 10}px)` // 현재의 left 값에 차감한다.
264
270
  this.style.right = ''
271
+ // this.style.left = ''
272
+ // this.style.right = '10px'
265
273
  }
266
274
  })
267
275