From 3b70a6de0f18b2a2678d9ee25636d68b74c4d76f Mon Sep 17 00:00:00 2001
From: Elisa Shapiro <83474365+ElisaShapiro@users.noreply.github.com>
Date: Tue, 28 Jan 2025 14:50:44 -0500
Subject: [PATCH] [PBNTR-440] Enable Global Props for pb_form_with (#4098)
**What does this PR do?** A clear and concise description with your
runway ticket url.
[PBNTR-440](https://runway.powerhrg.com/backlog_items/PBNTR-440) is a
POC demonstrating a method to get global props and flex props working
with our custom form builder `pb_form_with`.
As it stands currently - this PR demonstrates a solution that is not
ideal solution (requires significant manual effort to keep parity with
global prop additions/updates, and global flex props are nebulous, adds
props directly to the pb_forms_with() not contained within a props
hash), but does work. I recommend saving this work as a POC for now and
digging into a more railsy solution in a follow up investigation.
**Screenshots:** Screenshots to visualize your addition/change
**How to test?** Steps to confirm the desired behavior:
1. Go to the default form kit doc example in the
[milano](https://pr4098.playbook.beta.hq.powerapp.cloud/kits/form#default)
(has global props added to our default form kit doc example just for
demo purposes).
2. Observe how the three props added - padding, shadow, and justify -
are added to the default doc example. Compare to this [doc
ex](https://playbook.powerapp.cloud/kits/form#default) in production.
#### Checklist:
- [x] **LABELS** Add a label: `enhancement`, `bug`, `improvement`, `new
kit`, `deprecated`, or `breaking`. See [Changelog &
Labels](https://github.com/powerhome/playbook/wiki/Changelog-&-Labels)
for details.
- [x] **DEPLOY** I have added the `milano` label to show I'm ready for a
review.
~~- [ ] **TESTS** I have added test coverage to my code.~~
---------
Co-authored-by: Carlos Lima
---
.../playbook/pb_forms_global_props_helper.rb | 136 ++++++++++++++++++
playbook/lib/playbook/pb_forms_helper.rb | 17 ++-
2 files changed, 149 insertions(+), 4 deletions(-)
create mode 100755 playbook/lib/playbook/pb_forms_global_props_helper.rb
diff --git a/playbook/lib/playbook/pb_forms_global_props_helper.rb b/playbook/lib/playbook/pb_forms_global_props_helper.rb
new file mode 100755
index 0000000000..7b89ae1428
--- /dev/null
+++ b/playbook/lib/playbook/pb_forms_global_props_helper.rb
@@ -0,0 +1,136 @@
+# frozen_string_literal: true
+
+module Playbook
+ module PbFormsGlobalPropsHelper
+ private
+
+ def generate_prop_classes(props)
+ classes = []
+
+ props.each do |prop, value|
+ next if value.nil?
+
+ classes << case prop
+ when :padding
+ "p_#{value}"
+ when :padding_top
+ "pt_#{value}"
+ when :padding_bottom
+ "pb_#{value}"
+ when :padding_left
+ "pl_#{value}"
+ when :padding_right
+ "pr_#{value}"
+ when :padding_x
+ "px_#{value}"
+ when :padding_y
+ "py_#{value}"
+ when :margin
+ "m_#{value}"
+ when :margin_top
+ "mt_#{value}"
+ when :margin_bottom
+ "mb_#{value}"
+ when :margin_left
+ "ml_#{value}"
+ when :margin_right
+ "mr_#{value}"
+ when :margin_x
+ "mx_#{value}"
+ when :margin_y
+ "my_#{value}"
+ when :shadow
+ "shadow_#{value}"
+ when :width
+ value.to_s.end_with?("%") ? "width_#{value.to_i}_percent" : "width_#{value.downcase}"
+ when :min_width
+ value.to_s.end_with?("%") ? "min_width_#{value.to_i}_percent" : "min_width_#{value.downcase}"
+ when :max_width
+ value.to_s.end_with?("%") ? "max_width_#{value.to_i}_percent" : "max_width_#{value.downcase}"
+ when :height
+ "height_#{value.downcase}"
+ when :min_height
+ "min_height_#{value.downcase}"
+ when :max_height
+ "max_height_#{value.downcase}"
+ when :position
+ "position_#{value}"
+ when :vertical_alignment
+ "vertical_align_#{value}"
+ when :z_index
+ "z_index_#{value}"
+ when :line_height
+ "line_height_#{value}"
+ when :number_spacing
+ "ns_#{value}"
+ when :border_radius
+ "border_radius_#{value}"
+ when :text_size
+ "text_#{value}"
+ when :letter_spacing
+ "ls_#{value}"
+ when :display
+ "display_#{value}"
+ when :cursor
+ "cursor_#{value}"
+ when :hover
+ if value.is_a?(Hash)
+ value.map do |hover_prop, hover_value|
+ case hover_prop
+ when :shadow
+ "hover_shadow_#{hover_value}"
+ when :scale
+ "hover_scale_#{hover_value}"
+ when :underline
+ hover_value == true ? "hover_underline" : nil
+ when :color
+ "hover_color_#{hover_value}"
+ when :background
+ "hover_background_#{hover_value}"
+ end
+ end
+ else
+ "hover_#{value}"
+ end
+ when :text_align
+ "text_align_#{value}"
+ when :overflow
+ "overflow_#{value}"
+ when :overflow_x
+ "overflow_x_#{value}"
+ when :overflow_y
+ "overflow_y_#{value}"
+ when :truncate
+ "truncate_#{value}"
+ when :group_hover
+ value ? "group_hover" : nil
+ end
+ end
+
+ classes.flatten.compact
+ end
+
+ def extract_all_props(options)
+ global_props = %i[
+ padding padding_top padding_bottom padding_left padding_right padding_x padding_y
+ margin margin_top margin_bottom margin_left margin_right margin_x margin_y
+ shadow width min_width max_width height min_height max_height
+ position vertical_alignment z_index line_height number_spacing
+ border_radius text_size letter_spacing display cursor hover
+ text_align overflow overflow_x overflow_y truncate group_hover
+ ]
+
+ props = {}
+ form_opts = options.dup
+
+ global_props.each { |prop| props[prop] = form_opts.delete(prop) if form_opts.key?(prop) }
+
+ if form_opts[:props].is_a?(Hash)
+ nested_props = form_opts.delete(:props)
+ props.merge!(nested_props.slice(*global_props))
+ end
+
+ [props, form_opts]
+ end
+ end
+end
diff --git a/playbook/lib/playbook/pb_forms_helper.rb b/playbook/lib/playbook/pb_forms_helper.rb
index f515b5db13..eeebca8bd9 100755
--- a/playbook/lib/playbook/pb_forms_helper.rb
+++ b/playbook/lib/playbook/pb_forms_helper.rb
@@ -1,7 +1,10 @@
# frozen_string_literal: true
+require_relative "pb_forms_global_props_helper"
+
module Playbook
module PbFormsHelper
+ include Playbook::PbFormsGlobalPropsHelper
# Renders a pb form with ::Playbook::Forms::Builder, that can render
# Playbook kits in the most railsie way.
#
@@ -23,11 +26,17 @@ module PbFormsHelper
# @param validate [Boolean] whether validation should be triggered or not
# @see [#form_with] for other options
def pb_form_with(data: {}, validate: false, loading: false, **kwargs, &block)
+ global_props, form_options = extract_all_props(kwargs)
+
+ classnames = ["pb-form"]
+ classnames << form_options[:class] if form_options[:class].present?
+ classnames << "pb_form_loading" if loading
+ classnames.concat(generate_prop_classes(global_props))
+
data = data.merge("pb-form-validation" => validate)
- classname = ["pb-form", kwargs[:class]].join(" ")
- classname += " pb_form_loading" if loading
- options = kwargs.merge(
- class: classname,
+
+ options = form_options.merge(
+ class: classnames.compact.join(" "),
data: data,
builder: ::Playbook::Forms::Builder
)