@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.
- package/CHANGELOG.md +246 -0
- package/dist/src/ox-floating-overlay.js +17 -14
- package/dist/src/ox-floating-overlay.js.map +1 -1
- package/dist/src/ox-popup-list.d.ts +17 -3
- package/dist/src/ox-popup-list.js +109 -31
- package/dist/src/ox-popup-list.js.map +1 -1
- package/dist/src/ox-popup-menu.js +21 -16
- package/dist/src/ox-popup-menu.js.map +1 -1
- package/dist/src/ox-popup-menuitem.js +5 -5
- package/dist/src/ox-popup-menuitem.js.map +1 -1
- package/dist/src/ox-popup.d.ts +1 -0
- package/dist/src/ox-popup.js +19 -9
- package/dist/src/ox-popup.js.map +1 -1
- package/dist/src/ox-prompt.js +68 -28
- package/dist/src/ox-prompt.js.map +1 -1
- package/dist/stories/open-popup.stories.d.ts +6 -0
- package/dist/stories/open-popup.stories.js +26 -6
- package/dist/stories/open-popup.stories.js.map +1 -1
- package/dist/stories/ox-popup-list-sortable.stories.d.ts +24 -0
- package/dist/stories/ox-popup-list-sortable.stories.js +169 -0
- package/dist/stories/ox-popup-list-sortable.stories.js.map +1 -0
- package/dist/stories/ox-popup-list.stories.d.ts +8 -2
- package/dist/stories/ox-popup-list.stories.js +52 -32
- package/dist/stories/ox-popup-list.stories.js.map +1 -1
- package/dist/stories/ox-popup-menu.stories.d.ts +8 -2
- package/dist/stories/ox-popup-menu.stories.js +26 -7
- package/dist/stories/ox-popup-menu.stories.js.map +1 -1
- package/dist/stories/ox-popup.stories.d.ts +8 -1
- package/dist/stories/ox-popup.stories.js +47 -13
- package/dist/stories/ox-popup.stories.js.map +1 -1
- package/dist/stories/ox-prompt-icon.stories.d.ts +6 -0
- package/dist/stories/ox-prompt-icon.stories.js +24 -9
- package/dist/stories/ox-prompt-icon.stories.js.map +1 -1
- package/dist/stories/ox-prompt-normal.stories.d.ts +8 -1
- package/dist/stories/ox-prompt-normal.stories.js +25 -7
- package/dist/stories/ox-prompt-normal.stories.js.map +1 -1
- package/dist/stories/ox-prompt.stories.d.ts +7 -1
- package/dist/stories/ox-prompt.stories.js +26 -9
- package/dist/stories/ox-prompt.stories.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +5 -4
- package/src/ox-floating-overlay.ts +17 -14
- package/src/ox-popup-list.ts +133 -34
- package/src/ox-popup-menu.ts +21 -16
- package/src/ox-popup-menuitem.ts +5 -5
- package/src/ox-popup.ts +17 -9
- package/src/ox-prompt.ts +71 -28
- package/stories/open-popup.stories.ts +28 -6
- package/stories/ox-popup-list-sortable.stories.ts +188 -0
- package/stories/ox-popup-list.stories.ts +55 -34
- package/stories/ox-popup-menu.stories.ts +29 -8
- package/stories/ox-popup.stories.ts +51 -16
- package/stories/ox-prompt-icon.stories.ts +30 -9
- package/stories/ox-prompt-normal.stories.ts +28 -8
- package/stories/ox-prompt.stories.ts +30 -10
- package/themes/dark-hc.css +151 -0
- package/themes/dark-mc.css +151 -0
- package/themes/dark.css +151 -0
- package/themes/grist-theme.css +173 -0
- package/themes/light-hc.css +151 -0
- package/themes/light-mc.css +151 -0
- package/themes/light.css +151 -0
- package/themes/md-typescale-styles.css +100 -0
- package/themes/spacing.css +43 -0
- package/themes/state-color.css +6 -0
- package/themes/app-theme.css +0 -145
- package/themes/input-theme.css +0 -19
- 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-
|
|
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-
|
|
64
|
-
"@operato/utils": "^2.0.0-
|
|
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": "
|
|
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(--
|
|
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:
|
|
101
|
-
--help-icon-hover-color:
|
|
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
|
-
|
|
190
|
-
color: var(--
|
|
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
|
-
|
|
208
|
-
|
|
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:
|
|
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:
|
|
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-
|
|
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-
|
|
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
|
|
246
|
+
padding: 0 var(--spacing-medium);
|
|
244
247
|
}
|
|
245
248
|
|
|
246
249
|
[search] > * {
|
package/src/ox-popup-list.ts
CHANGED
|
@@ -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.
|
|
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.
|
|
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(--
|
|
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:
|
|
42
|
-
|
|
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:
|
|
66
|
-
border-bottom: 1px solid
|
|
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:
|
|
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(--
|
|
82
|
-
font-weight:
|
|
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:
|
|
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:
|
|
105
|
+
padding: var(--spacing-small) var(--spacing-medium);
|
|
104
106
|
|
|
105
|
-
--md-icon-size:
|
|
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
|
|
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(--
|
|
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:
|
|
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
|
-
<
|
|
197
|
-
|
|
198
|
-
e
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
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
|
-
/*
|
|
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.
|
|
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
|
package/src/ox-popup-menu.ts
CHANGED
|
@@ -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(--
|
|
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:
|
|
33
|
+
padding: var(--spacing-small) 0;
|
|
34
34
|
|
|
35
|
-
color: var(--
|
|
36
|
-
font:
|
|
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:
|
|
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(--
|
|
68
|
-
font-weight:
|
|
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:
|
|
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
|
]
|
package/src/ox-popup-menuitem.ts
CHANGED
|
@@ -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
|
|
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(--
|
|
42
|
-
font-size:
|
|
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:
|
|
50
|
-
color: var(--
|
|
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:
|
|
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 = '
|
|
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
|
|