Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
169 changes: 95 additions & 74 deletions panel/src/components/Collection/Item.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,66 +11,68 @@
@click="onClick"
@dragstart="$emit('drag', $event)"
>
<!-- Image -->
<slot name="image">
<k-item-image
v-if="hasFigure"
:image="image"
:layout="layout"
:width="width"
/>
</slot>

<!-- Sort handle -->
<k-sort-handle v-if="sortable" class="k-item-sort-handle" tabindex="-1" />

<!-- Content -->
<div class="k-item-content">
<h3 class="k-item-title" :title="title(text)">
<k-link
v-if="link !== false && selecting !== true"
:target="target"
:to="link"
>
<div class="k-item-box">
<!-- Image -->
<slot name="image">
<k-item-image
v-if="hasFigure"
:image="image"
:layout="layout"
:width="width"
/>
</slot>

<!-- Content -->
<div class="k-item-content">
<h3 class="k-item-title" :title="title(text)">
<k-link
v-if="link !== false && selecting !== true"
:target="target"
:to="link"
>
<!-- eslint-disable-next-line vue/no-v-html -->
<span v-html="text ?? '–'" />
</k-link>
<!-- eslint-disable-next-line vue/no-v-html -->
<span v-html="text ?? '–'" />
</k-link>
<span v-else v-html="text ?? '–'" />
</h3>
<!-- eslint-disable-next-line vue/no-v-html -->
<span v-else v-html="text ?? '–'" />
</h3>
<!-- eslint-disable-next-line vue/no-v-html -->
<p v-if="info" :title="title(info)" class="k-item-info" v-html="info" />
</div>

<div
v-if="buttons?.length || options || $slots.options || selecting"
class="k-item-options"
>
<!-- Buttons -->
<k-button
v-for="button in buttons"
:key="JSON.stringify(button)"
v-bind="button"
/>
<p v-if="info" :title="title(info)" class="k-item-info" v-html="info" />
</div>

<label v-if="selecting" class="k-item-options-checkbox" @click.stop>
<input
ref="selector"
type="checkbox"
:disabled="!selectable"
@change="$emit('select', $event)"
<div
v-if="buttons?.length || options || $slots.options || selecting"
class="k-item-options"
>
<!-- Buttons -->
<k-button
v-for="button in buttons"
:key="JSON.stringify(button)"
v-bind="button"
/>
</label>

<!-- Options -->
<slot v-else name="options">
<k-options-dropdown
v-if="options"
:options="options"
class="k-item-options-dropdown"
@option="onOption"
/>
</slot>
<label v-if="selecting" class="k-item-options-checkbox" @click.stop>
<input
ref="selector"
type="checkbox"
:disabled="!selectable"
@change="$emit('select', $event)"
/>
</label>

<!-- Options -->
<slot v-else name="options">
<k-options-dropdown
v-if="options"
:options="options"
class="k-item-options-dropdown"
@option="onOption"
/>
</slot>
</div>
</div>
</div>
</template>
Expand Down Expand Up @@ -179,16 +181,25 @@ export default {

.k-item {
position: relative;
background: var(--item-color-back);
box-shadow: var(--item-shadow);
border-radius: var(--rounded);
min-height: var(--item-height);
container-type: inline-size;
}
.k-item:has(a:focus) {
outline: 2px solid var(--color-focus);
}

.k-item:not(:hover):not(.k-sortable-fallback) .k-item-sort-handle {
opacity: 0;
}

.k-item-box {
position: relative;
width: 100%;
background: var(--item-color-back);
box-shadow: var(--item-shadow);
border-radius: var(--rounded);
container-type: inline-size;
}

.k-item .k-icon-frame {
--back: var(--color-gray-300);
}
Expand Down Expand Up @@ -224,16 +235,17 @@ export default {
--button-width: var(--item-button-width);
}

.k-item .k-sort-button {
position: absolute;
z-index: 2;
}
.k-item:not(:hover):not(.k-sortable-fallback) .k-sort-button {
opacity: 0;
}

/** List */
.k-item[data-layout="list"] {
--item-sort-button-width: calc(1.5rem + var(--spacing-1));

display: flex;
align-items: center;
}
.k-item[data-layout="list"]:has(.k-item-sort-handle) {
margin-inline-start: calc(-1 * var(--item-sort-button-width));
}
.k-item[data-layout="list"] .k-item-box {
--item-height: var(
--field-input-height
); /* TODO: change back to --height-md after input refactoring */
Expand All @@ -244,7 +256,11 @@ export default {
align-items: center;
grid-template-columns: 1fr auto;
}
.k-item[data-layout="list"][data-has-image="true"] {
.k-item[data-layout="list"] .k-item-sort-handle {
--button-width: var(--item-sort-button-width);
--button-height: var(--item-height);
}
.k-item[data-layout="list"][data-has-image="true"] .k-item-box {
grid-template-columns: var(--item-height) 1fr auto;
}
.k-item[data-layout="list"] .k-frame {
Expand Down Expand Up @@ -272,14 +288,10 @@ export default {
flex-direction: column;
}
}
.k-item[data-layout="list"] .k-sort-button {
--button-width: calc(1.5rem + var(--spacing-1));
--button-height: var(--item-height);
left: calc(-1 * var(--button-width));
}

/** Cardlet & cards */
.k-item:is([data-layout="cardlets"], [data-layout="cards"]) .k-sort-button {
.k-item:is([data-layout="cardlets"], [data-layout="cards"])
.k-item-sort-handle {
top: var(--spacing-2);
inset-inline-start: var(--spacing-2);
color: light-dark(var(--color-black), var(--color-white));
Expand All @@ -294,21 +306,29 @@ export default {
}

.k-item:is([data-layout="cardlets"], [data-layout="cards"])
.k-sort-button:hover {
.k-item-sort-handle {
position: absolute;
z-index: 2;
}

.k-item:is([data-layout="cardlets"], [data-layout="cards"])
.k-item-sort-handle:hover {
background: hsla(0, 0%, light-dark(100%, 7%), 95%);
}

/** Cardlet */
.k-item[data-layout="cardlets"] {
--item-height: var(--item-height-cardlet);
}
.k-item[data-layout="cardlets"] .k-item-box {
display: grid;
grid-template-areas:
"content"
"options";
grid-template-columns: 1fr;
grid-template-rows: 1fr var(--height-md);
}
.k-item[data-layout="cardlets"][data-has-image="true"] {
.k-item[data-layout="cardlets"][data-has-image="true"] .k-item-box {
grid-template-areas:
"image content"
"image options";
Expand All @@ -331,6 +351,7 @@ export default {
}
.k-item[data-layout="cardlets"] .k-item-options {
grid-area: options;
justify-content: flex-end;
}

/** Card */
Expand All @@ -352,7 +373,7 @@ export default {
}

/** Theme: disabled */
.k-item[data-theme="disabled"] {
.k-item[data-theme="disabled"] .k-item-box {
background: transparent;
box-shadow: none;
outline: 1px solid var(--color-border);
Expand Down
Loading