Tagixo Docs

Developer Documentation for Laravel, SDK integrations, and extensibility

Extending Tagixo

PropTypes System

Build reusable style/content groups that define UI schema and optional CSS output.

PropTypes System

PropTypes are reusable groups that power:

  1. properties panel sections
  2. defaults
  3. CSS generation

Registry

Core registry: PropTypeRegistry

Responsibilities:

  • register/resolve PropTypes
  • generate CSS from stored props
  • serialize metadata to frontend

This registry is one of the main reasons Tagixo integrations stay consistent across SDKs.

Contract and base class

  • Contract: PropTypeContract
  • Recommended base: Core\PropTypes\AbstractPropType

Key methods

  • key()
  • label()
  • tab()
  • schema()
  • hasCss()
  • toCss() / toCssWithSelectors()
  • defaults()
  • features()
  • vueComponent()

Schema-driven PropTypes

Prefer schema-driven definitions whenever possible.

Benefits:

  • less frontend custom code
  • predictable defaults
  • easier maintenance

Example

use Ccast\Tagixo\Core\PropTypes\AbstractPropType;
use Ccast\Tagixo\Core\Props\NumberProp;
use Ccast\Tagixo\Core\Props\ToggleProp;

class BlurPropType extends AbstractPropType
{
    public function key(): string { return 'blur'; }
    public function label(): string { return __('Blur'); }
    public function tab(): string { return 'design'; }
    public function hasCss(): bool { return true; }

    public function schema(): array
    {
        return [
            ToggleProp::make('enabled')->default(false),
            NumberProp::make('amount')->min(0)->max(30)->default(0),
        ];
    }

    public function toCss(array $values): string
    {
        if (!($values['enabled'] ?? false)) {
            return '';
        }

        return 'filter: blur(' . (int) ($values['amount'] ?? 0) . 'px);';
    }
}

How PropType values are stored

PropType values are stored under their own key inside a node's props.

Example:

{
  "props": {
    "blur": {
      "enabled": true,
      "amount": 8
    }
  }
}

That namespacing is what keeps design groups isolated and predictable.

toCss() vs toCssWithSelectors()

Use toCss() when the PropType styles the main node itself.

Use toCssWithSelectors() when the PropType needs nested rules, such as:

  • heading rules for h1, h2, h3
  • button label rules
  • repeated child selectors
  • structural sub-elements

If nested styling is part of the feature, document the selector strategy early so it stays stable.

Registration

app(\Ccast\Tagixo\Core\PropTypeRegistry::class)
    ->register(new BlurPropType());

Then reference in module definitions through design groups.

Config-based registration is also valid:

'prop_types' => [
    App\Tagixo\PropTypes\BlurPropType::class,
]

Built-in catalog

The package ships 18 PropTypes out of the box, grouped by the tab they target in the drawer. You compose them per module via ModuleDefinition::design(...).

Content tab

PropType Key Generates CSS What it provides
LinkPropType link no URL, new-tab toggle, title
AdminPropType admin no Editorial label shown in the canvas tree
LayoutPropType layout no Structural layout options (section/row/column)

Design tab

PropType Key What it provides
TypographyPropType typography 5 nested tabs — text, link, ul, ol, quote — each with font family/size/weight/line-height/letter-spacing/transform/align/color. Generates base typography + nested rules for a, ul, ol, blockquote.
HeadingTypographyPropType heading_typography Per-heading-level cascade (H1–H6) with override semantics — H1 inherits from base, H2 inherits from H1 if unset, etc.
SpacingPropType spacing 4-way padding + margin via FourWaysProp (linked or per-side)
BackgroundPropType background 6 layers — color, gradient, image, video, pattern, shape-mask — all composable per element
BorderPropType border Width, style, color, radius (linked or per-corner)
SizingPropType sizing Width/height with min/max, aspect-ratio, object-fit
BoxShadowPropType box_shadow Multiple shadow layers with x/y/blur/spread/color/inset/opacity
FilterPropType filter Brightness, contrast, saturate, blur, hue-rotate, sepia, grayscale, invert
TransformPropType transform Translate/rotate/scale/skew on X and Y
AnimationPropType animation Entry animations with stagger + scroll-triggered playback
SectionDividerPropType section_divider SVG divider (top and bottom) with shape preset, color, height, flip

Advanced tab

PropType Key What it provides
CssSelectorsPropType css_selectors Custom CSS id and class on the wrapper
CustomCssPropType custom_css Raw CSS with .this-element placeholder for the current node
VisibilityPropType visibility Hide per breakpoint + overflow control per axis
DisplayPropType display Position (static/relative/absolute), top/right/bottom/left, z-index

A module enables whichever set fits its semantics:

->design('typography', 'spacing', 'border', 'box_shadow', 'animation')

Unspecified PropTypes simply don't appear in the drawer for that module.

When to create a PropType instead of a Prop

Create a custom Prop when you need a single field.

Create a custom PropType when you need:

  • a reusable group of fields
  • generated CSS
  • a panel section that appears across many modules
  • stable defaults and reset behavior

Common pitfalls

  • duplicate keys
  • invalid CSS units
  • missing defaults
  • schema/data shape mismatch
  • mixing business data with design-layer configuration
  • creating a custom Vue-only PropType for a case that a schema-driven PropType could handle