Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[5.x] Add custom icon selection to CP Nav Preferences #8023

Merged
merged 28 commits into from
Aug 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
0713da1
Add icon picker to CP nav item editor.
jesseleite Apr 28, 2023
8b1c419
Revert "Add icon picker to CP nav item editor."
jesseleite Apr 28, 2023
009eada
Re-add icon picker to item editor.
jesseleite Apr 28, 2023
b0497f2
Clone config so that it doesn’t get changed in tree until event is em…
jesseleite Apr 28, 2023
ba7cd84
Ensure custom icon is shown in tree and saved in item manipulations.
jesseleite Apr 28, 2023
c91618a
Fix `<svg-icon>` references in nav item branches.
jesseleite Apr 28, 2023
193ff20
These slashes aren’t needed.
jesseleite Apr 28, 2023
1491e10
Extract renderable svg logic in `NavItem` to `svg()` method.
jesseleite Apr 28, 2023
eab9294
Use new `svg()` method for rendering nav icons.
jesseleite Apr 28, 2023
69fd257
Use new `svg()` icon in custom `Updates` nav item view.
jesseleite Apr 28, 2023
4f584a5
Test the newly updated `icon()` and `svg()` methods on `NavItem`.
jesseleite Apr 28, 2023
6f5d6ed
Fix reactivity issue on newly created nav items.
jesseleite May 3, 2023
8c12e45
Show original icon when necessary.
jesseleite May 3, 2023
18e7ba0
Don’t show icons on child items.
jesseleite May 3, 2023
c8222b8
Don’t allow editing of icons on child items.
jesseleite May 3, 2023
946ccf5
Only fall back to `entries` icon when resolving renderable svg.
jesseleite May 3, 2023
f50012d
Strip child icons out of yaml on save.
jesseleite May 3, 2023
7f00dc7
Merge branch '4.x' of https://github.com/statamic/cms into cp-nav-bui…
jesseleite Apr 15, 2024
eee60b4
Merge branch '5.x' into cp-nav-builder-icon-picker
duncanmcclean May 14, 2024
d1d6607
Merge branch '5.x' of https://github.com/statamic/cms into cp-nav-bui…
jesseleite May 22, 2024
b9f35b0
Fix settings icons.
jesseleite May 24, 2024
0c0aa00
Merge branch '5.x' of https://github.com/statamic/cms into cp-nav-bui…
jesseleite May 24, 2024
3b6a462
Merge branch 'cp-nav-builder-icon-picker' of https://github.com/stata…
jesseleite May 24, 2024
14de656
When creating from an item only, pass in parent item.
jesseleite May 24, 2024
500c118
Add `isParentItemNode()` helper method.
jesseleite May 24, 2024
33c3cb2
Move this method for future readability (section vs. parent vs. child).
jesseleite May 24, 2024
417484a
When creating, only show icon when item can have icon.
jesseleite May 24, 2024
3c61b01
Merge branch '5.x' into cp-nav-builder-icon-picker
jasonvarga Aug 14, 2024
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
13 changes: 8 additions & 5 deletions resources/js/components/nav/Branch.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
<div class="page-move w-6" />
<div class="flex items-center flex-1 p-2 rtl:mr-2 ltr:ml-2 text-xs leading-normal">
<div class="flex items-center flex-1" :class="{ 'opacity-50': isHidden || isInHiddenSection }">
<template v-if="! isSection">
<template v-if="! isSection && ! isChild">
<i v-if="isAlreadySvg" class="w-4 h-4 rtl:ml-2 ltr:mr-2" v-html="icon"></i>
<svg-icon v-else class="w-4 h-4 rtl:ml-2 ltr:mr-2" :name="icon" />
<svg-icon v-else class="w-4 h-4 rtl:ml-2 ltr:mr-2" :name="'light/'+icon" />
</template>

<a
Expand Down Expand Up @@ -37,10 +37,10 @@
<slot name="branch-icon" :branch="item" />

