Theming¶
The formatter's output is the ai_disclosure theme hook, which renders the
ai_disclosure:ai-disclosure single-directory component, and its look is a
small set of CSS custom properties, not hard-coded values. This page
covers the essentials. The class tree and custom properties
carries the full tree for both the disclosure and the report, with every custom property and
copy-paste examples.
Custom properties¶
Set them on both selectors, .ai-disclosure-wrapper, .ai-disclosure. Custom
properties inherit downwards only, and the card draws its border on the
wrapper, which is the ancestor of .ai-disclosure: a value set on
.ai-disclosure alone never reaches it.
Every rule reads them with a fallback, so a theme overrides what it needs and leaves the rest. A rule in the theme's own CSS is enough. The module's stylesheet stays untouched.
| Property | Default | Effect |
|---|---|---|
--ai-disclosure-gap |
0.75em |
Space between the icon and the text in the header |
--ai-disclosure-icon-height |
2em |
The icon's rendered height (width follows, the icons are not square) |
--ai-disclosure-border-width |
1px |
Width of the card border and the details divider |
--ai-disclosure-border-color |
rgb(128, 128, 128, 0.35) |
Color of the card border and the details divider |
--ai-disclosure-border-radius |
4px |
Corner radius of the card |
--ai-disclosure-padding |
1em 1.25em |
Inner padding of the card |
--ai-disclosure-sentence-weight |
700 |
Font weight of the disclosure sentence, card style only |
--ai-disclosure-secondary-size |
0.9em |
Font size of the legal line, the editorial responsibility line and the statement link, card style only |
--ai-disclosure-secondary-opacity |
0.75 |
Opacity of the legal line, the editorial responsibility line and the statement link, card style only |
--ai-disclosure-divider-gap |
0.75em |
Space above and below the divider between the details section and the header, card style only |
Example, changing only the border color from a theme:
.ai-disclosure-wrapper,
.ai-disclosure {
--ai-disclosure-border-color: rgb(20, 60, 120, 0.4);
}
Legal elements¶
The reference marks each class in the disclosure's markup as legal, structure or decoration. The icon, the disclosure sentence and the notice line are the disclosure itself. A theme that removes them drops the disclosure. The card wrapper, the details section and the statement link are presentation and safe to restyle or remove.
Replacing the stylesheet¶
The formatter always attaches the module's own CSS. A theme can replace it
with its own using libraries-override in its .info.yml, a mechanism of
Drupal itself, not a setting of this module:
libraries-override:
ai_disclosure/disclosure:
css:
component:
css/ai-disclosure.css: css/my-theme-ai-disclosure.css
Overriding the template¶
The markup lives in components/ai-disclosure/ai-disclosure.twig, and
templates/ai-disclosure.html.twig is the theme hook's thin wrapper around
it. A theme overrides the wrapper the usual Drupal way, by copying it into
its own templates/ directory, and gets the whole markup: the override
replaces the wrapper, so it can embed the component with different props or
print its own markup instead. Theme suggestions target a specific grade or
entity type without a preprocess hook:
ai-disclosure--[grade-id].html.twig, e.g.ai-disclosure--ai-deepfake.html.twigai-disclosure--[entity-type].html.twig, e.g.ai-disclosure--media.html.twig
Suggestions are a theme hook feature with no equivalent in a component: a theme overrides a component wholesale, not per suggestion. That is why the theme hook stays.
Placing the component¶
The same markup is available wherever the disclosure is not a field on the entity being rendered: an assembled page, a block, a listing. From a template:
{{ include('ai_disclosure:ai-disclosure', {
sentence: 'This image was generated with AI.',
label_requirement: 'required',
}) }}
From code:
$build['disclosure'] = [
'#type' => 'component',
'#component' => 'ai_disclosure:ai-disclosure',
'#props' => [
'sentence' => $this->t('This image was generated with AI.'),
'label_requirement' => 'required',
],
'#slots' => [
'description' => ['#markup' => $description],
],
];
sentence is the only required prop. Everything the formatter works out on
its own, the visibility policy, the effective grade and the icon variant,
is the caller's to decide here.
The report¶
The compliance report is plain Views output. Its exposed
form has no template and no theme hook of this module's own, the same as
core's own admin views, so the admin theme lays it out. The module adds one
class of its own, ai-disclosure-report__notices, on the "Configuration
notices" details above the table, and one rule for it in
css/ai-disclosure-report.css, the report library. There are no
--ai-disclosure-report-* custom properties.
The reference lists that class and says what the
exposed form, the header and the footer each leave to the theme.