From 59fbb2cad2dd7427fddb05b36f15792611ed13d5 Mon Sep 17 00:00:00 2001 From: Stephen Nelson Date: Sun, 2 Aug 2026 15:56:55 +0930 Subject: [PATCH] Support for katalyst-govuk-formbuilder 2.0 --- .github/workflows/release.yml | 4 + .github/workflows/test.yml | 4 + Gemfile.lock | 17 +- .../content/figures/_figure.html+form.erb | 7 +- katalyst-content.gemspec | 2 +- .../assets/javascripts/controllers/index.js | 6 +- .../app/assets/stylesheets/blocks/button.css | 8 +- .../assets/stylesheets/forms/checkboxes.css | 4 +- .../stylesheets/forms/document-field.css | 84 ------ .../assets/stylesheets/forms/file-upload.css | 259 ++++++++++++++++++ .../assets/stylesheets/forms/form-group.css | 6 + .../assets/stylesheets/forms/image-field.css | 96 ------- .../app/assets/stylesheets/forms/index.css | 4 +- .../app/assets/stylesheets/forms/input.css | 20 +- .../app/assets/stylesheets/forms/lexxy.css | 53 ++++ .../app/assets/stylesheets/forms/radios.css | 4 +- .../app/assets/stylesheets/forms/select.css | 1 - .../app/assets/stylesheets/forms/textarea.css | 2 +- .../app/assets/stylesheets/forms/trix.css | 36 ++- .../katalyst/content/items_controller_spec.rb | 2 +- 20 files changed, 397 insertions(+), 222 deletions(-) delete mode 100644 spec/dummy/app/assets/stylesheets/forms/document-field.css delete mode 100644 spec/dummy/app/assets/stylesheets/forms/image-field.css create mode 100644 spec/dummy/app/assets/stylesheets/forms/lexxy.css diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 05f9cae..8696dfc 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -15,6 +15,10 @@ jobs: contents: write id-token: write steps: + - name: Install dependencies + env: + DEPENDENCIES: libvips + run: sudo apt-get install -y $DEPENDENCIES || (sudo apt-get update && sudo apt-get install -y $DEPENDENCIES) - uses: actions/checkout@v6 - uses: ruby/setup-ruby@v1 with: diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 40db620..5bb16b4 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -6,6 +6,10 @@ jobs: test: runs-on: ubuntu-latest steps: + - name: Install dependencies + env: + DEPENDENCIES: libvips + run: sudo apt-get install -y $DEPENDENCIES || (sudo apt-get update && sudo apt-get install -y $DEPENDENCIES) - uses: actions/checkout@v6 - uses: ruby/setup-ruby@v1 with: diff --git a/Gemfile.lock b/Gemfile.lock index 82d0922..e936bc9 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - katalyst-content (3.2.1) + katalyst-content (3.2.2) active_storage_validations activerecord katalyst-govuk-formbuilder @@ -57,11 +57,11 @@ GEM erubi (~> 1.11) rails-dom-testing (~> 2.2) rails-html-sanitizer (~> 1.6) - active_storage_validations (3.0.6) - activejob (>= 6.1.4) - activemodel (>= 6.1.4) - activestorage (>= 6.1.4) - activesupport (>= 6.1.4) + active_storage_validations (4.0.0) + activejob (>= 7.0.1) + activemodel (>= 7.0.1) + activestorage (>= 7.0.1) + activesupport (>= 7.0.1) marcel (>= 1.0.3) activejob (8.1.3.1) activesupport (= 8.1.3.1) @@ -174,7 +174,8 @@ GEM rdoc (>= 4.0.0) reline (>= 0.4.2) json (2.21.2) - katalyst-govuk-formbuilder (1.30.1) + katalyst-govuk-formbuilder (2.0.0) + activestorage (>= 8.0.0) govuk_design_system_formbuilder (>= 6.2.0) katalyst-html-attributes (1.1.2) activesupport @@ -276,7 +277,7 @@ GEM zeitwerk (~> 2.6) rainbow (3.1.1) rake (13.4.2) - rbs (4.1.1) + rbs (4.1.2) logger prism (>= 1.6.0) tsort diff --git a/app/views/katalyst/content/figures/_figure.html+form.erb b/app/views/katalyst/content/figures/_figure.html+form.erb index 7d899a1..1d1423f 100644 --- a/app/views/katalyst/content/figures/_figure.html+form.erb +++ b/app/views/katalyst/content/figures/_figure.html+form.erb @@ -1,9 +1,8 @@ <%# locals: (form:, figure:) %> -<%= form.govuk_image_field(:image) do %> - <%= form.govuk_text_field(:heading, label: { text: "Alternate text" }) %> - <%= form.govuk_text_field(:caption, label: { text: "Caption (optional)" }, optional: true) %> -<% end %> +<%= form.govuk_image_field(:image) %> +<%= form.govuk_text_field(:heading, label: { text: "Alternate text" }) %> +<%= form.govuk_text_field(:caption, label: { text: "Caption (optional)" }) %> <%= form.content_theme_field %> <%= form.content_visible_field %> diff --git a/katalyst-content.gemspec b/katalyst-content.gemspec index d00f3df..8f78b4a 100644 --- a/katalyst-content.gemspec +++ b/katalyst-content.gemspec @@ -2,7 +2,7 @@ Gem::Specification.new do |spec| spec.name = "katalyst-content" - spec.version = "3.2.1" + spec.version = "3.2.2" spec.authors = ["Katalyst Interactive"] spec.email = ["developers@katalyst.com.au"] diff --git a/spec/dummy/app/assets/javascripts/controllers/index.js b/spec/dummy/app/assets/javascripts/controllers/index.js index 223f1c9..1568dfb 100644 --- a/spec/dummy/app/assets/javascripts/controllers/index.js +++ b/spec/dummy/app/assets/javascripts/controllers/index.js @@ -1,9 +1,11 @@ import { application } from "controllers/application"; import content from "@katalyst/content"; -import govuk from "@katalyst/govuk-formbuilder"; import tables from "@katalyst/tables"; application.load(content); -application.load(govuk); application.load(tables); + +import govuk from "@katalyst/govuk-formbuilder"; + +govuk.start(application); diff --git a/spec/dummy/app/assets/stylesheets/blocks/button.css b/spec/dummy/app/assets/stylesheets/blocks/button.css index 7ef3b39..b9bb6db 100644 --- a/spec/dummy/app/assets/stylesheets/blocks/button.css +++ b/spec/dummy/app/assets/stylesheets/blocks/button.css @@ -1,4 +1,5 @@ -.button { +.button, +:where(.govuk-button) { /* Configuration */ --button-padding: 0.5em 1em; --button-gap: 0.5em; @@ -33,7 +34,7 @@ font-weight: var(--button-font-weight, 500); font-size: var(--button-font-size, 1em); letter-spacing: 0.05ch; - font-family: sans-serif; + font-family: var(--font-base); line-height: 1.1; /* Interactive */ @@ -72,7 +73,8 @@ --button-padding: 0.5em; } - &[data-ghost-button] { + &[data-ghost-button], + &:where(.govuk-button--secondary) { --button-bg: transparent; --button-border-color: currentColor; --button-color: currentColor; diff --git a/spec/dummy/app/assets/stylesheets/forms/checkboxes.css b/spec/dummy/app/assets/stylesheets/forms/checkboxes.css index 976c53e..9af81c7 100644 --- a/spec/dummy/app/assets/stylesheets/forms/checkboxes.css +++ b/spec/dummy/app/assets/stylesheets/forms/checkboxes.css @@ -32,6 +32,8 @@ grid-area: input; margin-block-start: calc(-0.5 * var(--input-size)); translate: 0 calc(var(--stroke-input-width) + 0.25 * var(--input-size)); + /* Firefox fix - unable to calculate baseline from dynamic height */ + min-block-size: var(--input-size); } .govuk-checkboxes__item::after { @@ -55,7 +57,7 @@ cursor: pointer; touch-action: manipulation; margin-block-end: 0; - min-height: var(--input-size); + min-block-size: var(--input-size); } .govuk-checkboxes__hint { diff --git a/spec/dummy/app/assets/stylesheets/forms/document-field.css b/spec/dummy/app/assets/stylesheets/forms/document-field.css deleted file mode 100644 index 2948c3e..0000000 --- a/spec/dummy/app/assets/stylesheets/forms/document-field.css +++ /dev/null @@ -1,84 +0,0 @@ -.govuk-document-field { - display: grid; - grid-template-areas: - "label" - "hint" - "error" - "preview" - "file" - "supplemental"; - grid-template-columns: auto; - grid-auto-rows: auto; - - label { - grid-area: label; - } - - .govuk-hint { - grid-area: hint; - } - - .govuk-error-message { - grid-area: error; - } - - input { - grid-area: file; - - &::file-selector-button { - color: var(--color-dark); - background: var(--color-tint); - border: var(--stroke-input); - border-radius: var(--input-radius); - } - } - - .preview-file { - grid-area: preview; - position: relative; - overflow: visible; - background-color: var(--color-tint); - border: var(--stroke-input); - border-radius: var(--input-radius); - margin-bottom: var(--space-2xs); - padding: var(--space-3xs); - line-height: var(--leading-standard); - align-items: start; - margin-right: auto; - - &:not([hidden]) { - display: inline-flex; - } - - .preview-filename { - line-height: unset; - } - - .file-destroy { - appearance: none; - color: black; - border: none; - background: none; - display: inline-block; - margin-left: 0.2rem; - padding: 0; - - &::after { - content: "×"; - display: block; - position: relative; - width: 21px; - line-height: 21px; - font-size: 21px; - } - } - } - - > div:last-child { - grid-area: supplemental; - - > * + * { - margin-top: var(--flow-space, var(--space-2xs)); - } - } -} diff --git a/spec/dummy/app/assets/stylesheets/forms/file-upload.css b/spec/dummy/app/assets/stylesheets/forms/file-upload.css index e34fd2e..f340ae6 100644 --- a/spec/dummy/app/assets/stylesheets/forms/file-upload.css +++ b/spec/dummy/app/assets/stylesheets/forms/file-upload.css @@ -1,3 +1,5 @@ +/* HTML File inputs */ + .govuk-file-upload { max-width: 100%; } @@ -18,3 +20,260 @@ opacity: 0.5; cursor: not-allowed; } + +/* Drop zone (JS uploads) */ + +.govuk-file-upload-wrapper { + display: block; + position: relative; + z-index: 0; + border: var(--stroke-input); + border-radius: var(--input-radius); + padding: var(--space-s); + + .govuk-form-group--error & { + border-color: var(--govuk-error-color); + } + + &:has(.govuk-file-upload-button:hover) { + border-color: var(--color-dark-glare); + } +} + +.govuk-file-upload-wrapper--disabled { + /* the button disables pointer events, so the cursor lives on the wrapper */ + cursor: not-allowed; +} + +.govuk-file-upload-button { + --button-font-weight: 400; + + width: 100%; + background: transparent; + border: none; + padding: 0; + cursor: pointer; + border-radius: var(--radius-s); + + &:disabled { + pointer-events: none; + opacity: 0.5; + } + + &:focus-visible { + outline: none; + } + + &:focus-visible .govuk-button { + outline: var(--focus-outline); + outline-offset: 2px; + } + + .govuk-attachment + & { + margin-block-start: var(--flow-space, var(--space-s)); + } +} + +.govuk-file-upload-wrapper:has(.govuk-file-upload-button--dragging) { + background-color: var(--color-tint); +} + +.govuk-file-upload-button__status { + /* visually hidden */ + border: 0; + clip: rect(0 0 0 0); + height: auto; + margin: 0; + overflow: hidden; + padding: 0; + position: absolute; + width: 1px; + white-space: nowrap; +} + +.govuk-file-upload-button__pseudo-button-container { + display: flex; + flex-wrap: wrap; + align-items: baseline; + gap: var(--space-2xs); +} + +.govuk-file-upload-button__pseudo-button { + flex-shrink: 0; +} + +.govuk-file-upload-button__instruction { + margin: 0; + text-align: left; +} + +/* Attachments */ + +.govuk-attachment { + display: grid; + grid-template-areas: "preview caption actions"; + grid-template-columns: auto 1fr auto; + margin: 0 0 var(--flow-space) 0; + padding: var(--space-xs); + grid-gap: var(--space-s); + border: 1px solid var(--color-mid); + border-radius: var(--input-radius); + + .preview { + grid-area: preview; + max-width: 4rem; + aspect-ratio: 1/1; + object-fit: cover; + border-radius: var(--radius-s); + } + + .caption { + display: flex; + flex-direction: column; + grid-area: caption; + font-family: var(--font-base); + font-size: var(--size-step-0); + padding-block-start: unset; + } + + .filename { + font-weight: var(--font-bold); + } + + .size { + color: var(--govuk-hint-color); + } + + .govuk-attachment-progress { + inline-size: auto; + max-inline-size: 16em; + margin-block-start: var(--space-xs); + block-size: var(--space-2xs); + appearance: none; + border: none; + border-radius: var(--radius-s); + overflow: hidden; + + background-color: var(--color-mid); + + &::-webkit-progress-bar { + background-color: var(--color-mid); + } + + &::-webkit-progress-value { + background-color: var(--color-dark); + transition: width var(--transition-movement); + } + + &::-moz-progress-bar { + background-color: var(--color-dark); + } + } + + .actions { + grid-area: actions; + flex-direction: column; + align-items: stretch; + justify-content: center; + } + + .actions button { + display: none; /* Buttons require JavaScript */ + } + + &[data-state] .status { + margin-block-start: auto; + } + + &[data-state="upload-successful"] { + .status { + color: var(--color-success); + } + } + + &[data-state="upload-failed"] { + border-color: var(--govuk-error-color); + + .status { + color: var(--govuk-error-color); + } + } +} + +/* With JavaScript running the button is the figure's only interactive +control; the select still carries the submitted value but leaves the +display, tab order, and accessibility tree. */ +.govuk-frontend-supported .govuk-attachment { + .actions select { + display: none; + } + + .actions button { + display: revert; + } +} + +/* + * Hide duplicate inputs when multiple is not enabled, this allows reverting + * but the value from the last select will overwrite the others in save. + */ +.govuk-file-upload-wrapper:has(input[type="file"]:not([multiple])) { + .govuk-attachment:has(+ .govuk-attachment) { + display: none; + } +} + +/* Movement */ + +.govuk-attachment { + .status { + align-self: flex-start; + } + + &[data-state="upload-successful"] { + .status { + animation: govuk-attachment-state-pop var(--transition-bounce); + } + } + + &[data-state="upload-failed"] { + .status { + animation: govuk-attachment-state-pop var(--transition-bounce); + } + } +} + +@keyframes govuk-attachment-state-pop { + 50% { + scale: 1.05; + } +} + +.govuk-attachment { + &:has(.govuk-attachment-progress):has(.preview) { + &::before { + content: ""; + position: absolute; + display: block; + margin: var(--space-xs); + width: calc(64px - 2 * var(--space-xs)); + padding: 4px; /* spinner width */ + aspect-ratio: 1; + border-radius: 50%; + background: var(--color-light); + --mask: + conic-gradient(#0000 10%, #000), linear-gradient(#000 0 0) content-box; + -webkit-mask: var(--mask); + mask: var(--mask); + -webkit-mask-composite: source-out; + mask-composite: subtract; + animation: govuk-attachment-upload-spinner 1s infinite linear; + } + } +} + +@keyframes govuk-attachment-upload-spinner { + to { + transform: rotate(1turn); + } +} diff --git a/spec/dummy/app/assets/stylesheets/forms/form-group.css b/spec/dummy/app/assets/stylesheets/forms/form-group.css index 99d43e5..a34370e 100644 --- a/spec/dummy/app/assets/stylesheets/forms/form-group.css +++ b/spec/dummy/app/assets/stylesheets/forms/form-group.css @@ -5,9 +5,15 @@ form:not([class]), margin-top: var(--flow-space, var(--space-m)); } + /* if the first element in the form is hidden, create negative space to consume the next child's flow margin */ &:has(> [type="hidden"]:first-child) { margin-top: calc(-1 * var(--flow-space, var(--space-m))); } + + /* if we're flowing ourselves then removing our flow margin is sufficient */ + .flow > * + &:has(> [type="hidden"]:first-child) { + margin-top: 0; + } } .govuk-form-group { diff --git a/spec/dummy/app/assets/stylesheets/forms/image-field.css b/spec/dummy/app/assets/stylesheets/forms/image-field.css deleted file mode 100644 index a1afbc2..0000000 --- a/spec/dummy/app/assets/stylesheets/forms/image-field.css +++ /dev/null @@ -1,96 +0,0 @@ -.govuk-image-field { - display: grid; - grid-template-areas: - "label preview" - "hint preview" - "error preview" - "file preview" - "supplemental supplemental"; - grid-template-columns: 1fr auto; - grid-template-rows: auto auto auto 1fr auto; - gap: 0 1rem; - - label { - grid-area: label; - } - - .govuk-hint { - grid-area: hint; - } - - .govuk-error-message { - grid-area: error; - } - - input { - grid-area: file; - align-self: start; - - &::file-selector-button { - color: var(--color-dark); - background: var(--color-tint); - border: var(--stroke-input); - border-radius: var(--input-radius); - } - } - - .preview-image { - grid-area: preview; - position: relative; - display: grid; - overflow: visible; - align-self: start; - align-items: center; - justify-items: center; - background-color: var(--color-tint); - border: var(--stroke-input); - border-radius: var(--input-radius); - - min-width: calc(8em + 2 * var(--stroke-input-width)); - aspect-ratio: 1; - - .image-thumbnail { - max-width: 8em; - max-height: 8em; - } - } - - .file-destroy { - appearance: none; - position: absolute; - background-color: var(--color-tint); - color: var(--color-dark); - border-radius: var(--input-radius); - border: var(--stroke-input); - display: block; - padding: 0; - top: calc(-1 * var(--stroke-input-width)); - right: calc(-1 * var(--stroke-input-width)); - - &::after { - content: "×"; - display: block; - position: relative; - width: 21px; - line-height: 21px; - font-size: 21px; - top: -1px; - } - } - - > div:last-child { - grid-area: supplemental; - - > * + * { - margin-top: var(--flow-space, var(--space-2xs)); - } - } - - .preview-image[hidden] { - display: block !important; - - .file-destroy { - display: none; - } - } -} diff --git a/spec/dummy/app/assets/stylesheets/forms/index.css b/spec/dummy/app/assets/stylesheets/forms/index.css index 21e88ae..67f8bda 100644 --- a/spec/dummy/app/assets/stylesheets/forms/index.css +++ b/spec/dummy/app/assets/stylesheets/forms/index.css @@ -1,3 +1,4 @@ +@import url("/lexxy.css"); @import url("/trix.css"); @import url("label.css"); @@ -12,8 +13,7 @@ @import url("checkboxes.css"); @import url("date-input.css"); @import url("file-upload.css"); -@import url("image-field.css"); -@import url("document-field.css"); +@import url("lexxy.css"); @import url("radios.css"); @import url("password.css"); @import url("select.css"); diff --git a/spec/dummy/app/assets/stylesheets/forms/input.css b/spec/dummy/app/assets/stylesheets/forms/input.css index cd39958..c4fb681 100644 --- a/spec/dummy/app/assets/stylesheets/forms/input.css +++ b/spec/dummy/app/assets/stylesheets/forms/input.css @@ -1,15 +1,15 @@ -:is( - input:not([type="checkbox"], [type="radio"], [type="color"], [type="button"]) -), -:is(select, textarea), -trix-editor { +:where( + input:not([type="checkbox"], [type="radio"], [type="color"], [type="button"]), + select, + textarea +) { background: var(--color-light); border-radius: var(--input-radius); border: var(--stroke-input); color: var(--color-dark); padding: var(--space-3xs); width: 100%; - min-height: var(--input-size); + min-block-size: var(--input-size); &::placeholder { color: var(--color-mid); @@ -30,15 +30,13 @@ trix-editor { } } -:is(input, select, textarea, .govuk-richtextarea), -trix-editor { +:where(input, select, textarea) { accent-color: var(--color-primary); } -:is(textarea), -trix-editor { - resize: vertical; +:where(textarea) { line-height: var(--leading-fine); + resize: vertical; } .govuk-input { diff --git a/spec/dummy/app/assets/stylesheets/forms/lexxy.css b/spec/dummy/app/assets/stylesheets/forms/lexxy.css new file mode 100644 index 0000000..ba71e78 --- /dev/null +++ b/spec/dummy/app/assets/stylesheets/forms/lexxy.css @@ -0,0 +1,53 @@ +:root { + /* Colors */ + --lexxy-color-ink: var(--color-dark); + --lexxy-color-ink-medium: var(--color-dark-glare); + --lexxy-color-ink-light: var(--color-mid); + --lexxy-color-ink-lighter: var(--color-tint); + --lexxy-color-ink-lightest: var(--color-tint); + --lexxy-color-ink-inverted: var(--color-light); + + /* Typography */ + --lexxy-font-base: var(--font-base); + --lexxy-font-mono: var(--font-mono); + --lexxy-text-small: var(--size-step--1); + --lexxy-content-margin: var(--space-s); + + /* Focus ring */ + --lexxy-focus-ring-color: var(--focus-color); +} + +:where(lexxy-toolbar) { + border: none; +} + +:where(lexxy-editor) { + --lexxy-editor-padding: var(--space-2xs); + --lexxy-editor-rows: 5lh; + + @supports (min-block-size: attr(rows lh)) { + --lexxy-editor-rows: attr(rows lh, 5lh); + } + + border: none; + margin-block-end: var(--flow-space, var(--space-2xs)); + + [role="textbox"] { + border-radius: var(--input-radius); + border: var(--stroke-input); + + &:focus-visible { + outline: var(--focus-outline); + outline-offset: 0; + box-shadow: var(--focus-shadow); + } + + .govuk-rich-textarea--error &:not(:focus-visible) { + border-color: var(--govuk-error-color); + } + } +} + +.govuk-error-message:has(+ lexxy-editor) { + margin-block-end: unset; +} diff --git a/spec/dummy/app/assets/stylesheets/forms/radios.css b/spec/dummy/app/assets/stylesheets/forms/radios.css index 838d54f..106ecc6 100644 --- a/spec/dummy/app/assets/stylesheets/forms/radios.css +++ b/spec/dummy/app/assets/stylesheets/forms/radios.css @@ -32,6 +32,8 @@ grid-area: input; margin-block-start: calc(-0.5 * var(--input-size)); translate: 0 calc(var(--stroke-input-width) + 0.25 * var(--input-size)); + /* Firefox fix - unable to calculate baseline from dynamic height */ + min-block-size: var(--input-size); } .govuk-radios__item::after { @@ -56,7 +58,7 @@ cursor: pointer; touch-action: manipulation; margin-block-end: 0; - min-height: var(--input-size); + min-block-size: var(--input-size); } .govuk-radios__hint { diff --git a/spec/dummy/app/assets/stylesheets/forms/select.css b/spec/dummy/app/assets/stylesheets/forms/select.css index 67e622d..75a67ba 100644 --- a/spec/dummy/app/assets/stylesheets/forms/select.css +++ b/spec/dummy/app/assets/stylesheets/forms/select.css @@ -2,7 +2,6 @@ select { line-height: var(--leading-fine); min-width: 11.5em; max-width: 100%; - height: var(--input-size); background-color: var(--color-light); } diff --git a/spec/dummy/app/assets/stylesheets/forms/textarea.css b/spec/dummy/app/assets/stylesheets/forms/textarea.css index ba3fed5..7b33479 100644 --- a/spec/dummy/app/assets/stylesheets/forms/textarea.css +++ b/spec/dummy/app/assets/stylesheets/forms/textarea.css @@ -3,7 +3,7 @@ } .govuk-textarea { - min-height: calc( + min-block-size: calc( var(--size-step-0) * var(--leading-fine) * 5 + var(--space-3xs) * 2 ); } diff --git a/spec/dummy/app/assets/stylesheets/forms/trix.css b/spec/dummy/app/assets/stylesheets/forms/trix.css index bd80c6a..17fb80d 100644 --- a/spec/dummy/app/assets/stylesheets/forms/trix.css +++ b/spec/dummy/app/assets/stylesheets/forms/trix.css @@ -13,7 +13,7 @@ trix-toolbar { } .trix-button--dialog { - min-height: 2.2rem; + min-block-size: 2.2rem; } .trix-button:not(:first-child) { @@ -26,12 +26,36 @@ trix-toolbar { } } -.govuk-richtextarea { - min-height: calc( +trix-editor { + background: var(--color-light); + border-radius: var(--input-radius); + border: var(--stroke-input); + color: var(--color-dark); + padding: var(--space-2xs); + min-block-size: calc( var(--size-step-0) * var(--leading-fine) * 5 + var(--space-3xs) * 2 ); -} -.govuk-richtextarea--error:not(:focus-visible) { - border-color: var(--govuk-error-color); + &::placeholder { + color: var(--color-mid); + opacity: 1; + } + + &:disabled { + opacity: 0.5; + color: inherit; + background-color: transparent; + cursor: not-allowed; + } + + &:focus-visible { + outline: var(--focus-outline); + outline-offset: 0; + box-shadow: var(--focus-shadow); + } + + /* Note: turbo-permanent prevents govuk-rich-textarea--error toggle */ + .govuk-form-group--error > &:not(:focus-visible) { + border-color: var(--govuk-error-color); + } } diff --git a/spec/requests/katalyst/content/items_controller_spec.rb b/spec/requests/katalyst/content/items_controller_spec.rb index 57a8559..90f98d6 100644 --- a/spec/requests/katalyst/content/items_controller_spec.rb +++ b/spec/requests/katalyst/content/items_controller_spec.rb @@ -77,7 +77,7 @@ # note: response.parsed_body strips out