Assets
Four asset attributes are available, two for each of CSS and Javascript, split by local or external location.
\Pinto\Attribute\Asset\Css\Pinto\Attribute\Asset\Js\Pinto\Attribute\Asset\ExternalCss\Pinto\Attribute\Asset\ExternalJs
These attributes may be tacked above component classes, among other places.
#[Slots(bindPromotedProperties: true]
#[Js('script.js')]
#[Css('styles.css')]
final class MyComponent {}Local assets
#[Css] and #[Js] are used for locally available assets.
The $path argument of #[Css] and #[Js] determines the file name.
Base directory
\Pinto\List\ObjectListInterface::cssDirectory and \Pinto\List\ObjectListInterface::jsDirectory of discovery determine the absolute directory where assets for a component are located on disk. Since these methods are instance based, directories may be varied by enum.
public function cssDirectory(): string {
return match ($this) {
static::Component1 => '/path/to/component1/assets/'
static::Component2 => '/path/to/component2/assets/'
};
}WARNING
Pinto validates all local assets exist, otherwise exceptions are thrown.
External assets
#[ExternalCss] and #[ExternalJs] are used for externally available assets.
#[
Slots(bindPromotedProperties: true),
ExternalJs('//unpkg.com/htmx.org@1.9.12', attributes: [
'integrity' => 'sha384-ujb1lZYygJmzgSwoxRggbCHcjc0rB2XoQrxeTUQyRjrOnlCoYta87iKBWq3EsdM2',
'crossorigin' => 'anonymous',
]),
]
final class MyComponent {}INFO
External assets are not validated.
Resolution
Each of #[Css], #[Js], #[ExternalCss], #[ExternalJs], may be located on components, enum cases, or enums.
- The component class itself is checked first. If none are found,
- The enum case is checked. If none are found,
- The enum is checked.
Components
#[Css('styles.css')]
final class MyComponent {}Discovery enum case
enum PintoList implements ObjectListInterface {
#[Css('styles.css')]
#[Definition(MyComponent::class)]
case MyComponent;
}Discovery enum
#[Css('styles.css')]
enum PintoList implements ObjectListInterface {}Assets declared at the enum level are applied to all cases and components within it, unless an enum case or component adds assets itself. For situations where assets should be merged instead, consider creating an asset-only enum case combined with #[DependencyOn].
Asset-only enum cases
Asset only enums may be declared, these enums lack an associated #[Definition] referencing an component class. These are useful when working with #[DependencyOn], and are equivalent to a Drupal libraries.yml entry without a uniquely associated component.
enum GlobalAssets implements ObjectListInterface {
#[Css('global.css')]
#[Js('global.js')]
case Global;
}Dependencies
Dependencies to other components may be declared, dynamically bringing in the assets of other components. Dependencies are resolved recursively with the same logic of Drupal libraries.
Dependencies on other components
The value of #[DependencyOn] may be the enum case of a component, from discovery:
enum PintoList implements ObjectListInterface {
#[Css('styles.css')]
#[Definition(OtherComponent::class)]
case OtherComponent;
#[DependencyOn(MyComponents::OtherComponent)]
#[Definition(MyComponent::class)]
case MyComponent;
}Dependencies on libraries
Or the name of a Drupal library:
#[Slots(bindPromotedProperties: true]
#[DependencyOn('drupal/htmx')]
final class MyComponent {}WARNING
Names of Drupal libraries are not validated.
Resolution
Each of #[DependencyOn], may be located on enum cases or enums.
Dependencies are always merged together.
enum OtherPintoList implements ObjectListInterface {
#[Css('global.css')]
case Global;
}
#[DependencyOn(OtherPintoList::Global)]
enum PintoList implements ObjectListInterface {
#[Definition(Accordion::class)]
case Accordion;
#[Css('card.css')]
#[Definition(MyComponent2::class)]
case Card;
}In this example, both Accordion and Card use global.css via an asset-only enum, while Card uses card.css exclusively.
Dependencies are included at-most once-per-page using the same logic as Drupal libraries.