Skip to content
Open
Show file tree
Hide file tree
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
Original file line number Diff line number Diff line change
Expand Up @@ -108,5 +108,188 @@
cursor: not-allowed;
}
}

/* Shared custom dropdown/select styles (template field, tag storage field, etc.) */
.custom-field-wrapper,
.tag-storage-field-wrapper {
font-family: $font-default;
display: flex;
flex-direction: column;
gap: 0.5rem;
max-width: 100%;
min-height: 2.5rem;
}

.select-wrapper,
.tag-storage-select-wrapper {
position: relative;
width: 100%;
}

.custom-select-button,
.tag-storage-custom-select-button {
width: 100%;
padding: 0.5rem 3rem 0.5rem 0.75rem;
font-size: 0.875rem;
line-height: 1.5;
color: $color-palette-gray-700;
background-color: $white;
border: 1px solid;
Copy link

Copilot AI Feb 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Incomplete border declaration missing color value. The border property is set to "1px solid" without specifying a color, which will result in the browser using the default color (usually black). Based on the removed code from template_custom_field_new.vtl which had "border: 2px solid var(--color-palette-primary-500)", this should specify a border color. Consider adding a color such as "$color-palette-primary-500" to match the previous implementation and the hover/focus styles on lines 172 and 179.

Suggested change
border: 1px solid;
border: 1px solid $color-palette-primary-500;

Copilot uses AI. Check for mistakes.
border-radius: 6px;
cursor: pointer;
outline: none;
transition: border-color 0.2s;
text-align: left;
position: relative;
box-shadow: inset 0 0 0 1px
color-mix(in srgb, $color-palette-primary-500 20%, transparent);
min-height: 2.5rem;

&::after {
content: "";
position: absolute;
right: 0;
top: 0;
bottom: 0;
width: 40px;
background-color: $color-palette-gray-100;
border-top-right-radius: 6px;
border-bottom-right-radius: 6px;
background-image:
linear-gradient(45deg, transparent 50%, $color-palette-primary-500 50%),
linear-gradient(135deg, $color-palette-primary-500 50%, transparent 50%);
background-position:
calc(50% - 3px) calc(50% + 1px),
calc(50% + 2px) calc(50% + 1px);
background-size:
5px 5px,
5px 5px;
background-repeat: no-repeat;
pointer-events: none;
}

&:focus {
border-color: $color-palette-primary-500;
box-shadow:
inset 0 0 0 1px color-mix(in srgb, $color-palette-primary-500 30%, transparent),
0 0 0 2px color-mix(in srgb, $color-palette-primary-500 10%, transparent);
}

&:hover {
border-color: $color-palette-primary-500;
}

&.placeholder {
color: $color-palette-gray-500;
}

&:disabled {
opacity: 0.6;
cursor: not-allowed;
}
}

.custom-dropdown,
.tag-storage-custom-dropdown {
position: absolute;
top: 100%;
left: 0;
right: 0;
background-color: $white;
border: 1px solid $color-palette-gray-400;
border-radius: 6px;
box-shadow:
0 4px 6px -1px rgba(0, 0, 0, 0.1),
0 2px 4px -1px rgba(0, 0, 0, 0.06);
margin-top: 0.25rem;
max-height: 400px;
overflow-y: auto;
z-index: 1000;
display: none;

&.open {
display: block;
}

&::-webkit-scrollbar {
width: 8px;
}

&::-webkit-scrollbar-track {
background: $color-palette-gray-100;
}

&::-webkit-scrollbar-thumb {
background: $color-palette-gray-400;
border-radius: 4px;
}

&::-webkit-scrollbar-thumb:hover {
background: $color-palette-gray-500;
}
}

.custom-option,
.tag-storage-custom-option {
padding: 0.75rem 1rem;
cursor: pointer;
border-bottom: 1px solid $color-palette-gray-100;
transition: background-color 0.15s;

&:last-child {
border-bottom: none;
}

&:hover {
background-color: $color-palette-gray-200;
}

&.selected {
background-color: #dbeafe;
Copy link

Copilot AI Feb 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hardcoded color value instead of using SCSS variable. The line uses #dbeafe directly, but this color is defined as $color-palette-blue-tint in the codebase (core-web/libs/dotcms-scss/shared/_colors.scss:190). For consistency and maintainability, use the SCSS variable instead of the hardcoded hex value.

Suggested change
background-color: #dbeafe;
background-color: $color-palette-blue-tint;

Copilot uses AI. Check for mistakes.
}
}

.option-title,
.tag-storage-option-title {
font-size: 0.875rem;
color: $color-palette-gray-700;
font-weight: 400;
margin-bottom: 0.25rem;
}

.option-subtitle {
font-size: 0.75rem;
color: $color-palette-gray-500;
font-weight: 400;
}

.custom-option.placeholder .option-title {
color: $color-palette-gray-500;
font-style: italic;
}

