Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
0d64ced
First pass
jaygeorge Aug 27, 2026
594b7b0
Merge branch '6.x' into replicator-set-widths
jaygeorge Aug 28, 2026
fca82a4
Improve appearance
jaygeorge Aug 28, 2026
a209114
Reset replicator layout
jaygeorge Aug 28, 2026
bedc4b7
Wrapping a container around the first and last item of a set with a c…
jaygeorge Aug 28, 2026
2938557
Remove line connectors for replicator cards
jaygeorge Aug 28, 2026
de7903a
Get the CSS working
jaygeorge Aug 28, 2026
6b36382
Shift output toggle to overflow menu for cards so we have a bit more …
jaygeorge Aug 28, 2026
b009060
Fix missing connector line
jaygeorge Aug 28, 2026
cb91ed9
Fix drag and drop not working
jaygeorge Aug 28, 2026
f011af7
Back to grid
jaygeorge Aug 28, 2026
c6191d6
🏁 Fix vertical drag for single replicator card sets
jaygeorge Aug 29, 2026
51848c2
🏁 Switch things so you can drag cards in and out of card sets
jaygeorge Sep 1, 2026
314329a
Get the insert handle working again
jaygeorge Sep 1, 2026
d9e52b9
🏁 Show left insert handle on every card in a row
jaygeorge Sep 1, 2026
e4be3e5
Fix gaps
jaygeorge Sep 1, 2026
21e9062
TRICKSY LITTLE HOBBITSES
jaygeorge Sep 1, 2026
a5f96b2
Get connector back
jaygeorge Sep 1, 2026
5b16ead
Tidy CSS
jaygeorge Sep 1, 2026
3c10e35
Increase insert handle thickness slightly
jaygeorge Sep 1, 2026
dd60d50
Wrap container queries
jaygeorge Sep 1, 2026
5172b30
Restore layout on smaller containers
jaygeorge Sep 1, 2026
faceaf2
Columns should span full width when cards kick in
jaygeorge Sep 1, 2026
0640146
Tidy instructions
jaygeorge Sep 1, 2026
22a21a1
Collapse/expand all replicator cards at once
jaygeorge Sep 1, 2026
c4834a7
Fix scope of publish field columns
jaygeorge Sep 1, 2026
0817802
Scope card field columns to card slot publish fields
jaygeorge Sep 1, 2026
2561b0a
Extract replicator card layout helpers for testing
jaygeorge Sep 1, 2026
d29fe4c
Fix card row collapse grouping and drag reorder recovery
jaygeorge Sep 1, 2026
04f2040
Add trailing newline to cards icon SVG
jaygeorge Sep 1, 2026
700161c
Restore some CSS needed
jaygeorge Sep 1, 2026
c35d377
Scope replicator card layout to Replicator fields only
jaygeorge Sep 2, 2026
4916e96
Merge branch '6.x' into replicator-card-layout
jaygeorge Sep 2, 2026
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
1 change: 1 addition & 0 deletions lang/en/messages.php
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@
'publish_actions_publish' => 'Changes to the working copy will be applied to the entry and it will be published immediately.',
'publish_actions_schedule' => 'Changes to the working copy will be applied to the entry and it will appear published on the selected date.',
'publish_actions_unpublish' => 'The current revision will be unpublished.',
'replicator_set_card_layout_instructions' => 'In a Replicator field, stacked instances of this set are displayed side by side as cards when there’s enough space.',
'relationship_item_unavailable' => 'This item is unavailable. It may have been deleted, or you may not have permission to view it.',
'reset_password_notification_body' => 'You are receiving this email because we received a password reset request for your account.',
'reset_password_notification_no_action' => 'If you did not request a password reset, no further action is required.',
Expand Down
106 changes: 106 additions & 0 deletions resources/css/components/fieldtypes/replicator-card-sets.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
/* GROUP REPLICATOR CARD SETS
=================================================== */
.replicator-card-set-row-start {
--pull: 1.5rem;

&:not(.replicator-card-set-has-entry-connector) {
[data-ui-popover-trigger] {
position: absolute;
z-index: var(--z-index-above);
transform: translateY(calc(0% - var(--pull)));
width: 100%;
}
}

&.replicator-card-set-has-entry-connector {
[data-ui-popover-trigger] {
position: relative;
z-index: var(--z-index-above);
width: 100%;
}
}
}

