| 1 |
// Canvas field-block visuals. |
| 2 |
// |
| 3 |
// Mirrors the designer's "Form Editor" mockup field-block design: a roomy white |
| 4 |
// card, a 14px bold label with a red required asterisk, a bordered "control" |
| 5 |
// placeholder preview of the front-end input, and a meta row with a field-type |
| 6 |
// chip + the field number. Token values come from style/_tokens.scss. |
| 7 |
.wppb-fb-field-block { |
| 8 |
background: var(--wppb-fb-surface-default); |
| 9 |
border: 1px solid var(--wppb-fb-border-default); |
| 10 |
border-radius: var(--wppb-fb-radius-md); // Figma radius "md" = cards/tiles/fields |
| 11 |
// border-box so the layout's content-size (max-width) caps the block's |
| 12 |
// TOTAL width, not its content box. Without it, content-box adds each |
| 13 |
// block's padding+border OUTSIDE the max-width, so blocks with different |
| 14 |
// padding render at different total widths once the canvas is wide enough |
| 15 |
// for the content-size to bind (masked on a narrow, both-sidebars canvas). |
| 16 |
box-sizing: border-box; |
| 17 |
margin: var(--wppb-fb-space-md) 0; |
| 18 |
padding: var(--wppb-fb-space-2xl); // 20px all sides |
| 19 |
|
| 20 |
// Persist the "selected block" outline while focus is inside the Field |
| 21 |
// Settings PluginSidebar. Gutenberg binds the blue outline to |
| 22 |
// `.block-editor-block-list__block:focus::after` — DOM focus, not |
| 23 |
// `.is-selected` — so clicking any control in our right-rail PluginSidebar |
| 24 |
// makes the canvas block lose `:focus` and the outline vanishes, though it's |
| 25 |
// still the selected block in the store — the opposite of the Block-inspector |
| 26 |
// contract users expect when editing a field's settings. |
| 27 |
// |
| 28 |
// Repaint the same outline off `.is-selected` so it survives the focus shift. |
| 29 |
// Mirrors Gutenberg's pseudo-element geometry (inset 0, outline 2px theme |
| 30 |
// color, white inner ring via inset box-shadow) so the two render pixel- |
| 31 |
// identically — when focus IS on the canvas both paint the same outline, no |
| 32 |
// double border. |
| 33 |
&.is-selected::after { |
| 34 |
content: ""; |
| 35 |
position: absolute; |
| 36 |
inset: 0; |
| 37 |
pointer-events: none; |
| 38 |
outline: 2px solid var(--wppb-fb-accent); |
| 39 |
outline-offset: -2px; |
| 40 |
box-shadow: inset 0 0 0 2.5px rgba(255, 255, 255, 0.7); |
| 41 |
border-radius: inherit; |
| 42 |
} |
| 43 |
|
| 44 |
.wppb-fb-field-label { |
| 45 |
color: var(--wppb-fb-text-primary); |
| 46 |
display: block; |
| 47 |
font-size: var(--wppb-fb-font-lg); |
| 48 |
font-weight: 600; |
| 49 |
margin-bottom: var(--wppb-fb-space-sm); |
| 50 |
} |
| 51 |
|
| 52 |
// Required marker beside the label. |
| 53 |
.wppb-fb-field-required { |
| 54 |
color: var(--wppb-fb-status-danger); |
| 55 |
margin-left: var(--wppb-fb-space-3xs); |
| 56 |
} |
| 57 |
|
| 58 |
// In-card callouts (e.g. `wppb-fb-username-hidden-notice`, the exclusive- |
| 59 |
// field-conflict warning). Core's `.components-notice` declares padding but |
| 60 |
// NO margin, so the notice sits flush against whatever follows it — the |
| 61 |
// field preview when it's passed as a child, the meta row otherwise. Give |
| 62 |
// it bottom breathing room. Scoped by our own block class, so it can't |
| 63 |
// affect notices on other editor screens. |
| 64 |
.components-notice { |
| 65 |
margin-bottom: var(--wppb-fb-space-lg); |
| 66 |
} |
| 67 |
|
| 68 |
// Static preview of the front-end control. Each block passes a real (but |
| 69 |
// disabled) input/select/textarea as children; style them to read like a |
| 70 |
// placeholder box. Checkbox/radio/file inputs keep |
| 71 |
// their native size — only text-like fields get the full-width frame. |
| 72 |
.wppb-fb-field-preview { |
| 73 |
color: var(--wppb-fb-text-primary); |
| 74 |
|
| 75 |
input:not([type="checkbox"]):not([type="radio"]):not([type="file"]), |
| 76 |
select, |
| 77 |
textarea { |
| 78 |
background: var(--wppb-fb-surface-default); |
| 79 |
border: 1px solid var(--wppb-fb-border-strong); |
| 80 |
border-radius: var(--wppb-fb-radius-sm); |
| 81 |
box-sizing: border-box; |
| 82 |
color: var(--wppb-fb-text-faint); |
| 83 |
font-size: var(--wppb-fb-font-md); |
| 84 |
height: 38px; |
| 85 |
padding: 0 var(--wppb-fb-space-lg); |
| 86 |
width: 100%; |
| 87 |
} |
| 88 |
|
| 89 |
textarea { |
| 90 |
height: 96px; |
| 91 |
padding: var(--wppb-fb-space-md) var(--wppb-fb-space-lg); |
| 92 |
resize: none; |
| 93 |
} |
| 94 |
|
| 95 |
// Previews are display-only — block all interaction regardless of type. |
| 96 |
input, |
| 97 |
select, |
| 98 |
textarea { |
| 99 |
pointer-events: none; |
| 100 |
} |
| 101 |
} |
| 102 |
|
| 103 |
.wppb-fb-field-desc { |
| 104 |
color: var(--wppb-fb-text-muted); |
| 105 |
font-size: var(--wppb-fb-font-sm); |
| 106 |
margin-top: var(--wppb-fb-space-sm); |
| 107 |
} |
| 108 |
|
| 109 |
// Bottom meta row: a field-type chip followed by the field number. |
| 110 |
.wppb-fb-field-meta { |
| 111 |
align-items: center; |
| 112 |
color: var(--wppb-fb-text-faint); |
| 113 |
display: flex; |
| 114 |
flex-wrap: wrap; |
| 115 |
font-size: var(--wppb-fb-font-xs); |
| 116 |
gap: var(--wppb-fb-space-md); |
| 117 |
margin-top: var(--wppb-fb-space-lg); |
| 118 |
} |
| 119 |
|
| 120 |
.wppb-fb-field-tag { |
| 121 |
align-items: center; |
| 122 |
background: var(--wppb-fb-surface-subtle); |
| 123 |
border-radius: var(--wppb-fb-radius-pill); |
| 124 |
color: var(--wppb-fb-text-muted); |
| 125 |
display: inline-flex; |
| 126 |
font-weight: 500; |
| 127 |
gap: var(--wppb-fb-space-2xs); |
| 128 |
padding: var(--wppb-fb-space-3xs) var(--wppb-fb-space-xs); |
| 129 |
} |
| 130 |
} |
| 131 |
|