playbook_ui 15.5.0 → 15.6.0.pre.alpha.PLAY2686contactkittextonly13049

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (122) hide show
  1. checksums.yaml +4 -4
  2. data/app/pb_kits/playbook/pb_advanced_table/_advanced_table.scss +96 -6
  3. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_table_props.html.erb +1 -1
  4. data/app/pb_kits/playbook/pb_background/_background.tsx +6 -6
  5. data/app/pb_kits/playbook/pb_background/background.test.js +5 -1
  6. data/app/pb_kits/playbook/pb_background/docs/_background_light.html.erb +1 -1
  7. data/app/pb_kits/playbook/pb_background/docs/_background_light.jsx +0 -1
  8. data/app/pb_kits/playbook/pb_background/docs/_background_light.md +1 -0
  9. data/app/pb_kits/playbook/pb_background/docs/example.yml +2 -2
  10. data/app/pb_kits/playbook/pb_card/docs/_card_header.md +1 -1
  11. data/app/pb_kits/playbook/pb_card/docs/_card_highlight.md +1 -1
  12. data/app/pb_kits/playbook/pb_collapsible/__snapshots__/collapsible.test.js.snap +2 -2
  13. data/app/pb_kits/playbook/pb_collapsible/child_kits/CollapsibleIcon.tsx +10 -8
  14. data/app/pb_kits/playbook/pb_collapsible/docs/_collapsible_icons.jsx +0 -1
  15. data/app/pb_kits/playbook/pb_collapsible/docs/_collapsible_state.jsx +0 -3
  16. data/app/pb_kits/playbook/pb_contact/_contact.tsx +51 -24
  17. data/app/pb_kits/playbook/pb_contact/contact.html.erb +53 -19
  18. data/app/pb_kits/playbook/pb_contact/contact.rb +11 -1
  19. data/app/pb_kits/playbook/pb_contact/contact.test.js +76 -0
  20. data/app/pb_kits/playbook/pb_contact/docs/_contact_unstyled.html.erb +33 -0
  21. data/app/pb_kits/playbook/pb_contact/docs/_contact_unstyled.jsx +46 -0
  22. data/app/pb_kits/playbook/pb_contact/docs/_contact_unstyled_rails.md +2 -0
  23. data/app/pb_kits/playbook/pb_contact/docs/_contact_unstyled_react.md +2 -0
  24. data/app/pb_kits/playbook/pb_contact/docs/example.yml +2 -0
  25. data/app/pb_kits/playbook/pb_contact/docs/index.js +1 -0
  26. data/app/pb_kits/playbook/pb_date_picker/date_picker.test.js +24 -0
  27. data/app/pb_kits/playbook/pb_date_picker/date_picker_helper.ts +181 -3
  28. data/app/pb_kits/playbook/pb_dialog/docs/_dialog_compound_components.html.erb +31 -0
  29. data/app/pb_kits/playbook/pb_distribution_bar/docs/_distribution_bar_custom_colors.md +1 -1
  30. data/app/pb_kits/playbook/pb_draggable/context/index.tsx +458 -7
  31. data/app/pb_kits/playbook/pb_draggable/context/types.ts +8 -3
  32. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_multiple_containers_dropzone.jsx +180 -0
  33. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_multiple_containers_dropzone.md +22 -0
  34. data/app/pb_kits/playbook/pb_draggable/docs/example.yml +3 -2
  35. data/app/pb_kits/playbook/pb_draggable/docs/index.js +2 -1
  36. data/app/pb_kits/playbook/pb_draggable/draggable.test.jsx +77 -1
  37. data/app/pb_kits/playbook/pb_file_upload/_file_upload.scss +4 -4
  38. data/app/pb_kits/playbook/pb_filter/Filter/FilterBackground.tsx +3 -3
  39. data/app/pb_kits/playbook/pb_home_address_street/_home_address_street.tsx +34 -22
  40. data/app/pb_kits/playbook/pb_home_address_street/city_emphasis.html.erb +16 -12
  41. data/app/pb_kits/playbook/pb_home_address_street/docs/_home_address_street_default.html.erb +1 -1
  42. data/app/pb_kits/playbook/pb_home_address_street/none_emphasis.html.erb +16 -12
  43. data/app/pb_kits/playbook/pb_home_address_street/street_emphasis.html.erb +16 -12
  44. data/app/pb_kits/playbook/pb_multiple_users/_multiple_users.scss +10 -0
  45. data/app/pb_kits/playbook/pb_multiple_users/_multiple_users.tsx +66 -15
  46. data/app/pb_kits/playbook/pb_multiple_users/docs/_multiple_users_with_tooltip.jsx +42 -0
  47. data/app/pb_kits/playbook/pb_multiple_users/docs/_multiple_users_with_tooltip.md +1 -0
  48. data/app/pb_kits/playbook/pb_multiple_users/docs/example.yml +1 -0
  49. data/app/pb_kits/playbook/pb_multiple_users/docs/index.js +1 -0
  50. data/app/pb_kits/playbook/pb_multiple_users/multiple_users.test.js +25 -0
  51. data/app/pb_kits/playbook/pb_phone_number_input/_phone_number_input.tsx +44 -10
  52. data/app/pb_kits/playbook/pb_phone_number_input/docs/_phone_number_input_validation.html.erb +34 -4
  53. data/app/pb_kits/playbook/pb_phone_number_input/docs/_phone_number_input_validation.jsx +16 -7
  54. data/app/pb_kits/playbook/pb_radio/docs/_radio_error.md +1 -1
  55. data/app/pb_kits/playbook/pb_select/_select.tsx +8 -3
  56. data/app/pb_kits/playbook/pb_select/docs/_select_error.md +1 -1
  57. data/app/pb_kits/playbook/pb_select/docs/_select_input_options.html.erb +16 -0
  58. data/app/pb_kits/playbook/pb_select/docs/_select_input_options.jsx +30 -0
  59. data/app/pb_kits/playbook/pb_select/docs/_select_input_options.md +1 -0
  60. data/app/pb_kits/playbook/pb_select/docs/example.yml +2 -0
  61. data/app/pb_kits/playbook/pb_select/docs/index.js +1 -0
  62. data/app/pb_kits/playbook/pb_select/select.html.erb +2 -2
  63. data/app/pb_kits/playbook/pb_select/select.rb +3 -1
  64. data/app/pb_kits/playbook/pb_select/select.test.js +23 -0
  65. data/app/pb_kits/playbook/pb_table/_table.tsx +187 -33
  66. data/app/pb_kits/playbook/pb_table/docs/_table_with_filter_variant.jsx +134 -0
  67. data/app/pb_kits/playbook/pb_table/docs/_table_with_filter_variant.md +34 -0
  68. data/app/pb_kits/playbook/pb_table/docs/_table_with_filter_variant_rails.html.erb +101 -0
  69. data/app/pb_kits/playbook/pb_table/docs/_table_with_filter_variant_rails.md +33 -0
  70. data/app/pb_kits/playbook/pb_table/docs/_table_with_filter_variant_with_pagination.jsx +180 -0
  71. data/app/pb_kits/playbook/pb_table/docs/_table_with_filter_variant_with_pagination.md +3 -0
  72. data/app/pb_kits/playbook/pb_table/docs/_table_with_filter_variant_with_pagination_rails.html.erb +122 -0
  73. data/app/pb_kits/playbook/pb_table/docs/_table_with_filter_variant_with_pagination_rails.md +3 -0
  74. data/app/pb_kits/playbook/pb_table/docs/example.yml +4 -0
  75. data/app/pb_kits/playbook/pb_table/docs/index.js +2 -0
  76. data/app/pb_kits/playbook/pb_table/styles/_vertical_border.scss +49 -0
  77. data/app/pb_kits/playbook/pb_table/table.html.erb +68 -12
  78. data/app/pb_kits/playbook/pb_table/table.rb +22 -3
  79. data/app/pb_kits/playbook/pb_table/table.test.js +143 -0
  80. data/app/pb_kits/playbook/pb_text_input/docs/_text_input_error.md +1 -1
  81. data/app/pb_kits/playbook/pb_textarea/docs/_textarea_error.md +1 -1
  82. data/app/pb_kits/playbook/pb_timeline/_item.tsx +3 -0
  83. data/app/pb_kits/playbook/pb_timeline/docs/_timeline_show_current_year.html.erb +60 -0
  84. data/app/pb_kits/playbook/pb_timeline/docs/_timeline_show_current_year.jsx +118 -0
  85. data/app/pb_kits/playbook/pb_timeline/docs/_timeline_show_current_year.md +1 -0
  86. data/app/pb_kits/playbook/pb_timeline/docs/_timeline_with_date.md +1 -1
  87. data/app/pb_kits/playbook/pb_timeline/docs/example.yml +2 -0
  88. data/app/pb_kits/playbook/pb_timeline/docs/index.js +1 -0
  89. data/app/pb_kits/playbook/pb_timeline/item.html.erb +1 -1
  90. data/app/pb_kits/playbook/pb_timeline/item.rb +2 -0
  91. data/app/pb_kits/playbook/pb_timeline/label.html.erb +2 -1
  92. data/app/pb_kits/playbook/pb_timeline/label.rb +2 -0
  93. data/app/pb_kits/playbook/pb_timeline/subcomponents/Label.tsx +3 -0
  94. data/app/pb_kits/playbook/pb_timeline/timeline.test.js +51 -0
  95. data/app/pb_kits/playbook/pb_typeahead/_typeahead.test.jsx +15 -0
  96. data/app/pb_kits/playbook/pb_typeahead/_typeahead.tsx +3 -0
  97. data/app/pb_kits/playbook/pb_typeahead/components/ClearIndicator.tsx +13 -2
  98. data/app/pb_kits/playbook/pb_typeahead/components/MultiValue.tsx +6 -1
  99. data/app/pb_kits/playbook/pb_typeahead/components/ValueContainer.tsx +34 -7
  100. data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_input_display.html.erb +30 -0
  101. data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_input_display.jsx +37 -0
  102. data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_input_display.md +3 -0
  103. data/app/pb_kits/playbook/pb_typeahead/docs/example.yml +2 -0
  104. data/app/pb_kits/playbook/pb_typeahead/docs/index.js +2 -1
  105. data/app/pb_kits/playbook/pb_typeahead/typeahead.rb +6 -1
  106. data/app/pb_kits/playbook/tokens/_colors.scss +2 -1
  107. data/app/pb_kits/playbook/utilities/deprecated.ts +73 -0
  108. data/dist/chunks/_typeahead-CHwm9MTE.js +6 -0
  109. data/dist/chunks/lib-Cugvy62C.js +29 -0
  110. data/dist/chunks/vendor.js +3 -3
  111. data/dist/playbook-rails-react-bindings.js +1 -1
  112. data/dist/playbook-rails.js +1 -1
  113. data/dist/playbook.css +1 -1
  114. data/lib/playbook/forms/builder/collection_select_field.rb +9 -1
  115. data/lib/playbook/forms/builder/select_field.rb +9 -1
  116. data/lib/playbook/forms/builder/time_zone_select_field.rb +9 -1
  117. data/lib/playbook/pb_kit_helper.rb +35 -0
  118. data/lib/playbook/version.rb +2 -2
  119. metadata +31 -5
  120. data/app/pb_kits/playbook/pb_bar_graph/BarGraphStyles.scss +0 -58
  121. data/dist/chunks/_typeahead-Bx4QsIEU.js +0 -6
  122. data/dist/chunks/lib-Dk4GKPut.js +0 -29
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a883729bcc3b37b0d4b1d155e4a7a27a6a598c8a0ceb563b0eb5516b56e3dff4
4
- data.tar.gz: 2a3fef178d8aa3c10a6f91f66b5b2f8bcce5c63314b9c2a26a676877b0fa7c5d
3
+ metadata.gz: a30081dbc5a14dfeec79933dd490fe553502036499c58f64de1d148a0fba985e
4
+ data.tar.gz: b6cf7dd45fd95b0cc39435dd440bb3829648799a28295ca0fd5b0f7d324a07d2
5
5
  SHA512:
