Skip to content

Commit 4b0cc8a

Browse files
committed
fix!: Place sort handle inside k-item boundaries
Fixes #7349 BREAKING CHANGE: DOM structure of `k-item` has been changes. An additional wrapper `.k-item-box` div was added.
1 parent 389aaba commit 4b0cc8a

File tree

1 file changed

+91
-72
lines changed

1 file changed

+91
-72
lines changed

panel/src/components/Collection/Item.vue

Lines changed: 91 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -11,66 +11,68 @@
1111
@click="onClick"
1212
@dragstart="$emit('drag', $event)"
1313
>
14-
<!-- Image -->
15-
<slot name="image">
16-
<k-item-image
17-
v-if="hasFigure"
18-
:image="image"
19-
:layout="layout"
20-
:width="width"
21-
/>
22-
</slot>
23-
2414
<!-- Sort handle -->
2515
<k-sort-handle v-if="sortable" class="k-item-sort-handle" tabindex="-1" />
2616

27-
<!-- Content -->
28-
<div class="k-item-content">
29-
<h3 class="k-item-title" :title="title(text)">
30-
<k-link
31-
v-if="link !== false && selecting !== true"
32-
:target="target"
33-
:to="link"
34-
>
17+
<div class="k-item-wrapper">
18+
<!-- Image -->
19+
<slot name="image">
20+
<k-item-image
21+
v-if="hasFigure"
22+
:image="image"
23+
:layout="layout"
24+
:width="width"
25+
/>
26+
</slot>
27+
28+
<!-- Content -->
29+
<div class="k-item-content">
30+
<h3 class="k-item-title" :title="title(text)">
31+
<k-link
32+
v-if="link !== false && selecting !== true"
33+
:target="target"
34+
:to="link"
35+
>
36+
<!-- eslint-disable-next-line vue/no-v-html -->
37+
<span v-html="text ?? '–'" />
38+
</k-link>
3539
<!-- eslint-disable-next-line vue/no-v-html -->
36-
<span v-html="text ?? '–'" />
37-
</k-link>
40+
<span v-else v-html="text ?? '–'" />
41+
</h3>
3842
<!-- eslint-disable-next-line vue/no-v-html -->
39-
<span v-else v-html="text ?? '–'" />
40-
</h3>
41-
<!-- eslint-disable-next-line vue/no-v-html -->
42-
<p v-if="info" :title="title(info)" class="k-item-info" v-html="info" />
43-
</div>
44-
45-
<div
46-
v-if="buttons?.length || options || $slots.options || selecting"
47-
class="k-item-options"
48-
>
49-
<!-- Buttons -->
50-
<k-button
51-
v-for="(button, buttonIndex) in buttons"
52-
:key="'button-' + buttonIndex"
53-
v-bind="button"
54-
/>
43+
<p v-if="info" :title="title(info)" class="k-item-info" v-html="info" />
44+
</div>
5545

56-
<label v-if="selecting" class="k-item-options-checkbox" @click.stop>
57-
<input
58-
ref="selector"
59-
type="checkbox"
60-
:disabled="!selectable"
61-
@change="$emit('select', $event)"
46+
<div
47+
v-if="buttons?.length || options || $slots.options || selecting"
48+
class="k-item-options"
49+
>
50+
<!-- Buttons -->
51+
<k-button
52+
v-for="(button, buttonIndex) in buttons"
53+
:key="'button-' + buttonIndex"
54+
v-bind="button"
6255
/>
63-
</label>
6456

