// ─── Common single-purpose presets ────────────────────────────────────────
/** Page/post title field — usually the column shown in admin lists. */
export function titleField(opts = {}) {
    return {
        title: {
            type: 'text',
            label: opts.label ?? 'Title',
            required: opts.required ?? true,
            maxLength: 200,
            admin: { placeholder: opts.placeholder ?? 'Enter a clear, descriptive title' },
        },
    };
}
/** URL slug. Defaults to deriving from `title`. */
export function slugField(opts = {}) {
    return {
        slug: {
            type: 'slug',
            label: 'Slug',
            from: opts.from ?? 'title',
            required: opts.required ?? true,
            unique: true,
            admin: { description: 'URL-friendly identifier. Auto-derived from the title.' },
        },
    };
}
/**
 * Explicit URL path for a page. Distinct from `slug`: a `slug` is the
 * URL-friendly identifier auto-derived from the title, while `path` is the full
 * route the page renders at (e.g. `/`, `/about`, `/services/seo`), so a site can
 * model nested or custom routes the slug alone can't express. Optional — the
 * renderer falls back to `/${slug}` when it's blank.
 */
export function pagePathField(opts = {}) {
    return {
        path: {
            type: 'text',
            label: opts.label ?? 'Path',
            required: opts.required ?? false,
            maxLength: 512,
            admin: {
                description: 'Full URL path this page renders at (e.g. "/", "/about", "/services/seo"). Falls back to /slug when blank.',
            },
        },
    };
}
/** Short excerpt / dek shown in listings and OG cards. */
export function excerptField(opts = {}) {
    return {
        excerpt: {
            type: 'text',
            label: opts.label ?? 'Excerpt',
            maxLength: opts.maxLength ?? 280,
            admin: {
                description: 'Short summary shown in listings, search results, and OG cards.',
            },
        },
    };
}
/** Long-form rich text content. */
export function richContentField(opts = {}) {
    const name = opts.name ?? 'content';
    return {
        [name]: {
            type: 'richText',
            label: opts.label ?? 'Content',
            required: opts.required,
            features: ['bold', 'italic', 'link', 'heading', 'list', 'code', 'image', 'embed'],
        },
    };
}
/** Featured/hero image. */
export function featuredImageField(opts = {}) {
    return {
        featuredImage: {
            type: 'media',
            label: opts.label ?? 'Featured image',
            required: opts.required,
            accept: ['image/jpeg', 'image/png', 'image/webp', 'image/avif'],
            admin: {
                description: 'Hero image used at the top of the page and in social previews.',
            },
        },
    };
}
/**
 * Editorial category. With `options` it becomes a `select` (structured
 * vocabulary — the editor renders a dropdown instead of free text); without,
 * it stays a free-text field for back-compat with existing sites.
 */