6
- metadata.gz: b14d4934f5ee87c4513676c1d35fd7fce4187222567d2d516379b6dcf536183afc946d4264b8448ff91038e3b5f9a9492b06fd0229c74b462fb16f4ebb0fc0b4
7
- data.tar.gz: bac6a862cb3f18a38877933a07c9abab89165f721867aba4eb0672bb0cc5448ec793fd2dfdd606d9e99b11b06fa60ab3e4ed4090cb95ac4a1f786f8afb9066c8
6
+ metadata.gz: ae9a12d8598e97d2326f6d8b6c65950a2316e511d1e22de76709c4fb416b3f67a61e02dbc895138b64ec80c2f68bfd26be27a2e0aaa1a07f439c4be7a3e87c63
7
+ data.tar.gz: 97507923ae090f97a814c18cbd242e3746f7481fd797e0f3b809ccc34c3a784644e9b5d5b5ac8c8ef407bc712f17d67f1e2c778c82c0abc1ac28aa070fa79285
@@ -791,6 +791,28 @@
791
791
  box-shadow: 1px 0px 0px 0px var(--column-border-color) !important;
792
792
  }
793
793
 
794
+ // Override last-header-cell border color in dark mode
795
+ .pb_advanced_table_header {
796
+ > tr:not(:first-child) {
797
+ .last-header-cell {
798
+ border-right: 1px solid $border_dark !important;
799
+ }
800
+ }
801
+
802
+ th[colspan]:not([colspan="1"]) {
803
+ border-right: 1px solid $border_dark !important;
804
+ }
805
+ }
806
+
807
+ // Override last-cell border color in dark mode for body cells
808
+ .pb_advanced_table_body {
809
+ tr {
810
+ .last-cell:not(:last-of-type) {
811
+ border-right: 1px solid $border_dark !important;
812
+ }
813
+ }
814
+ }
815
+
794
816
  // Apply border colors in dark mode