@container panel (width > 635px) {
.replicator-set-list {
display: flex;
flex-wrap: wrap;
column-gap: 0.75rem;
align-items: start;
}

.replicator-set-slot--full,
.replicator-set-slot--card-cols-1 {
width: 100%;
min-width: 0;
}

.replicator-set-slot--card-cols-2,
.replicator-set-slot--card-cols-3 {
width: calc((100% - 0.75rem) / 2);
min-width: 0;
}

@container panel (width > 935px) {
.replicator-set-slot--card-cols-3 {
width: calc((100% - 1.5rem) / 3);
min-width: 0;
}
}

.replicator-set-slot--full,
.replicator-set-slot--card-cols-1,
.replicator-set-slot--card-cols-2,
.replicator-set-slot--card-cols-3 {
.publish-fields {
/* Prevent columns and gaps exceeding the container */
grid-column-gap: unset;

* {
--col-span: 12;
}
}
}

.replicator-card-set-inset-picker:not(.replicator-card-set-row-start) {
position: relative;
margin-block-start: 1.5rem;

[data-replicator-connector] {
display: none;
}

[data-ui-popover-trigger] {
position: absolute;
inset: 0;
left: -1.15rem;
writing-mode: vertical-lr;

[data-insert-handle] {
position: absolute;
top: 0;
left: calc(0.5rem + 2px);
height: 100%;
width: 0.325rem;
background: linear-gradient(to bottom, var(--color-gray-200) 0%, var(--color-gray-100) 50%, var(--color-gray-200) 100%);
}
}

/* Nudge to account for rounding error / subpixel positioning */
&:nth-child(3n + 1) [data-ui-popover-trigger] {
[data-insert-handle] {
left: calc(0.5rem + 1.5px);
}
}
}

.replicator-card-set-row-start.replicator-card-set-has-entry-connector {
&.replicator-set-slot--card-cols-2 [data-ui-popover-trigger] {
width: calc(200% + 0.75rem);
}

&.replicator-set-slot--card-cols-3 [data-ui-popover-trigger] {
width: calc(300% + 1.5rem);
}
}
}
3 changes: 0 additions & 3 deletions resources/css/components/fieldtypes/replicator.css

This file was deleted.

1 change: 1 addition & 0 deletions resources/css/cp.css
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
@import './components/fieldtypes/markdown.css';
@import './components/fieldtypes/partial.css';
@import './components/fieldtypes/relationship.css';
@import './components/fieldtypes/replicator-card-sets.css';
@import './components/fieldtypes/section.css';
@import './components/fieldtypes/table.css';
@import './components/fieldtypes/width.css';
27 changes: 25 additions & 2 deletions resources/js/components/blueprints/Section.vue
Original file line number Diff line number Diff line change
@@ -1,11 +1,21 @@
<template>
<div class="blueprint-section min-h-40 w-full outline-hidden @container" tabindex="-1">
<div
class="blueprint-section min-h-40 outline-hidden @container w-full"
tabindex="-1"
>
<ui-panel>
<ui-panel-header class="flex items-center justify-between pl-2.75! pr-3.25!">
<div class="flex items-center gap-2 flex-1">
<div class="flex items-center gap-2 flex-1 min-w-0">
<ui-icon name="handles-sm" class="blueprint-section-drag-handle size-3! cursor-grab text-gray-400" />
<ui-icon :name="section.icon" :set="iconSet" v-if="section.icon" />
<ui-heading v-text="__(section.display ?? 'Section')" />
<ui-badge
v-if="showCardField && card"
pill
icon="cards"
:text="__('Card')"
color="white"
/>
</div>
<ui-button icon="pencil-line" size="sm" variant="ghost" @click="edit" />
<ui-button icon="trash" size="sm" variant="ghost" @click.prevent="$emit('deleted')" />
Expand Down Expand Up @@ -70,6 +80,13 @@
<ui-field :label="__('Instructions')">
<ui-input type="text" v-model="editingSection.instructions" />
</ui-field>
<ui-field
:label="__('Card layout')"
:instructions="__('messages.replicator_set_card_layout_instructions')"
v-if="showCardField"
>
<ui-switch v-model="editingSection.card" />
</ui-field>
<ui-field :label="__('Collapsible')" v-if="showCollapsibleField">
<ui-switch v-model="editingSection.collapsible" />
</ui-field>
Expand Down Expand Up @@ -156,6 +173,7 @@ export default {
tabId: { type: String },
section: { type: Object, required: true },
showHandleField: { type: Boolean, default: false },
showCardField: { type: Boolean, default: false },
showCollapsibleField: { type: Boolean, default: false },
showHideField: { type: Boolean, default: false },
editText: { type: String },
Expand Down Expand Up @@ -193,6 +211,10 @@ export default {
const stacks = this.$stacks.stacks();
return stacks.length === 1 && stacks[0]?.data?.vm?.size === 'narrow';
},

card() {
return this.section.card ?? false;
},
},