<svg-icon v-if="isRenamedSection" class="inline-block w-4 h-4 text-gray-500" name="light/content-writing" v-tooltip="__('Renamed Section')" />
<svg-icon v-else-if="isHidden" class="inline-block w-4 h-4 text-gray-500" name="hidden" v-tooltip="isSection ? __('Hidden Section') : __('Hidden Item')" />
<svg-icon v-else-if="isHidden" class="inline-block w-4 h-4 text-gray-500" name="light/hidden" v-tooltip="isSection ? __('Hidden Section') : __('Hidden Item')" />
<svg-icon v-else-if="isPinnedAlias" class="inline-block w-4 h-4 text-gray-500" name="light/pin" v-tooltip="__('Pinned Item')" />
<svg-icon v-else-if="isAlias" class="inline-block w-4 h-4 text-gray-500" name="light/duplicate-ids" v-tooltip="__('Alias Item')" />
<svg-icon v-else-if="isMoved" class="inline-block w-4 text-gray-500" name="flip-vertical" v-tooltip="__('Moved Item')" />
<svg-icon v-else-if="isMoved" class="inline-block w-4 text-gray-500" name="regular/flip-vertical" v-tooltip="__('Moved Item')" />
<svg-icon v-else-if="isModified" class="inline-block w-4 h-4 text-gray-500" name="light/content-writing" v-tooltip="__('Modified Item')" />
<svg-icon v-else-if="isCustom" class="inline-block w-4 text-gray-500" name="light/user-edit" v-tooltip="isSection ? __('Custom Section') : __('Custom Item')" />