795
817
  &[class*="column-group-border-"] {
796
818
  // For top-level column groups (ENROLLMENT DATA, PERFORMANCE DATA)
@@ -850,7 +872,7 @@
850
872
  // Restore vertical border styling in dark mode when verticalBorder is true
851
873
  .pb_table[data-vertical-border="true"] {
852
874
  .pb_advanced_table_header {
853
- > tr:not(:first-child) {
875
+ > tr {
854
876
  th:not(:last-child) {
855
877
  border-right: 1px solid $border_dark !important;
856
878
  }
@@ -864,11 +886,17 @@
864
886
  }
865
887
  }
866
888
 
889
+ tr.virtualized-table-row {
890
+ td:not(:last-child) {
891
+ border-right: 1px solid $border_dark !important;
892
+ }
893
+ }
894
+
867
895
  // When both verticalBorder AND columnGroupBorderColor are set in dark mode,
868
896
  // override the default border-dark with the custom color
869
897
  &.pb_advanced_table[class*="column-group-border-"] {
870
898
  .pb_advanced_table_header {
871
- > tr:not(:first-child) {
899
+ > tr {
872
900
  th:not(:last-child) {
873
901
  border-right: 1px solid var(--column-border-color) !important;
874
902
  }
@@ -881,6 +909,12 @@
881
909
  border-right: 1px solid var(--column-border-color) !important;
882
910
  }
883
911
  }
912
+
913
+ tr.virtualized-table-row {
914
+ td:not(:last-child) {
915
+ border-right: 1px solid var(--column-border-color) !important;
916
+ }
917
+ }
884
918
  }
885
919
  }
886
920
 
@@ -985,34 +1019,90 @@
985
1019
  // Firefox-specific fix for last-header-cell and last-cell vertical borders
986
1020
  @-moz-document url-prefix() {
987
1021
  .pb_advanced_table_header {
988
- .last-header-cell:not(:last-child) {
1022
+ th[colspan]:not([colspan="1"]):not(:last-child) {
1023
+ border-right: none !important;
1024
+ box-shadow: 1px 0 0 0 $border_light !important;
1025
+ }
1026
+
1027
+ .last-header-cell:not(:last-child),
1028
+ > tr:last-child .last-header-cell:not(:last-child) {
989
1029
  border-right: none !important;
990
1030
  box-shadow: 1px 0 0 0 $border_light !important;
991
1031
  }
992
1032
  }
993
1033
 
994
1034
  .pb_advanced_table_body {
995
- .last-cell:not(:last-child) {
1035
+ tr .last-cell:not(:last-of-type),
1036
+ td.last-cell:not(:last-child),
1037
+ .pb_table_td.last-cell:not(:last-child) {
996
1038
  border-right: none !important;
997
1039
  box-shadow: 1px 0 0 0 $border_light !important;
998
1040
  }
999
1041
  }
1000
1042
 
1043
+ &[class*="column-group-border-"] {
1044
+ .pb_advanced_table_header {
1045
+ th[colspan]:not([colspan="1"]):not(:last-child),
1046
+ .last-header-cell:not(:last-child),
1047
+ > tr:last-child .last-header-cell:not(:last-child) {
1048
+ box-shadow: 1px 0 0 0 var(--column-border-color) !important;
1049
+ }
1050
+ }
1051
+
1052
+ .pb_advanced_table_body {
1053
+ tr .last-cell:not(:last-of-type),
1054
+ td.last-cell:not(:last-child),
1055
+ .pb_table_td.last-cell:not(:last-child) {
1056
+ box-shadow: 1px 0 0 0 var(--column-border-color) !important;
1057
+ }
1058
+ }
1059
+ }
1060
+
1001
1061
  // Dark mode Firefox fixes
1002
1062
  &.dark {
1003
1063
  .pb_advanced_table_header {
1004
- .last-header-cell:not(:last-child) {
1064
+ // Convert all colspan headers to box-shadow with dark color
1065
+ th[colspan]:not([colspan="1"]) {
1066
+ border-right: none !important;
1067
+ box-shadow: 1px 0 0 0 $border_dark !important;
1068
+ }
1069
+
1070
+ // Convert all last-header-cell borders to box-shadow with dark color
1071
+ .last-header-cell:not(:last-child),
1072
+ > tr:last-child .last-header-cell:not(:last-child),
1073
+ > tr:not(:first-child) .last-header-cell:not(:last-child),
1074
+ > tr:not(:first-child) .last-header-cell:last-child {
1005
1075
  border-right: none !important;
1006
1076
  box-shadow: 1px 0 0 0 $border_dark !important;
1007
1077
  }
1008
1078
  }
1009
1079
 
1010
1080
  .pb_advanced_table_body {
1011
- .last-cell:not(:last-child) {
1081
+ tr .last-cell:not(:last-of-type),
1082
+ td.last-cell:not(:last-child),
1083
+ .pb_table_td.last-cell:not(:last-child) {
1012
1084
  border-right: none !important;
1013
1085
  box-shadow: 1px 0 0 0 $border_dark !important;
1014
1086
  }
1015
1087
  }
1088
+
1089
+ &[class*="column-group-border-"] {
1090
+ .pb_advanced_table_header {
1091
+ th[colspan]:not([colspan="1"]):not(:last-child),
1092
+ .last-header-cell:not(:last-child),
1093
+ > tr:last-child .last-header-cell:not(:last-child) {
1094
+ box-shadow: 1px 0 0 0 var(--column-border-color) !important;
1095
+ }
1096
+ }
1097
+
1098
+ .pb_advanced_table_body {
1099
+ tr .last-cell:not(:last-of-type),
1100
+ td.last-cell:not(:last-child),
1101
+ .pb_table_td.last-cell:not(:last-child) {
1102
+ box-shadow: 1px 0 0 0 var(--column-border-color) !important;
1103
+ }
1104
+ }
1105
+ }
1016
1106
  }
1017
1107
  }
1018
1108
  }
@@ -30,4 +30,4 @@
30
30
  }
31
31
  ] %>
32
32
 
33
- <%= pb_rails("advanced_table", props: { id: "table_props_table", table_data: @table_data, column_definitions: column_definitions, table_props: { vertical_border: true, container: false }}) %>
33
+ <%= pb_rails("advanced_table", props: { id: "table_props_table", table_data: @table_data, column_definitions: column_definitions, table_props: { vertical_border: true, container: false }}) %>
@@ -102,16 +102,16 @@ const Background = (props: BackgroundProps): React.ReactElement => {
102
102
  useEffect(() => {
103
103
  const updateResponsiveProps = () => {
104
104
  setResponsiveProps({
105
- backgroundSize: getResponsiveValue(props.backgroundSize),
106
- backgroundPosition: getResponsiveValue(props.backgroundPosition),
107
- backgroundRepeat: getResponsiveValue(props.backgroundRepeat),
108
- backgroundColor: getResponsiveValue(props.backgroundColor),
109
- imageUrl: getResponsiveValue(props.imageUrl),
105
+ backgroundSize: getResponsiveValue(backgroundSize),
106
+ backgroundPosition: getResponsiveValue(backgroundPosition),
107
+ backgroundRepeat: getResponsiveValue(backgroundRepeat),
108
+ backgroundColor: getResponsiveValue(backgroundColor),
109
+ imageUrl: getResponsiveValue(imageUrl),
110
110
  });
111
111
  };
112
112
  window.addEventListener('resize', updateResponsiveProps);
113
113
  return () => window.removeEventListener('resize', updateResponsiveProps);
114
- }, [props]);
114
+ }, [backgroundSize, backgroundPosition, backgroundRepeat, backgroundColor, imageUrl]);
115
115
 
116
116
 
117
117
  // Extract currently applicable responsive values.
@@ -4,7 +4,6 @@ import Background from './_background'
4
4
 
5
5
  const props = {
6
6
  data: { testid: 'background' },
7
- backgroundColor: null,
8
7
  }
9
8
 
10
9
  it('Should be accessible', async () => {
@@ -42,3 +41,8 @@ test('applies correct overlay class when imageOverlay prop is provided', () => {
42
41
  const kit = renderKit(Background, props, { imageOverlay: 'opacity_6' });
43
42
  expect(kit).toHaveClass('imageoverlay_opacity_6');
44
43
  });
44
+
45
+ test('Sets backgroundColor to light as default when no backgroundColor prop is provided', () => {
46
+ const kit = renderKit(Background, props);
47
+ expect(kit).toHaveClass('pb_background_color_light');
48
+ });
@@ -1,3 +1,3 @@
1
- <%= pb_rails("background", props: { background_color: "light", padding: "xl" }) do %>
1
+ <%= pb_rails("background", props: { padding: "xl" }) do %>
2
2
 
3
3
  <% end %>
@@ -3,7 +3,6 @@ import Background from '../../pb_background/_background'
3
3
 
4
4
  const BackgroundLight = (props) => (
5
5
  <Background
6
- backgroundColor="light"
7
6
  padding="xl"
8
7
  {...props}
9
8
  />
@@ -0,0 +1 @@
1
+ By default, the Background kit sets background color to 'light' as seen here.
@@ -1,7 +1,7 @@
1
1
  examples:
2
2
 
3
3
  rails:
4
- - background_light: Light
4
+ - background_light: Default
5
5
  - background_white: White
6
6
  - background_gradient: Gradient
7
7
  - background_image: Image
@@ -11,7 +11,7 @@ examples:
11
11
  - background_size: Size
12
12
 
13
13
  react:
14
- - background_light: Light
14
+ - background_light: Default
15
15
  - background_white: White
16
16
  - background_gradient: Gradient
17
17
  - background_image: Image
@@ -1 +1 @@
1
- Card headers pass category, product, status and background colors only. List of all category, product, status and background colors can be viewed <a href="https://playbook.powerapp.cloud/token/colors" target="_blank">here</a>.
1
+ Card headers pass category, product, status and background colors only. List of all category, product, status and background colors can be viewed <a href="https://playbook.powerapp.cloud/tokens/colors" target="_blank">here</a>.
@@ -1 +1 @@
1
- Card highlight can pass status, product, and category colors. List of all colors can be viewed <a href="https://playbook.powerapp.cloud/token/colors" target="_blank">here</a>.
1
+ Card highlight can pass status, product, and category colors. List of all colors can be viewed <a href="https://playbook.powerapp.cloud/tokens/colors" target="_blank">here</a>.
@@ -25,11 +25,11 @@ exports[`html structure is correct 1`] = `
25
25
  >
26
26
  <div
27
27
  class="icon_wrapper"
28
- style="vertical-align: middle; color: rgb(193, 205, 214);"
28
+ style="vertical-align: middle;"
29
29
  >
30
30
  <svg
31
31
  aria-label="chevron-down icon"
32
- class="pb_custom_icon svg-inline--fa svg_lg svg_fw"
32
+ class="pb_custom_icon svg-inline--fa color_text_lt_lighter svg_lg svg_fw"
33
33
  color="currentColor"
34
34
  fill="none"
35
35
  height="auto"
@@ -27,12 +27,12 @@ type colorMap = {
27
27
  };
28
28
 
29
29
  const colorMap = {
30
- default: "#242B42",
31
- light: "#687887",
32
- lighter: "#C1CDD6",
33
- link: "#0056CF",
34
- error: "#FF2229",
35
- success: "#00CA74",
30
+ default:"text_lt_default",
31
+ light: "text_lt_light",
32
+ lighter: "text_lt_lighter",
33
+ link: "primary",
34
+ error: "error",
35
+ success: "text_dk_success_sm",
36
36
  };
37
37
 
38
38
  const CollapsibleIcon = ({
@@ -68,9 +68,10 @@ const CollapsibleIcon = ({
68
68
  className="icon_wrapper"
69
69
  key={icon ? showIcon(icon)[0] : "chevron-down"}
70
70
  onClick={(e) => handleIconClick(e)}
71
- style={{ verticalAlign: "middle", color: color }}
71
+ style={{ verticalAlign: "middle"}}
72
72
  >
73
73
  <Icon
74
+ color={color}
74
75
  icon={icon ? showIcon(icon)[0] : "chevron-down"}
75
76
  size={iconSize}
76
77
  />
@@ -80,9 +81,10 @@ const CollapsibleIcon = ({
80
81
  className="icon_wrapper"
81
82
  key={icon ? showIcon(icon)[1] : "chevron-up"}
82
83
  onClick={(e) => handleIconClick(e)}
83
- style={{ verticalAlign: "middle", color: color }}
84
+ style={{ verticalAlign: "middle" }}
84
85
  >
85
86
  <Icon
87
+ color={color}
86
88
  icon={icon ? showIcon(icon)[1] : "chevron-up"}
87
89
  size={iconSize}
88
90
  />
@@ -7,7 +7,6 @@ const CollapsibleIcons = (props) => {
7
7
  <>
8
8
  <Collapsible
9
9
  icon={['plus','minus']}
10
- iconColor='white'
11
10
  >
12
11
  <Collapsible.Main {...props}>
13
12
  <div>{'Main Section'}</div>
@@ -22,7 +22,6 @@ const CollapsibleState = (props) => {
22
22
  <Collapsible
23
23
  collapsed={isCollapsed}
24
24
  icon={["plus", "minus"]}
25
- iconColor='white'
26
25
  padding="none"
27
26
  >
28
27
  <Collapsible.Main padding="sm"
@@ -41,7 +40,6 @@ const CollapsibleState = (props) => {
41
40
  <Collapsible
42
41
  collapsed={isCollapsed}
43
42
  icon={["plus", "minus"]}
44
- iconColor='white'
45
43
  padding="none"
46
44
  >
47
45
  <Collapsible.Main padding="sm"
@@ -60,7 +58,6 @@ const CollapsibleState = (props) => {
60
58
  <Collapsible
61
59
  collapsed={isCollapsed}
62
60
  icon={["plus", "minus"]}
63
- iconColor='white'
64
61
  padding="none"
65
62
  >
66
63
  <Collapsible.Main padding="sm"
@@ -61,7 +61,9 @@ type ContactProps = {
61
61
  data?: { [key: string]: string }
62
62
  dark?: boolean
63
63
  htmlOptions?: { [key: string]: string | number | boolean | (() => void) }
64
+ iconEnabled?: boolean
64
65
  id?: string
66
+ unstyled?: boolean
65
67
  }
66
68
 
67
69
  const Contact = (props: ContactProps): React.ReactElement => {
@@ -74,7 +76,9 @@ const Contact = (props: ContactProps): React.ReactElement => {
74
76
  data = {},
75
77
  dark = false,
76
78
  htmlOptions = {},
79
+ iconEnabled = true,
77
80
  id,
81
+ unstyled = false,
78
82
  } = props
79
83
  const ariaProps = buildAriaProps(aria)
80
84
  const dataProps = buildDataProps(data)
@@ -85,6 +89,51 @@ const Contact = (props: ContactProps): React.ReactElement => {
85
89
  className
86
90
  )
87
91
 
92
+ const formattedValue = formatContact(contactValue, contactType)
93
+ const content = (
94
+ <>
95
+ {iconEnabled && (contactType === 'email' ? (
96
+ <Icon
97
+ className="svg-inline--fa envelope"
98
+ customIcon={envelopeIcon}
99
+ dark={dark}
100
+ fixedWidth
101
+ />
102
+ ) : (
103
+ <Icon
104
+ dark={dark}
105
+ fixedWidth
106
+ icon={contactTypeMap[contactType] || 'phone'}
107
+ />
108
+ ))}
109
+ {iconEnabled ? ` ${formattedValue} ` : formattedValue}
110
+ {contactDetail && (
111
+ <Caption
112
+ dark={dark}
113
+ size="xs"
114
+ tag="span"
115
+ text={contactDetail}
116
+ />
117
+ )}
118
+ </>
119
+ )
120
+
121
+ // When unstyled, render just the content without Body wrapper
122
+ if (unstyled) {
123
+ return (
124
+ <span
125
+ {...ariaProps}
126
+ {...dataProps}
127
+ {...htmlProps}
128
+ className={classes}
129
+ id={id}
130
+ >
131
+ {content}
132
+ </span>
133
+ )
134
+ }
135
+
136
+ // Default styled mode with Body wrapper
88
137
  return (
89
138
  <div
90
139
  {...ariaProps}
@@ -95,33 +144,11 @@ const Contact = (props: ContactProps): React.ReactElement => {
95
144
  >
96
145
  <Body
97
146
  className="pb_contact_kit"
98
- color={"light"}
147
+ color="light"
99
148
  dark={dark}
100
149
  tag="span"
101
150
  >
102
- {contactType === 'email' ? (
103
- <Icon
104
- className="svg-inline--fa envelope"
105
- customIcon={envelopeIcon}
106
- dark={dark}
107
- fixedWidth
108
- />
109
- ) : (
110
- <Icon
111
- dark={dark}
112
- fixedWidth
113
- icon={contactTypeMap[contactType] || 'phone'}
114
- />
115
- )}
116
- {` ${formatContact(contactValue, contactType)} `}
117
- {contactDetail && (
118
- <Caption
119
- dark={dark}
120
- size="xs"
121
- tag="span"
122
- text={contactDetail}
123
- />
124
- )}
151
+ {content}
125
152
  </Body>
126
153
  </div>
127
154
  )
@@ -1,24 +1,23 @@
1
- <%= pb_content_tag do %>
2
- <%= pb_rails("body", props: {
3
- tag: "span",
4
- classname: "pb_contact_kit",
5
- color: "light",
6
- dark: object.dark
7
- }) do %>
8
- <% if contact_type == "email" %>
9
- <%= pb_rails("icon", props: {
10
- custom_icon: Playbook::Engine::root.join(envelope_path),
11
- fixed_width: true,
12
- dark: object.dark
13
- }) %>
1
+ <% if object.unstyled %>
2
+ <%= content_tag :span, class: object.classname, id: object.id, data: object.data, aria: object.aria, **object.html_options do %>
3
+ <% if icon_enabled %>
4
+ <% if contact_type == "email" %>
5
+ <%= pb_rails("icon", props: {
6
+ custom_icon: Playbook::Engine::root.join(envelope_path),
7
+ fixed_width: true,
8
+ dark: object.dark
9
+ }) %>
10
+ <% else %>
11
+ <%= pb_rails("icon", props: {
12
+ icon: object.contact_icon,
13
+ fixed_width: true,
14
+ dark: object.dark
15
+ }) %>
16
+ <% end %>
17
+ <%= " #{object.formatted_contact_value}" if object.contact_value %>
14
18
  <% else %>
15
- <%= pb_rails("icon", props: {
16
- icon: object.contact_icon,
17
- fixed_width: true,
18
- dark: object.dark
19
- }) %>
19
+ <%= object.formatted_contact_value if object.contact_value %>
20
20
  <% end %>
21
- <%= object.formatted_contact_value if object.contact_value %>
22
21
 
23
22
  <%= pb_rails("caption", props: {
24
23
  text: object.contact_detail,
@@ -27,4 +26,39 @@
27
26
  dark: object.dark
28
27
  }) if object.contact_detail %>
29
28
  <% end %>
29
+ <% else %>
30
+ <%= pb_content_tag do %>
31
+ <%= pb_rails("body", props: {
32
+ tag: "span",
33
+ classname: "pb_contact_kit",
34
+ color: "light",
35
+ dark: object.dark
36
+ }) do %>
37
+ <% if icon_enabled %>
38
+ <% if contact_type == "email" %>
39
+ <%= pb_rails("icon", props: {
40
+ custom_icon: Playbook::Engine::root.join(envelope_path),
41
+ fixed_width: true,
42
+ dark: object.dark
43
+ }) %>
44
+ <% else %>
45
+ <%= pb_rails("icon", props: {
46
+ icon: object.contact_icon,
47
+ fixed_width: true,
48
+ dark: object.dark
49
+ }) %>
50
+ <% end %>
51
+ <%= " #{object.formatted_contact_value}" if object.contact_value %>
52
+ <% else %>
53
+ <%= object.formatted_contact_value if object.contact_value %>
54
+ <% end %>
55
+
56
+ <%= pb_rails("caption", props: {
57
+ text: object.contact_detail,
58
+ tag: 'span',
59
+ size: 'xs',
60
+ dark: object.dark
61
+ }) if object.contact_detail %>
62
+ <% end %>
63
+ <% end %>
30
64
  <% end %>
@@ -8,6 +8,8 @@ module Playbook
8
8
  prop :contact_type
9
9
  prop :contact_value
10
10
  prop :contact_detail
11
+ prop :icon_enabled, type: Playbook::Props::Boolean, default: true
12
+ prop :unstyled, type: Playbook::Props::Boolean, default: false
11
13
 
12
14
  def classname
13
15
  generate_classname("pb_contact_kit")
@@ -44,7 +46,15 @@ module Playbook
44
46
  elsif contact_type == "international"
45
47
  contact_value
46
48
  else
47
- number_to_phone(formatted_value, area_code: true)
49
+ # Check if number has leading 1 (US country code)
50
+ # Format like "+1 (212) 555-1234"
51
+ intl_code = ""
52
+ cleaned_number = formatted_value
53
+ if cleaned_number.length == 11 && cleaned_number.start_with?("1")
54
+ intl_code = "+1 "
55
+ cleaned_number = cleaned_number.sub(/^1/, "")
56
+ end
57
+ "#{intl_code}#{number_to_phone(cleaned_number, area_code: true)}"
48
58
  end
49
59
  end
50
60
 
@@ -149,3 +149,79 @@ test('international contact type preserves original format', () => {
149
149
  const kit = screen.getByTestId('test-international-format')
150
150
  expect(kit).toHaveTextContent('+44 20 7946 0958')
151
151
  })
152
+
153
+ test('iconEnabled prop hides icon when false', () => {
154
+ render(
155
+ <>
156
+ <Contact
157
+ contactType="home"
158
+ contactValue="2125551234"
159
+ data={{ testid: 'test-with-icon' }}
160
+ iconEnabled
161
+ />
162
+ <Contact
163
+ contactType="home"
164
+ contactValue="2125551234"
165
+ data={{ testid: 'test-without-icon' }}
166
+ iconEnabled={false}
167
+ />
168
+ </>
169
+ )
170
+
171
+ // With icon enabled, should have icon
172
+ expect(screen.getByTestId('test-with-icon').querySelector('.pb_custom_icon')).toBeInTheDocument()
173
+
174
+ // Without icon, should not have icon
175
+ expect(screen.getByTestId('test-without-icon').querySelector('.pb_custom_icon')).not.toBeInTheDocument()
176
+
177
+ // But should still have the formatted phone number
178
+ expect(screen.getByTestId('test-without-icon')).toHaveTextContent('(212) 555-1234')
179
+ })
180
+
181
+ test('unstyled prop renders without Body wrapper', () => {
182
+ render(
183
+ <>
184
+ <Contact
185
+ contactType="home"
186
+ contactValue="2125551234"
187
+ data={{ testid: 'test-styled' }}
188
+ />
189
+ <Contact
190
+ contactType="home"
191
+ contactValue="2125551234"
192
+ data={{ testid: 'test-unstyled' }}
193
+ unstyled
194
+ />
195
+ </>
196
+ )
197
+
198
+ // Styled version should have Body wrapper with pb_contact_kit class
199
+ const styled = screen.getByTestId('test-styled')
200
+ const styledBody = styled.querySelector('span.pb_contact_kit')
201
+ expect(styledBody).toBeInTheDocument()
202
+ expect(styledBody).toHaveTextContent('(212) 555-1234')
203
+
204
+ // Unstyled version should be a span without Body wrapper
205
+ const unstyled = screen.getByTestId('test-unstyled')
206
+ expect(unstyled.tagName).toBe('SPAN')
207
+ expect(unstyled.querySelector('span.pb_contact_kit')).not.toBeInTheDocument()
208
+ expect(unstyled).toHaveTextContent('(212) 555-1234')
209
+ })
210
+
211
+ test('unstyled and iconEnabled work together', () => {
212
+ render(
213
+ <Contact
214
+ contactType="home"
215
+ contactValue="2125551234"
216
+ data={{ testid: 'test-unstyled-no-icon' }}
217
+ iconEnabled={false}
218
+ unstyled
219
+ />
220
+ )
221
+
222
+ const kit = screen.getByTestId('test-unstyled-no-icon')
223
+ expect(kit.tagName).toBe('SPAN')
224
+ expect(kit.querySelector('.pb_custom_icon')).not.toBeInTheDocument()
225
+ expect(kit.querySelector('.pb_body_kit')).not.toBeInTheDocument()
226
+ expect(kit).toHaveTextContent('(212) 555-1234')
227
+ })