From 32ae94524af8493ba48e6774de05e38008648151 Mon Sep 17 00:00:00 2001 From: Jason Zimdars Date: Thu, 29 May 2025 14:19:48 -0500 Subject: [PATCH] Safari doesn't support CSS `field-sizing: content` so we can shim it for now --- app/assets/stylesheets/autoresize.css | 27 +++++++++++++++++++ app/assets/stylesheets/cards.css | 6 +++++ .../controllers/autoresize_controller.js | 13 +++++++++ app/views/cards/container/_title.html.erb | 10 +++---- app/views/cards/edit.html.erb | 11 ++++---- 5 files changed, 56 insertions(+), 11 deletions(-) create mode 100644 app/assets/stylesheets/autoresize.css create mode 100644 app/javascript/controllers/autoresize_controller.js diff --git a/app/assets/stylesheets/autoresize.css b/app/assets/stylesheets/autoresize.css new file mode 100644 index 000000000..ac16e04a4 --- /dev/null +++ b/app/assets/stylesheets/autoresize.css @@ -0,0 +1,27 @@ +@layer components { + @supports not (field-sizing: content) { + .autoresize__wrapper { + display: grid !important; + position: relative; + + > *, &::after { + grid-area: 1 / 1 / 2 / 2; + } + + &::after { + content: attr(data-autoresize-clone-value) " "; + font: inherit; + line-height: inherit; + visibility: hidden; + white-space: pre-wrap; + } + } + + .autoresize__textarea { + inset: 0; + overflow: hidden; + position: absolute; + resize: none; + } + } +} diff --git a/app/assets/stylesheets/cards.css b/app/assets/stylesheets/cards.css index d13b60498..53315b8a6 100644 --- a/app/assets/stylesheets/cards.css +++ b/app/assets/stylesheets/cards.css @@ -174,6 +174,12 @@ line-height: 1.2; text-wrap: balance; + @supports not (field-sizing: content) { + &:has(textarea) { + text-wrap: unset; /* Safari is annoying if you have text-wrap: balance in textareas */ + } + } + .card-field__title { &:is(textarea)::placeholder { color: inherit; diff --git a/app/javascript/controllers/autoresize_controller.js b/app/javascript/controllers/autoresize_controller.js new file mode 100644 index 000000000..02b6cc501 --- /dev/null +++ b/app/javascript/controllers/autoresize_controller.js @@ -0,0 +1,13 @@ +import { Controller } from "@hotwired/stimulus" + +export default class extends Controller { + static targets = ["textarea", "wrapper"] + + connect() { + this.resize() + } + + resize() { + this.wrapperTarget.setAttribute("data-autoresize-clone-value", this.textareaTarget.value) + } +} diff --git a/app/views/cards/container/_title.html.erb b/app/views/cards/container/_title.html.erb index 8bbe68550..1767fd854 100644 --- a/app/views/cards/container/_title.html.erb +++ b/app/views/cards/container/_title.html.erb @@ -10,12 +10,12 @@ <% end %> <% else %> - <%= form_with model: card, url: collection_card_path(card.collection, card), id: "card_form", class: "card__content", data: { controller: "auto-save" } do |form| %> -

+ <%= form_with model: card, url: collection_card_path(card.collection, card), id: "card_form", class: "card__content", data: { controller: "autoresize auto-save" } do |form| %> +

<%= form.text_area :title, placeholder: "Name it…", - class: "input input--textarea full-width borderless txt-align-start", - autofocus: card.title.blank?, - data: { action: "auto-save#change blur->auto-save#submit keydown.enter->auto-save#submit:prevent keydown.ctrl+enter->auto-save#submit:prevent" } %> + class: "input input--textarea full-width borderless txt-align-start autoresize__textarea", + autofocus: card.title.blank?, rows: 1, + data: { autoresize_target: "textarea", action: "input->autoresize#resize auto-save#change blur->auto-save#submit keydown.enter->auto-save#submit:prevent keydown.ctrl+enter->auto-save#submit:prevent" } %>

<%= form.rich_textarea :description, class: "card-field__description", diff --git a/app/views/cards/edit.html.erb b/app/views/cards/edit.html.erb index c02e2a635..6a8d37e13 100644 --- a/app/views/cards/edit.html.erb +++ b/app/views/cards/edit.html.erb @@ -1,11 +1,10 @@ <%= turbo_frame_tag @card, :edit do %> - <%= form_with model: @card, url: collection_card_path(@card.collection, @card), class: "card__content", data: { controller: "form" } do |form| %> + <%= form_with model: @card, url: collection_card_path(@card.collection, @card), class: "card__content", data: { controller: "autoresize form" } do |form| %>

- <%= form.label :title, class: "flex flex-column align-center" do %> - <%= form.text_area :title, class: "input input--textarea full-width borderless txt-align-start card-field__title", - required: true, autofocus: true, placeholder: "Name it…", - rows: 1, - data: { action: "keydown.enter->form#submit:prevent keydown.ctrl+enter->form#submit:prevent keydown.meta+enter->form#submit:prevent keydown.esc->form#cancel focus->form#select" } %> + <%= form.label :title, class: "flex flex-column align-center autoresize__wrapper", data: { autoresize_target: "wrapper", autoresize_clone_value: "" } do %> + <%= form.text_area :title, class: "input input--textarea full-width borderless txt-align-start card-field__title autoresize__textarea", + required: true, autofocus: true, placeholder: "Name it…", rows: 1, + data: { autoresize_target: "textarea", action: "input->autoresize#resize keydown.enter->form#submit:prevent keydown.ctrl+enter->form#submit:prevent keydown.meta+enter->form#submit:prevent keydown.esc->form#cancel focus->form#select" } %> <% end %>