Expand Down Expand Up @@ -70,6 +70,7 @@ export default {
root: Boolean,
vm: Object,
isOpen: Boolean,
isChild: Boolean,
hasChildren: Boolean,
disableSections: Boolean,
topLevel: Boolean,
Expand All @@ -96,7 +97,9 @@ export default {
},

icon() {
return data_get(this.item.config, 'icon') || 'entries';
return data_get(this.item, 'config.icon')
|| data_get(this.item, 'original.icon')
|| 'entries';
},

isAlreadySvg() {
Expand Down
36 changes: 25 additions & 11 deletions resources/js/components/nav/Builder.vue
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@
:depth="vm.level"
:vm="vm"
:is-open="item.open"
:is-child="isChildItemNode(item)"
:has-children="item.children.length > 0"
:disable-sections="true"
:top-level="true"
Expand All @@ -95,7 +96,7 @@
<dropdown-item
v-if="vm.level < 2"
:text="__('Add Item')"
@click="addItem(item.children)" />
@click="addItem(item.children, item)" />
<dropdown-item
:text="__('Edit')"
@click="editingItem = item" />
Expand Down Expand Up @@ -136,6 +137,7 @@
:depth="vm.level"
:vm="vm"
:is-open="item.open"
:is-child="isChildItemNode(item)"
:has-children="item.children.length > 0"
@edit="editItem(item)"
@toggle-open="store.toggleOpen(item)"
Expand All @@ -144,7 +146,7 @@
<dropdown-item
v-if="vm.level < 3"
:text="__('Add Item')"
@click="addItem(item.children)" />
@click="addItem(item.children, item)" />
<dropdown-item
:text="__('Edit')"
@click="editItem(item)" />
Expand Down Expand Up @@ -174,13 +176,15 @@
<item-editor
v-if="creatingItem"
:creating="true"
:is-child="creatingItemIsChild"
@closed="resetItemEditor"
@updated="itemAdded"
/>

<item-editor
v-if="editingItem"
:item="editingItem"
:is-child="isChildItemNode(editingItem)"
@closed="resetItemEditor"
@updated="itemUpdated"
/>
Expand Down Expand Up @@ -275,6 +279,7 @@ export default {
changed: false,
targetDataArray: null,
creatingItem: false,
creatingItemIsChild: false,
editingItem: false,
creatingSection: false,
editingSection: false,
Expand Down Expand Up @@ -433,6 +438,18 @@ export default {
return data_get(node, 'isSection', false);
},

isParentItemNode(node) {
return ! this.isSectionNode(node) && ! this.isChildItemNode(node);
},

isChildItemNode(node) {
if (data_get(node, 'parent.isRoot')) {
return false;
}

return ! this.isSectionNode(node.parent);
},

isCustomSectionNode(node) {
return this.isSectionNode(node) && data_get(node, 'manipulations.action') === '@create';
},
Expand All @@ -445,14 +462,6 @@ export default {
return node;
},

isChildItemNode(node) {
if (data_get(node, 'parent.isRoot')) {
return false;
}

return ! this.isSectionNode(node.parent);
},

traverseTree(nodes, callback, parentPath = []) {
const nodesArray = Array.isArray(nodes) ? nodes : [nodes];

Expand All @@ -473,9 +482,10 @@ export default {
});
},

addItem(targetDataArray) {
addItem(targetDataArray, parentItem) {
this.targetDataArray = targetDataArray;
this.creatingItem = true;
this.creatingItemIsChild = parentItem && this.isParentItemNode(parentItem);
},

addSection() {
Expand All @@ -489,6 +499,7 @@ export default {
action: '@create',
display: createdConfig.display,
url: createdConfig.url,
icon: createdConfig.icon,
};

this.targetDataArray.push(item);
Expand Down Expand Up @@ -518,9 +529,11 @@ export default {

itemUpdated(updatedConfig, item) {
item.text = updatedConfig.display;
item.config.icon = updatedConfig.icon;

this.updateItemManipulation(item, 'display', updatedConfig.display);
this.updateItemManipulation(item, 'url', updatedConfig.url);
this.updateItemManipulation(item, 'icon', updatedConfig.icon);
this.updateItemAction(item);

this.resetItemEditor();
Expand Down Expand Up @@ -674,6 +687,7 @@ export default {
resetItemEditor() {
this.editingItem = false;
this.creatingItem = false;
this.creatingItemIsChild = false;
this.targetDataArray = false;
},

Expand Down
25 changes: 24 additions & 1 deletion resources/js/components/nav/ItemEditor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,19 @@
</div>
</div>

<div class="form-group publish-field w-full" v-if="! isChild">
<div class="field-inner">
<label class="text-sm font-medium mb-2">{{ __('Icon') }}</label>
<publish-field-meta
:config="{ handle: 'icon', type: 'icon', folder: 'light' }"
:initial-value="config.icon"
v-slot="{ meta, value, loading }"
>
<icon-fieldtype v-if="!loading" handle="icon" :meta="meta" :value="value" @input="config.icon = $event" />
</publish-field-meta>
</div>
</div>

</div>
</div>

Expand All @@ -61,11 +74,12 @@ export default {
props: {
creating: false,
item: {},
isChild: false,
},

data() {
return {
config: data_get(this.item, 'config', this.createNewItem()),
config: clone(data_get(this.item, 'config', this.createNewItem())),
saveKeyBinding: null,
validateDisplay: false,
validateUrl: false,
Expand All @@ -89,6 +103,7 @@ export default {
return {
display: '',
url: '',
icon: null,
};
},

Expand All @@ -108,6 +123,14 @@ export default {
return;
}

let config = clone(this.config);

if (this.isChild) {
config.icon = null;
} else if (! config.icon) {
config.icon = data_get(this.item, 'original.icon');
}

this.$emit('updated', this.config, this.item);
},

Expand Down
2 changes: 1 addition & 1 deletion resources/views/nav/updates.blade.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<li class="{{ $item->isActive() ? 'current' : '' }}">
<a href="{{ $item->url() }}">
<i>{!! $item->icon() !!}</i><span v-pre>{{ __($item->name()) }}</span>
<i>{!! $item->svg() !!}</i><span v-pre>{{ __($item->name()) }}</span>
<updates-badge class="rtl:mr-2 ltr:ml-2"></updates-badge>
</a>
</li>
2 changes: 1 addition & 1 deletion resources/views/partials/nav-main.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
@unless ($item->view())
<li class="{{ $item->isActive() ? 'current' : '' }}" v-pre>
<a href="{{ $item->url() }}" {{ $item->attributes() }}>
<i>{!! $item->icon() !!}</i><span>{{ __($item->name()) }}</span>
<i>{!! $item->svg() !!}</i><span>{{ __($item->name()) }}</span>
</a>
@if ($item->children() && $item->isActive())
<ul>
Expand Down
2 changes: 1 addition & 1 deletion resources/views/partials/nav-mobile.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
@unless ($item->view())
<li class="{{ $item->isActive() ? 'current' : '' }}" v-pre>
<a href="{{ $item->url() }}">
<i>{!! $item->icon() !!}</i><span>{{ __($item->name()) }}</span>
<i>{!! $item->svg() !!}</i><span>{{ __($item->name()) }}</span>
</a>
@if ($item->children() && $item->isActive())
<ul>
Expand Down
Loading
Loading