@@ -12,138 +12,90 @@ const validateLabel: TextFieldSingleValidation = (val, args) => {
1212 return Boolean ( val ) ? text ( val , args ) : 'You must define a label for an external link.'
1313}
1414
15- type LinkFieldsOptions = {
16- includeLabel ?: boolean
17- /** When true, newTab checkbox only shows for external links and defaults to true */
18- newTabForExternalOnly ?: boolean
19- /** Custom admin Description component path for the label field */
20- labelDescriptionComponent ?: string
21- }
22-
23- type LinkFieldOptions = LinkFieldsOptions & {
24- fieldName ?: string
25- }
26-
27- /**
28- * Builds the raw link fields array.
29- * Used internally by linkField and exported as linkFields for array contexts.
30- */
31- const buildLinkFields = ( {
32- includeLabel = false ,
33- newTabForExternalOnly = false ,
34- labelDescriptionComponent,
35- } : LinkFieldsOptions = { } ) : Field [ ] => {
36- const newTabField : Field = {
37- name : 'newTab' ,
38- type : 'checkbox' ,
39- admin : {
40- ...( newTabForExternalOnly
41- ? {
42- condition : ( _ , siblingData ) => siblingData ?. type === 'external' ,
43- }
44- : {
45- style : {
46- alignSelf : 'flex-end' ,
47- alignItems : 'flex-end' ,
48- marginBottom : '4px' ,
49- } ,
50- width : '50%' ,
51- } ) ,
15+ const linkReferenceRow = ( includeLabel = false ) : Field [ ] => {
16+ const fields : Field [ ] = [
17+ {
18+ name : 'reference' ,
19+ type : 'relationship' ,
20+ admin : {
21+ condition : ( _ , siblingData ) => siblingData ?. type === 'internal' ,
22+ width : '50%' ,
23+ } ,
24+ label : 'Select page or post' ,
25+ relationTo : [ 'pages' , 'builtInPages' , 'posts' ] ,
26+ required : true ,
27+ filterOptions : getTenantFilter ,
5228 } ,
53- ...( newTabForExternalOnly ? { defaultValue : true } : { } ) ,
54- label : 'Open in new tab' ,
55- }
56-
57- const referenceField : Field = {
58- name : 'reference' ,
59- type : 'relationship' ,
60- admin : {
61- condition : ( _ , siblingData ) => siblingData ?. type === 'internal' ,
62- width : '50%' ,
29+ {
30+ name : 'url' ,
31+ type : 'text' ,
32+ admin : {
33+ condition : ( _ , siblingData ) => siblingData ?. type === 'external' ,
34+ width : '100%' ,
35+ } ,
36+ label : 'External URL' ,
37+ validate : validateExternalUrl ,
6338 } ,
64- label : 'Select page or post' ,
65- relationTo : [ 'pages' , 'builtInPages' , 'posts' ] ,
66- required : true ,
67- filterOptions : getTenantFilter ,
68- }
39+ ]
6940
70- const urlField : Field = {
71- name : 'url' ,
72- type : 'text' ,
73- admin : {
74- condition : ( _ , siblingData ) => siblingData ?. type === 'external' ,
75- width : '100%' ,
76- } ,
77- label : 'External URL' ,
78- validate : validateExternalUrl ,
41+ if ( includeLabel ) {
42+ fields . push ( {
43+ name : 'label' ,
44+ type : 'text' ,
45+ admin : { width : '50%' } ,
46+ label : 'Label' ,
47+ validate : validateLabel ,
48+ } )
7949 }
8050
81- const labelField : Field = {
82- name : 'label' ,
83- type : 'text' ,
84- admin : {
85- width : '50%' ,
86- ...( labelDescriptionComponent
87- ? {
88- components : {
89- Description : labelDescriptionComponent ,
90- } ,
91- }
92- : { } ) ,
93- } ,
94- label : 'Label' ,
95- validate : validateLabel ,
96- }
51+ return fields
52+ }
9753
98- return [
99- {
100- type : 'row' ,
101- fields : [
102- {
103- name : 'type' ,
104- type : 'radio' ,
105- admin : {
106- layout : 'horizontal' ,
107- width : '50%' ,
54+ export const linkToPageOrPost = ( includeLabel = false ) : Field [ ] => [
55+ {
56+ type : 'row' ,
57+ fields : [
58+ {
59+ name : 'type' ,
60+ type : 'radio' ,
61+ admin : {
62+ layout : 'horizontal' ,
63+ width : '50%' ,
64+ } ,
65+ defaultValue : 'internal' ,
66+ options : [
67+ { label : 'Internal link' , value : 'internal' } ,
68+ { label : 'External link' , value : 'external' } ,
69+ ] ,
70+ } ,
71+ {
72+ name : 'newTab' ,
73+ type : 'checkbox' ,
74+ admin : {
75+ style : {
76+ alignSelf : 'flex-end' ,
77+ alignItems : 'flex-end' ,
78+ marginBottom : '4px' ,
10879 } ,
109- defaultValue : 'internal' ,
110- options : [
111- { label : 'Internal link' , value : 'internal' } ,
112- { label : 'External link' , value : 'external' } ,
113- ] ,
80+ width : '50%' ,
11481 } ,
115- ...( newTabForExternalOnly ? [ ] : [ newTabField ] ) ,
116- ] ,
117- } ,
118- {
119- type : 'row' ,
120- fields : [ referenceField , urlField , ...( includeLabel ? [ labelField ] : [ ] ) ] ,
121- } ,
122- ...( newTabForExternalOnly ? [ newTabField ] : [ ] ) ,
123- ]
124- }
82+ label : 'Open in new tab' ,
83+ } ,
84+ ] ,
85+ } ,
86+ {
87+ type : 'row' ,
88+ fields : linkReferenceRow ( includeLabel ) ,
89+ } ,
90+ ]
12591
126- /**
127- * Creates a link group field with configurable options.
128- *
129- * @example
130- * // Basic usage
131- * linkField()
132- *
133- * @example
134- * // With custom field name and label
135- * linkField({ fieldName: 'button', includeLabel: true })
136- *
137- * @example
138- * // Navigation-style link (newTab only for external)
139- * linkField({ includeLabel: true, newTabForExternalOnly: true })
140- */
14192export const linkField = ( {
14293 fieldName = 'link' ,
14394 includeLabel = false ,
144- newTabForExternalOnly = false ,
145- labelDescriptionComponent,
146- } : LinkFieldOptions = { } ) : NamedGroupField => ( {
95+ } : {
96+ fieldName ?: string
97+ includeLabel ?: boolean
98+ } = { } ) : NamedGroupField => ( {
14799 name : fieldName ,
148100 type : 'group' ,
149101 admin : {
@@ -152,19 +104,5 @@ export const linkField = ({
152104 hooks : {
153105 beforeChange : [ clearIrrelevantLinkValues ] ,
154106 } ,
155- fields : buildLinkFields ( { includeLabel, newTabForExternalOnly , labelDescriptionComponent } ) ,
107+ fields : linkToPageOrPost ( includeLabel ) ,
156108} )
157-
158- /**
159- * Returns the raw link fields array for use in array field contexts.
160- * Use this when you need the fields directly on array items without a group wrapper.
161- *
162- * @example
163- * // In an array field
164- * {
165- * name: 'quickLinks',
166- * type: 'array',
167- * fields: linkFields(true), // includeLabel
168- * }
169- */
170- export const linkFields = ( includeLabel = false ) : Field [ ] => buildLinkFields ( { includeLabel } )
0 commit comments