watch: {
Expand Down Expand Up @@ -269,6 +291,7 @@ export default {
icon: this.section.icon,
image: this.section.image,
hide: this.section.hide,
card: this.section.card ?? false,
collapsible: this.section.collapsible,
collapsed: this.section.collapsed,
};
Expand Down
16 changes: 14 additions & 2 deletions resources/js/components/blueprints/Sections.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
<template>
<div>
<div ref="sections" class="blueprint-sections flex flex-wrap outline-hidden" :data-tab="tabId" tabindex="-1">
<div
ref="sections"
class="blueprint-sections outline-hidden"
:class="showSectionHandleField ? 'field-grid' : 'flex flex-wrap'"
:data-tab="tabId"
tabindex="-1"
>
<BlueprintSection
ref="section"
v-for="(section, i) in sections"
Expand All @@ -9,6 +15,7 @@
:can-define-localizable="canDefineLocalizable"
:tab-id="tabId"
:show-handle-field="showSectionHandleField"
:show-card-field="showSectionCardField"
:show-collapsible-field="showSectionCollapsibleField"
:show-hide-field="showSectionHideField"
:exclude-fieldset="excludeFieldset"
Expand All @@ -18,7 +25,7 @@
@deleted="deleteSection(i)"
/>

<div class="blueprint-add-section-container w-full">
<div class="blueprint-add-section-container" :class="showSectionHandleField ? 'field-w-100' : 'w-full'">
<button class="blueprint-add-section-button" @click="addAndEditSection">
<div class="flex items-center gap-2">
<ui-icon name="plus" class="size-4" />
Expand Down Expand Up @@ -73,6 +80,10 @@ export default {
showSectionHandleField: {
type: Boolean,
default: false,
},
showSectionCardField: {
type: Boolean,
default: false,
},
showSectionCollapsibleField: {
type: Boolean,
Expand Down Expand Up @@ -114,6 +125,7 @@ export default {
collapsed: false,
icon: null,
hide: null,
card: false,
handle: snake_case(this.newSectionText),
fields: [],
};
Expand Down
5 changes: 5 additions & 0 deletions resources/js/components/blueprints/TabContent.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
:add-section-text="addSectionText"
:edit-section-text="editSectionText"
:show-section-handle-field="showSectionHandleField"
:show-section-card-field="showSectionCardField"
:show-section-collapsible-field="showSectionCollapsibleField"
:show-section-hide-field="showSectionHideField"
:can-define-localizable="canDefineLocalizable"
Expand Down Expand Up @@ -36,6 +37,10 @@ export default {
showSectionHandleField: {
type: Boolean,
default: false,
},
showSectionCardField: {
type: Boolean,
default: false,
},
showSectionCollapsibleField: {
type: Boolean,
Expand Down
5 changes: 5 additions & 0 deletions resources/js/components/blueprints/Tabs.vue
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@
:tab="tab"
v-show="currentTab === tab._id"
:show-section-handle-field="showSectionHandleField"
:show-section-card-field="showSectionCardField"
:show-section-collapsible-field="showSectionCollapsibleField"
:show-section-hide-field="showSectionHideField"
:new-section-text="newSectionText"
Expand Down Expand Up @@ -154,6 +155,10 @@ export default {
showSectionHandleField: {
type: Boolean,
default: false,
},
showSectionCardField: {
type: Boolean,
default: false,
},
showSectionCollapsibleField: {
type: Boolean,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
>
<div
v-if="showConnector"
data-replicator-connector
class="absolute group-focus-within:opacity-0 transition-opacity group-focus-within:transition-none delay-10 duration-250 inset-y-0 left-3.5 border-l-1 border-gray-400 dark:border-gray-600 border-dashed z-0 dark:bg-gray-850"
:class="{
'group-hover:opacity-0': enabled,
Expand All @@ -30,7 +31,7 @@
tabindex="-1"
>
<div class="h-full flex flex-col justify-center">
<div class="rounded-full bg-[linear-gradient(90deg,theme(colors.gray.100)_0%,theme(colors.gray.200)_50%,theme(colors.gray.100)_100%)] dark:bg-[linear-gradient(90deg,theme(colors.gray.800)_0%,theme(colors.gray.700)_50%,theme(colors.gray.800)_100%)] h-2" />
<div data-insert-handle class="rounded-full bg-[linear-gradient(90deg,theme(colors.gray.100)_0%,theme(colors.gray.200)_50%,theme(colors.gray.100)_100%)] dark:bg-[linear-gradient(90deg,theme(colors.gray.800)_0%,theme(colors.gray.700)_50%,theme(colors.gray.800)_100%)] h-2" />
</div>
</button>
<Button v-if="enabled" round icon="plus" size="sm" class="-my-4 z-3 opacity-0 group-hover:opacity-100 focus:opacity-100 transition-opacity delay-10 duration-250" />
Expand Down
Loading
Loading