65-
<!-- Options -->
66-
<slot v-else name="options">
67-
<k-options-dropdown
68-
v-if="options"
69-
:options="options"
70-
class="k-item-options-dropdown"
71-
@option="onOption"
72-
/>
73-
</slot>
57+
<label v-if="selecting" class="k-item-options-checkbox" @click.stop>
58+
<input
59+
ref="selector"
60+
type="checkbox"
61+
:disabled="!selectable"
62+
@change="$emit('select', $event)"
63+
/>
64+
</label>
65+
66+
<!-- Options -->
67+
<slot v-else name="options">
68+
<k-options-dropdown
69+
v-if="options"
70+
:options="options"
71+
class="k-item-options-dropdown"
72+
@option="onOption"
73+
/>
74+
</slot>
75+
</div>
7476
</div>
7577
</div>
7678
</template>
@@ -179,16 +181,25 @@ export default {
179181
180182
.k-item {
181183
position: relative;
182-
background: var(--item-color-back);
183-
box-shadow: var(--item-shadow);
184-
border-radius: var(--rounded);
185184
min-height: var(--item-height);
186-
container-type: inline-size;
187185
}
188186
.k-item:has(a:focus) {
189187
outline: 2px solid var(--color-focus);
190188
}
191189
190+
.k-item:not(:hover):not(.k-sortable-fallback) .k-sort-button {
191+
opacity: 0;
192+
}
193+
194+
.k-item-wrapper {
195+
position: relative;
196+
width: 100%;
197+
background: var(--item-color-back);
198+
box-shadow: var(--item-shadow);
199+
border-radius: var(--rounded);
200+
container-type: inline-size;
201+
}
202+
192203
.k-item .k-icon-frame {
193204
--back: var(--color-gray-300);
194205
}
@@ -224,16 +235,17 @@ export default {
224235
--button-width: var(--item-button-width);
225236
}
226237
227-
.k-item .k-sort-button {
228-
position: absolute;
229-
z-index: 2;
230-
}
231-
.k-item:not(:hover):not(.k-sortable-fallback) .k-sort-button {
232-
opacity: 0;
233-
}
234-
235238
/** List */
236239
.k-item[data-layout="list"] {
240+
--item-sort-button-width: calc(1.5rem + var(--spacing-1));
241+
242+
display: flex;
243+
align-items: center;
244+
}
245+
.k-item[data-layout="list"]:has(.k-item-sort-handle) {
246+
margin-inline-start: calc(-1 * var(--item-sort-button-width));
247+
}
248+
.k-item[data-layout="list"] .k-item-wrapper {
237249
--item-height: var(
238250
--field-input-height
239251
); /* TODO: change back to --height-md after input refactoring */
@@ -244,7 +256,11 @@ export default {
244256
align-items: center;
245257
grid-template-columns: 1fr auto;
246258
}
247-
.k-item[data-layout="list"][data-has-image="true"] {
259+
.k-item[data-layout="list"] .k-sort-button {
260+
--button-width: var(--item-sort-button-width);
261+
--button-height: var(--item-height);
262+
}
263+
.k-item[data-layout="list"][data-has-image="true"] .k-item-wrapper {
248264
grid-template-columns: var(--item-height) 1fr auto;
249265
}
250266
.k-item[data-layout="list"] .k-frame {
@@ -272,11 +288,6 @@ export default {
272288
flex-direction: column;
273289
}
274290
}
275-
.k-item[data-layout="list"] .k-sort-button {
276-
--button-width: calc(1.5rem + var(--spacing-1));
277-
--button-height: var(--item-height);
278-
left: calc(-1 * var(--button-width));
279-
}
280291
281292
/** Cardlet & cards */
282293
.k-item:is([data-layout="cardlets"], [data-layout="cards"]) .k-sort-button {
@@ -293,6 +304,11 @@ export default {
293304
--icon-size: 14px;
294305
}
295306
307+
.k-item:is([data-layout="cardlets"], [data-layout="cards"]) .k-sort-button {
308+
position: absolute;
309+
z-index: 2;
310+
}
311+
296312
.k-item:is([data-layout="cardlets"], [data-layout="cards"])
297313
.k-sort-button:hover {
298314
background: hsla(0, 0%, light-dark(100%, 7%), 95%);
@@ -301,14 +317,16 @@ export default {
301317
/** Cardlet */
302318
.k-item[data-layout="cardlets"] {
303319
--item-height: var(--item-height-cardlet);
320+
}
321+
.k-item[data-layout="cardlets"] .k-item-wrapper {
304322
display: grid;
305323
grid-template-areas:
306324
"content"
307325
"options";
308326
grid-template-columns: 1fr;
309327
grid-template-rows: 1fr var(--height-md);
310328
}
311-
.k-item[data-layout="cardlets"][data-has-image="true"] {
329+
.k-item[data-layout="cardlets"][data-has-image="true"] .k-item-wrapper {
312330
grid-template-areas:
313331
"image content"
314332
"image options";
@@ -331,6 +349,7 @@ export default {
331349
}
332350
.k-item[data-layout="cardlets"] .k-item-options {
333351
grid-area: options;
352+
justify-content: flex-end;
334353
}
335354
336355
/** Card */
@@ -352,7 +371,7 @@ export default {
352371
}
353372
354373
/** Theme: disabled */
355-
.k-item[data-theme="disabled"] {
374+
.k-item[data-theme="disabled"] .k-item-wrapper {
356375
background: transparent;
357376
box-shadow: none;
358377
outline: 1px solid var(--color-border);

0 commit comments

Comments
 (0)