export function categoryField(opts = {}) {
    if (opts.options && opts.options.length > 0) {
        return {
            category: {
                type: 'select',
                label: opts.label ?? 'Category',
                required: opts.required,
                options: opts.options.map((o) => typeof o === 'string' ? { label: o, value: slugifyOption(o) } : o),
            },
        };
    }
    return {
        category: {
            type: 'text',
            label: opts.label ?? 'Category',
            required: opts.required,
            maxLength: 80,
        },
    };
}
function slugifyOption(label) {
    return label
        .toLowerCase()
        .trim()
        .replace(/[^a-z0-9]+/g, '-')
        .replace(/^-+|-+$/g, '');
}
/** Tags (array of plain strings). */
export function tagsField(opts = {}) {
    return {
        tags: {
            type: 'array',
            label: opts.label ?? 'Tags',
            maxRows: opts.maxRows ?? 12,
            fields: {
                tag: { type: 'text', label: 'Tag', required: true, maxLength: 40 },
            },
        },
    };
}
/** Published-at datetime. */
export function publishedDateField() {
    return {
        publishedDate: {
            type: 'date',
            label: 'Published date',
            includeTime: true,
            admin: {
                description: 'When this content should appear as published. Defaults to first publish time.',
            },
        },
    };
}
/** Author byline — text + optional relationship to a `team` collection. */
export function authorField(opts = {}) {
    const fields = {
        authorName: {
            type: 'text',
            label: opts.label ?? 'Author name',
            admin: { description: 'Display name shown on the byline.' },
        },
    };
    if (opts.relationTo) {
        fields.author = {
            type: 'relationship',
            label: 'Author',
            relationTo: opts.relationTo,
            admin: {
                description: `Optional reference to a ${opts.relationTo} record. Overrides Author name when set.`,
            },
        };
    }
    return fields;
}
/** Pull-quote / featured quote, used by case studies and testimonials. */
export function quoteField(opts = {}) {
    const name = opts.name ?? 'quote';
    return {
        [name]: {
            type: 'text',
            label: opts.label ?? 'Quote',
            maxLength: 600,
            admin: { description: 'Featured quote rendered as a pull-quote.' },
        },
    };
}
/** Call-to-action label + URL pair. */
export function ctaField(opts = {}) {
    const prefix = opts.name ?? 'cta';
    return {
        [`${prefix}Label`]: {
            type: 'text',
            label: `${opts.label ?? 'CTA'} label`,
            maxLength: 80,
            admin: { description: 'Button text for the primary call to action.' },
        },
        [`${prefix}Url`]: {
            type: 'url',
            label: `${opts.label ?? 'CTA'} URL`,
            admin: { description: 'Where the CTA button links to.' },
        },
    };
}
/** SEO meta fields — meta title, description, OG image, canonical, robots. */
export function seoFields() {
    return {
        metaTitle: {
            type: 'text',
            label: 'SEO title',
            maxLength: 70,
            admin: {
                description: 'Overrides the page title in <title> and OG tags. Keep under 60 chars.',
                position: 'sidebar',
            },
        },
        metaDescription: {
            type: 'text',
            label: 'SEO description',
            maxLength: 200,
            admin: {
                description: 'Search engine description. 120–160 characters is ideal.',
                position: 'sidebar',
            },
        },
        ogImage: {
            type: 'media',
            label: 'Social share image',
            accept: ['image/jpeg', 'image/png', 'image/webp'],
            admin: {
                description: 'Custom OG/Twitter image (1200×630 recommended). Falls back to featured image.',
                position: 'sidebar',
            },
        },
        canonical: {
            type: 'url',
            label: 'Canonical URL',
            admin: {
                description: 'Override the canonical URL for syndicated content.',
                position: 'sidebar',
            },
        },
        noIndex: {
            type: 'boolean',
            label: 'Hide from search engines',
            admin: { description: 'Adds noindex to the robots meta tag.', position: 'sidebar' },
        },
    };
}
/** Address + phone + hours fields for location-style records. */
export function locationFields() {
    return {
        address: {
            type: 'json',
            label: 'Address',
            admin: {
                description: 'PostalAddress object: { streetAddress, addressLocality, addressRegion, postalCode, addressCountry }.',
            },
        },
        phone: {
            type: 'text',
            label: 'Phone',
            maxLength: 40,
            admin: { description: 'Customer-facing phone number in E.164 or local format.' },
        },
        email: {
            type: 'email',
            label: 'Email',
        },
        hours: {
            type: 'json',
            label: 'Hours of operation',
            admin: {
                description: 'OpeningHoursSpecification array: [{ dayOfWeek: "Monday", opens: "09:00", closes: "17:00" }, ...].',
            },
        },
    };
}
/** Geo coordinates pair — useful for Schema.org Place / LocalBusiness. */
export function geoFields() {
    return {
        latitude: {
            type: 'number',
            label: 'Latitude',
            min: -90,
            max: 90,
            step: 0.0001,
        },
        longitude: {
            type: 'number',
            label: 'Longitude',
            min: -180,
            max: 180,
            step: 0.0001,
        },
    };
}
/** Price + currency pair — used by service / product types. */
export function priceFields(opts = {}) {
    return {
        price: {
            type: 'number',
            label: 'Price',
            min: 0,
            step: 0.01,
        },
        currency: {
            type: 'text',
            label: 'Currency',
            maxLength: 3,
            defaultValue: opts.currency ?? 'USD',
            admin: { description: 'ISO 4217 currency code (USD, EUR, GBP, ...).' },
        },
    };
}
/**
 * Single-reference relation preset. Use when a document points at exactly
 * one other document — e.g. `post → primaryService`, `caseStudy → client`,
 * `page → location`. The admin renders this with the {@link RelationshipField}
 * picker.
 *
 * @example
 *   ...relationField('primaryService', { relationTo: 'services', label: 'Primary service' })
 */
export function relationField(name, opts) {
    return {
        [name]: {
            type: 'relationship',
            label: opts.label ?? name,
            relationTo: opts.relationTo,
            ...(opts.required ? { required: true } : {}),
            admin: {
                description: opts.description ??
                    `Reference to a ${Array.isArray(opts.relationTo) ? opts.relationTo.join(' or ') : opts.relationTo} document.`,
            },
        },
    };
}
/**
 * Many-relation preset. Use when a document can point at zero-or-more
 * peers — e.g. `post.relatedPosts`, `service.relatedCaseStudies`,
 * `caseStudy.featuredTeamMembers`. Always renders as a multi-select picker.
 *
 * @example
 *   ...relatedDocsField('relatedPosts', { relationTo: 'posts' })
 */
export function relatedDocsField(name, opts) {
    return {
        [name]: {
            type: 'relationship',
            label: opts.label ?? name,
            relationTo: opts.relationTo,
            hasMany: true,
            admin: {
                description: opts.description ??
                    `Zero or more ${Array.isArray(opts.relationTo) ? opts.relationTo.join(' / ') : opts.relationTo} references.`,
            },
        },
    };
}
//# sourceMappingURL=presets.js.map