.more-choices-button {
padding: 0.75rem 1rem;
text-align: center;
cursor: pointer;
color: $color-palette-gray-700;
font-size: 0.875rem;
border-top: 1px solid $color-palette-gray-200;
background-color: $white;
transition: background-color 0.15s;

&:hover {
background-color: $color-palette-gray-100;
}

&:active {
background-color: $color-palette-gray-200;
}

&.loading {
color: $color-palette-gray-500;
cursor: wait;
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,37 +1,5 @@
<script language="Javascript">
dojo.require('dotcms.dijit.FileBrowserDialog');

function browseFiles() {
fileSelector.show();
}

function fileSelected(file) {
var path = file.pageURI;
if (!path) {
path = file.path + file.fileName;
}
dojo.byId('vlUri').value = path;
dojo.byId('${field.velocityVarName}').value = path;
}

function setValue(e) {
dojo.byId('${field.velocityVarName}').value = e.target.value;
}

dojo.ready(function() {
dojo.byId('vlUri').value = dojo.byId('${field.velocityVarName}').value;

dojo.require('dojo.on')(dojo.byId('vlUri'), 'change', setValue);
});

</script>
<div class="inline-form">
<input id="vlUri" type="text" name="uri" dojoType="dijit.form.TextBox"
trim="true" invalidMessage="$text.get('Invalid-option-selected')" />
<button dojoType="dijit.form.Button"
onClick="browseFiles();return false;" iconClass="browseIcon">
$text.get('click-here-to-browse')</button>
</div>
<div dojoAttachPoint="fileBrowser" jsId="fileSelector" includeDotAssets="false"
onFileSelected="fileSelected" dojoType="dotcms.dijit.FileBrowserDialog">
</div>
#if( $structures.isNewEditModeEnabled() )
#parse('/static/content/file_browser_field_render_new.vtl')
#else
#parse('/static/content/file_browser_field_render_old.vtl')
#end
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<script type="application/javascript">
DotCustomFieldApi.ready(() => {
const field = DotCustomFieldApi.getField("${field.velocityVarName}");
const vlUriInput = document.getElementById("vlUri");
const browseButton = document.getElementById("browseButton");
Copy link

Copilot AI Feb 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing null safety checks for DOM elements. The code directly uses DOM elements (vlUriInput, browseButton) retrieved via getElementById without checking if they exist. If any element is missing, calling methods like addEventListener will throw errors. For consistency with tag_storage_field_creation_new.vtl (lines 64-67) which includes null checks, add validation after line 5: if (!vlUriInput || !browseButton) return;

Suggested change
const browseButton = document.getElementById("browseButton");
const browseButton = document.getElementById("browseButton");
if (!vlUriInput || !browseButton) {
return;
}

Copilot uses AI. Check for mistakes.

// Initialize input with current field value
const currentValue = field.getValue() || "";
vlUriInput.value = currentValue;

// Sync input changes to field
vlUriInput.addEventListener("change", () => {
field.setValue(vlUriInput.value);
});

// Handle browse button click
browseButton.addEventListener("click", () => {
DotCustomFieldApi.openBrowserModal({
header: "$text.get('Select-a-file')",
params: {
showFiles: true,
showPages: true,
showFolders: true,
showDotAssets: false,
showWorking: false,
showArchived: false,
sortByDesc: true,
},
onClose: (result) => {
if (result && result.url) {
vlUriInput.value = result.url;
field.setValue(result.url);
}
},
});
});
});
</script>

<div class="flex gap-2 align-items-center flex-wrap">
<input
type="text"
id="vlUri"
name="uri"
class="flex-1 min-w-0"
placeholder="$text.get('enter-file-path')"
/>
<button
id="browseButton"
type="button"
class="p-button p-button-outlined bg-primary"
>
$text.get('click-here-to-browse')
</button>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<script language="Javascript">
dojo.require('dotcms.dijit.FileBrowserDialog');

function browseFiles() {
fileSelector.show();
}

function fileSelected(file) {
var path = file.pageURI;
if (!path) {
path = file.path + file.fileName;
}
dojo.byId('vlUri').value = path;
dojo.byId('${field.velocityVarName}').value = path;
}

function setValue(e) {
dojo.byId('${field.velocityVarName}').value = e.target.value;
}

dojo.ready(function() {
dojo.byId('vlUri').value = dojo.byId('${field.velocityVarName}').value;

dojo.require('dojo.on')(dojo.byId('vlUri'), 'change', setValue);
});

</script>
<div class="inline-form">
<input id="vlUri" type="text" name="uri" dojoType="dijit.form.TextBox"
trim="true" invalidMessage="$text.get('Invalid-option-selected')" />
<button dojoType="dijit.form.Button"
onClick="browseFiles();return false;" iconClass="browseIcon">
$text.get('click-here-to-browse')</button>
</div>
<div dojoAttachPoint="fileBrowser" jsId="fileSelector" includeDotAssets="false"
onFileSelected="fileSelected" dojoType="dotcms.dijit.FileBrowserDialog">
</div>
Loading
Loading