/
whose - items are part of the block
* itself (the `items` attribute), not child blocks. A leaf block, so it uses
* AtomicBlockBase like Atomic Text.
*/
class Block extends AtomicBlockBase {
protected $block_name = 'atomic-list';
/** Alignment (block prop `listAlign`) => the flex alignment it stands for. */
const ALIGN_VALUES = [
'left' => 'flex-start',
'center' => 'center',
'right' => 'flex-end',
];
/**
* What each Layout (block prop `listLayout`) writes, as selector suffix =>
* declarations. Both values set the same declarations, so a breakpoint
* that switches back to Vertical fully undoes a wider one's Horizontal.
* Mirror of LAYOUT_CSS in src/blocks/atomic-list/edit.js.
*/
const LAYOUT_CSS = [
'horizontal' => [
'' => '--ablocks-list-direction:row;--ablocks-list-wrap:wrap;--ablocks-list-align-items:normal;--ablocks-list-justify:var(--ablocks-list-align,normal);',
':not(.ablocks-atomic-list--custom):not(.ablocks-atomic-list--inside)' => 'padding-inline-start:0;',
':not(.ablocks-atomic-list--custom):not(.ablocks-atomic-list--inside) > li' => 'margin-inline-start:var(--ablocks-list-indent,1.5em);',
'.ablocks-atomic-list--divider > li:not(:last-child)::after' => 'inset-block:0;inset-inline:auto calc(var(--ablocks-list-gap,0px) / -2);inline-size:auto;block-size:var(--ablocks-list-divider-size,auto);border-block-end-width:0;border-inline-end-width:var(--ablocks-list-divider-weight,1px);',
],
'vertical' => [
'' => '--ablocks-list-direction:initial;--ablocks-list-wrap:initial;--ablocks-list-align-items:initial;--ablocks-list-justify:initial;',
':not(.ablocks-atomic-list--custom):not(.ablocks-atomic-list--inside)' => 'padding-inline-start:var(--ablocks-list-indent,1.5em);',
':not(.ablocks-atomic-list--custom):not(.ablocks-atomic-list--inside) > li' => 'margin-inline-start:0;',
'.ablocks-atomic-list--divider > li:not(:last-child)::after' => 'inset-inline:0;inset-block:auto calc(var(--ablocks-list-gap,0px) / -2);block-size:auto;inline-size:var(--ablocks-list-divider-size,auto);border-inline-end-width:0;border-block-end-width:var(--ablocks-list-divider-weight,1px);',
],
];
/** Divider panel → Style (block prop `dividerStyle`). Mirror of DIVIDER_STYLES in edit.js. */
const DIVIDER_STYLES = [ 'solid', 'dashed', 'dotted', 'double', 'groove', 'ridge' ];
/**
* Block props `listLayout`, `listAlign`, `indent`, `markerColor`,
* `markerSize`, `markerGap`, `dividerStyle`, `dividerWidth`,
* `dividerColor`, `dividerWeight`, `dropCapColor` and `dropCapSize`, plus
* the shared `gap` mirrored for the divider, per breakpoint and state. Values
* travel as custom properties, read by the rules in style.css; Layout adds
* the rules in LAYOUT_CSS. Mirrors emitListProps() in atomic-list/edit.js.
*/
protected function extra_css( $base, $attributes ) {
$styles = isset( $attributes['styles'] ) && is_array( $attributes['styles'] ) ? $attributes['styles'] : [];
return AtomicBlockProps::rules(
$styles,
$base,
function ( $props ) {
$indent = AtomicBlockProps::range( isset( $props['indent'] ) ? $props['indent'] : '' );
$size = AtomicBlockProps::range( isset( $props['markerSize'] ) ? $props['markerSize'] : '' );
$color = AtomicBlockProps::scalar( $props, 'markerColor' );
$marker_gap = AtomicBlockProps::range( isset( $props['markerGap'] ) ? $props['markerGap'] : '' );
$gap = AtomicBlockProps::range( isset( $props['gap'] ) ? $props['gap'] : '' );
$align_key = AtomicBlockProps::scalar( $props, 'listAlign' );
$align = isset( self::ALIGN_VALUES[ $align_key ] ) ? self::ALIGN_VALUES[ $align_key ] : '';
$layout_key = AtomicBlockProps::scalar( $props, 'listLayout' );
$layout = isset( self::LAYOUT_CSS[ $layout_key ] ) ? self::LAYOUT_CSS[ $layout_key ] : [];
$div_style = AtomicBlockProps::scalar( $props, 'dividerStyle' );
$div_style = in_array( $div_style, self::DIVIDER_STYLES, true ) ? $div_style : '';
$div_size = AtomicBlockProps::range( isset( $props['dividerWidth'] ) ? $props['dividerWidth'] : '', '%' );
$div_color = AtomicBlockProps::scalar( $props, 'dividerColor' );
$div_weight = AtomicBlockProps::range( isset( $props['dividerWeight'] ) ? $props['dividerWeight'] : '' );
$dc_size = AtomicBlockProps::range( isset( $props['dropCapSize'] ) ? $props['dropCapSize'] : '' );
$dc_color = AtomicBlockProps::scalar( $props, 'dropCapColor' );
$rules = $layout;
$rules[''] = ( '' !== $indent ? 'padding-inline-start:' . $indent . ';--ablocks-list-indent:' . $indent . ';' : '' )
. ( '' !== $color ? '--ablocks-list-marker-color:' . $color . ';' : '' )
. ( '' !== $size ? '--ablocks-list-marker-size:' . $size . ';' : '' )
. ( '' !== $marker_gap ? '--ablocks-list-marker-gap:' . $marker_gap . ';' : '' )
. ( '' !== $gap ? '--ablocks-list-gap:' . $gap . ';' : '' )
. ( '' !== $align ? '--ablocks-list-align:' . $align . ';' : '' )
. ( isset( $layout[''] ) ? $layout[''] : '' )
. ( '' !== $div_style ? '--ablocks-list-divider-style:' . $div_style . ';' : '' )
. ( '' !== $div_size ? '--ablocks-list-divider-size:' . $div_size . ';' : '' )
. ( '' !== $div_color ? '--ablocks-list-divider-color:' . $div_color . ';' : '' )
. ( '' !== $div_weight ? '--ablocks-list-divider-weight:' . $div_weight . ';' : '' )
. ( '' !== $dc_color ? '--ablocks-list-drop-cap-color:' . $dc_color . ';' : '' )
. ( '' !== $dc_size ? '--ablocks-list-drop-cap-size:' . $dc_size . ';' : '' );
return $rules;
}
);
}
}