playbook_ui 14.8.0.pre.alpha.PLAY1615movenegativetoleftofcurrencysign4543 → 14.8.0.pre.alpha.PLAY1649rolloutheightglobalprops4635

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/app/pb_kits/playbook/_playbook.scss +1 -0
  3. data/app/pb_kits/playbook/pb_background/_background.tsx +8 -2
  4. data/app/pb_kits/playbook/pb_checkbox/checkbox.html.erb +2 -2
  5. data/app/pb_kits/playbook/pb_checkbox/checkbox.rb +0 -4
  6. data/app/pb_kits/playbook/pb_checkbox/docs/_checkbox_indeterminate.html.erb +84 -7
  7. data/app/pb_kits/playbook/pb_collapsible/_collapsible.tsx +3 -1
  8. data/app/pb_kits/playbook/pb_currency/_currency.tsx +3 -7
  9. data/app/pb_kits/playbook/pb_currency/currency.html.erb +2 -2
  10. data/app/pb_kits/playbook/pb_currency/currency.rb +1 -17
  11. data/app/pb_kits/playbook/pb_drawer/_drawer.tsx +4 -1
  12. data/app/pb_kits/playbook/pb_dropdown/_dropdown.scss +1 -0
  13. data/app/pb_kits/playbook/pb_dropdown/dropdown_container.html.erb +0 -1
  14. data/app/pb_kits/playbook/pb_dropdown/dropdown_container.rb +0 -4
  15. data/app/pb_kits/playbook/pb_form/docs/_form_form_with.html.erb +2 -2
  16. data/app/pb_kits/playbook/pb_form/docs/_form_form_with_loading.html.erb +1 -1
  17. data/app/pb_kits/playbook/pb_form/docs/_form_form_with_validate.html.erb +63 -12
  18. data/app/pb_kits/playbook/pb_image/_image.tsx +3 -1
  19. data/app/pb_kits/playbook/pb_layout/_layout.tsx +6 -3
  20. data/app/pb_kits/playbook/pb_overlay/_overlay.tsx +3 -1
  21. data/app/pb_kits/playbook/pb_section_separator/_section_separator.tsx +3 -1
  22. data/app/pb_kits/playbook/pb_selectable_card/docs/_selectable_card_default.html.erb +2 -1
  23. data/app/pb_kits/playbook/pb_table/_table.tsx +3 -1
  24. data/app/pb_kits/playbook/pb_timeline/docs/_timeline_with_children.html.erb +47 -0
  25. data/app/pb_kits/playbook/pb_timeline/docs/_timeline_with_children.jsx +59 -0
  26. data/app/pb_kits/playbook/pb_typeahead/_typeahead.scss +3 -0
  27. data/app/pb_kits/playbook/pb_typeahead/index.ts +29 -3
  28. data/app/pb_kits/playbook/pb_typeahead/typeahead.html.erb +5 -2
  29. data/app/pb_kits/playbook/pb_typeahead/typeahead.rb +4 -0
  30. data/app/pb_kits/playbook/tokens/_height.scss +19 -0
  31. data/app/pb_kits/playbook/tokens/exports/_height.module.scss +37 -0
  32. data/app/pb_kits/playbook/utilities/_height.scss +33 -0
  33. data/app/pb_kits/playbook/utilities/_max_width.scss +4 -0
  34. data/app/pb_kits/playbook/utilities/_min_width.scss +1 -1
  35. data/app/pb_kits/playbook/utilities/globalPropNames.mjs +0 -1
  36. data/app/pb_kits/playbook/utilities/globalProps.ts +24 -0
  37. data/dist/chunks/{_typeahead-D0PihN_3.js → _typeahead-PpBCdLHD.js} +3 -3
  38. data/dist/chunks/_weekday_stacked-fqRjy8nx.js +45 -0
  39. data/dist/chunks/{lib-BC6ESsxG.js → lib-SyD3buPZ.js} +1 -1
  40. data/dist/chunks/{pb_form_validation-B_Z9rEbg.js → pb_form_validation-Dt8UJgrJ.js} +1 -1
  41. data/dist/chunks/vendor.js +1 -1
  42. data/dist/menu.yml +321 -0
  43. data/dist/playbook-doc.js +1 -1
  44. data/dist/playbook-rails-react-bindings.js +1 -1
  45. data/dist/playbook-rails.js +1 -1
  46. data/dist/playbook.css +1 -1
  47. data/lib/playbook/classnames.rb +3 -0
  48. data/lib/playbook/forms/builder/typeahead_field.rb +13 -0
  49. data/lib/playbook/height.rb +29 -0
  50. data/lib/playbook/kit_base.rb +16 -1
  51. data/lib/playbook/max_height.rb +29 -0
  52. data/lib/playbook/min_height.rb +29 -0
  53. data/lib/playbook/version.rb +1 -1
  54. metadata +12 -6
  55. data/dist/chunks/_weekday_stacked-CVx1CzK-.js +0 -45
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f1129b60a8057cb4a47a1cd2a7fbfe1ab4a6566d84a3ee8413f494694d17d13b
4
- data.tar.gz: 1488209f50dca59f1e932ff6b53183e1772718e0d5664e1d7b05e49c0d2994df
3
+ metadata.gz: db8ee9f13c7629142d8ebee9009fe589989ec0a27cf7cb7177adf16d52ffa1d3
4
+ data.tar.gz: c793285b7a81d5ff14d5caba6ec65320c00763fba4fc01d9d388794bc684289a
5
5
  SHA512:
6
- metadata.gz: 1e0e520ba271f69218c9f0b812bfac695491c19105b34a4df62d3ba7cfaa209f29a8bcab3dd08900910d2aca5920d1eb72b2d44d9eefb84a60b3538554d8b378
7
- data.tar.gz: c7ebb609bf8a7f21fb85cb161e0ddd39b798193e493cdef6bfd3d8feb821f8f837a5c6caeb37167d4ca33678fabbdf211dc704d89603fdcbf1d58116bfd4c8e9
6
+ metadata.gz: 9768ae568bb5b7688320d5c6fc48dee29c5f551614622c2e0f5ce9f0efe08b91891a5ef5798b912aed744e9c0cb6cea69a7a3fdb1046dcbe528cd8d760f634cc
7
+ data.tar.gz: e33ec41098720c971d57a925d57d9f77882e977bfea8273c60c4ff87b8b4302cdf323f51fe629a79f343c7db729a2ca9061feed631229c9818c39b6207759204
@@ -126,3 +126,4 @@
126
126
  @import 'utilities/overflow';
127
127
  @import 'utilities/truncate';
128
128
  @import 'utilities/vertical_align';
129
+ @import 'utilities/height';
@@ -1,7 +1,7 @@
1
1
  import React, { useEffect, useState } from 'react'
2
2
  import classnames from 'classnames'
3
3
  import { buildAriaProps, buildCss, buildDataProps, buildHtmlProps } from '../utilities/props'
4
- import { GlobalProps, globalProps } from '../utilities/globalProps'
4
+ import { GlobalProps, globalProps, globalInlineProps } from '../utilities/globalProps'
5
5
 
6
6
  type BackgroundColors = 'gradient' |
7
7
  'dark' |'light' | 'white' | 'success' | 'warning' | 'error' | 'info' | 'neutral' | 'primary' | 'shadow' |
@@ -145,6 +145,12 @@ const Background = (props: BackgroundProps): React.ReactElement => {
145
145
  } : {})
146
146
  };
147
147
 
148
+ const dynamicInlineProps = globalInlineProps(props);
149
+ const combinedStyles = {
150
+ ...backgroundStyle,
151
+ ...dynamicInlineProps
152
+ };
153
+
148
154
  const Tag: React.ReactElement | any = `${tag}`;
149
155
  const ariaProps = buildAriaProps(aria);
150
156
  const dataProps = buildDataProps(data);
@@ -158,7 +164,7 @@ const Background = (props: BackgroundProps): React.ReactElement => {
158
164
  alt={alt}
159
165
  className={classes}
160
166
  id={id}
161
- style={backgroundStyle}
167
+ style={combinedStyles}
162
168
  >
163
169
  {children}
164
170
  </Tag>
@@ -6,12 +6,12 @@
6
6
  ) do %>
7
7
  <%= content.presence || object.input %>
8
8
  <% if object.indeterminate %>
9
- <span class="pb_checkbox_indeterminate">
9
+ <span data-pb-checkbox-icon-span="true" class="pb_checkbox_indeterminate">
10
10
  <%= pb_rails("icon", props: { icon: "minus", classname: "indeterminate_icon", fixed_width: true}) %>
11
11
  <%= pb_rails("icon", props: { icon: "check", classname: "check_icon hidden", fixed_width: true}) %>
12
12
  </span>
13
13
  <% else %>
14
- <span class="pb_checkbox_checkmark">
14
+ <span data-pb-checkbox-icon-span="true" class="pb_checkbox_checkmark">
15
15
  <%= pb_rails("icon", props: { icon: "check", classname: "check_icon", fixed_width: true}) %>
16
16
  <%= pb_rails("icon", props: { icon: "minus", classname: "indeterminate_icon hidden", fixed_width: true}) %>
17
17
  </span>
@@ -18,10 +18,6 @@ module Playbook
18
18
  prop :form_spacing, type: Playbook::Props::Boolean,
19
19
  default: false
20
20
 
21
- def checked_html
22
- checked ? "checked='true'" : nil
23
- end
24
-
25
21
  def classname
26
22
  generate_classname("pb_checkbox_kit", checked_class) + indeterminate_class + error_class
27
23
  end
@@ -1,7 +1,84 @@
1
- <%= pb_rails("checkbox" , props: {
2
- text: "Select ",
3
- value: "checkbox-value",
4
- name: "main",
5
- indeterminate: true,
6
- id: "test-indeterminate-js"
7
- }) %>
1
+ <% checkboxes = [
2
+ { name: 'Coffee', id: 'coffee', checked: false },
3
+ { name: 'Ice Cream', id: 'ice-cream', checked: false },
4
+ { name: 'Chocolate', id: 'chocolate', checked: true }
5
+ ] %>
6
+
7
+ <%= pb_rails("table", props: { container: false, size: "md" }) do %>
8
+ <thead>
9
+ <tr>
10
+ <th>
11
+ <%= pb_rails("checkbox", props: {
12
+ checked: true,
13
+ text: "Uncheck All",
14
+ value: "checkbox-value",
15
+ name: "main-checkbox",
16
+ indeterminate: true,
17
+ id: "indeterminate-checkbox"
18
+ }) %>
19
+ </th>
20
+ </tr>
21
+ </thead>
22
+
23
+ <tbody>
24
+ <% checkboxes.each do |checkbox| %>
25
+ <tr>
26
+ <td>
27
+ <%= pb_rails("checkbox", props: {
28
+ checked: checkbox[:checked],
29
+ text: checkbox[:name],
30
+ value: checkbox[:id],
31
+ name: "#{checkbox[:id]}-indeterminate-checkbox",
32
+ id: "#{checkbox[:id]}-indeterminate-checkbox",
33
+ }) %>
34
+ </td>
35
+ </tr>
36
+ <% end %>
37
+ </tbody>
38
+ <% end %>
39
+
40
+ <script>
41
+ document.addEventListener('DOMContentLoaded', function() {
42
+ const mainCheckboxWrapper = document.getElementById('indeterminate-checkbox');
43
+ const mainCheckbox = document.getElementsByName("main-checkbox")[0];
44
+ const childCheckboxes = document.querySelectorAll('input[type="checkbox"][id$="indeterminate-checkbox"]');
45
+
46
+ const updateMainCheckbox = () => {
47
+ // Count the number of checked child checkboxes
48
+ const checkedCount = Array.from(childCheckboxes).filter(cb => cb.checked).length;
49
+ // Determine if the main checkbox should be in an indeterminate state
50
+ const indeterminate = checkedCount > 0 && checkedCount < childCheckboxes.length;
51
+
52
+ // Set the main checkbox states
53
+ mainCheckbox.indeterminate = indeterminate;
54
+ mainCheckbox.checked = checkedCount > 0;
55
+
56
+ // Determine the main checkbox label based on the number of checked checkboxes
57
+ const text = checkedCount === 0 ? 'Check All' : 'Uncheck All';
58
+
59
+ // Determine the icon class to add and remove based on the number of checked checkboxes
60
+ const iconClassToAdd = checkedCount === 0 ? 'pb_checkbox_checkmark' : 'pb_checkbox_indeterminate';
61
+ const iconClassToRemove = checkedCount === 0 ? 'pb_checkbox_indeterminate' : 'pb_checkbox_checkmark';
62
+
63
+ // Update main checkbox label
64
+ mainCheckboxWrapper.getElementsByClassName('pb_body_kit')[0].textContent = text;
65
+
66
+ // Add and remove the icon class to the main checkbox wrapper
67
+ mainCheckboxWrapper.querySelector('[data-pb-checkbox-icon-span]').classList.add(iconClassToAdd);
68
+ mainCheckboxWrapper.querySelector('[data-pb-checkbox-icon-span]').classList.remove(iconClassToRemove);
69
+
70
+ // Toggle the visibility of the checkbox icon based on the indeterminate state
71
+ mainCheckboxWrapper.getElementsByClassName("indeterminate_icon")[0].classList.toggle('hidden', !indeterminate);
72
+ mainCheckboxWrapper.getElementsByClassName("check_icon")[0].classList.toggle('hidden', indeterminate);
73
+ };
74
+
75
+ mainCheckbox.addEventListener('change', function() {
76
+ childCheckboxes.forEach(cb => cb.checked = this.checked);
77
+ updateMainCheckbox();
78
+ });
79
+
80
+ childCheckboxes.forEach(cb => {
81
+ cb.addEventListener('change', updateMainCheckbox);
82
+ });
83
+ });
84
+ </script>
@@ -2,7 +2,7 @@ import React, { useEffect, ReactElement } from 'react'
2
2
  import classnames from 'classnames'
3
3
  import useCollapsible from './useCollapsible'
4
4
 
5
- import { globalProps } from '../utilities/globalProps'
5
+ import { globalProps, globalInlineProps } from '../utilities/globalProps'
6
6
  import { buildAriaProps, buildCss, buildDataProps, buildHtmlProps } from '../utilities/props'
7
7
 
8
8
  import CollapsibleContent from './child_kits/CollapsibleContent'
@@ -75,6 +75,7 @@ const Collapsible = ({
75
75
  globalProps(props),
76
76
  className
77
77
  )
78
+ const dynamicInlineProps = globalInlineProps(props)
78
79
  return (
79
80
  <CollapsibleContext.Provider value={{ collapsed: isCollapsed, toggle, icon, iconSize, iconColor, onIconClick, onClick }}>
80
81
  <div
@@ -83,6 +84,7 @@ const Collapsible = ({
83
84
  {...htmlProps}
84
85
  className={classes}
85
86
  id={id}
87
+ style={dynamicInlineProps}
86
88
  >
87
89
  {Main ? (
88
90
  <CollapsibleMain {...mainProps}>
@@ -101,11 +101,7 @@ const Currency = (props: CurrencyProps): React.ReactElement => {
101
101
  return decimalPart ? `${formattedWhole}.${decimalPart}` : formattedWhole;
102
102
  }
103
103
 
104
- const swapNegative = size === "sm" && symbol !== ""
105
- const handleNegative = amount.startsWith("-") && swapNegative ? "-" : ""
106
- const getAbsoluteAmount = (amountString: string) => amountString.replace(/^-/,'')
107
- const getAbbrOrFormatAmount = abbreviate ? getAbbreviatedValue('amount') : formatAmount(getMatchingDecimalAmount)
108
- const getAmount = swapNegative ? getAbsoluteAmount(getAbbrOrFormatAmount) : getAbbrOrFormatAmount
104
+ const getAmount = abbreviate ? getAbbreviatedValue('amount') : formatAmount(getMatchingDecimalAmount)
109
105
  const getAbbreviation = abbreviate ? getAbbreviatedValue('unit') : null
110
106
  const getDecimalValue = abbreviate ? '' : getMatchingDecimalValue
111
107
 
@@ -122,7 +118,7 @@ const Currency = (props: CurrencyProps): React.ReactElement => {
122
118
  <div className={`pb_currency_wrapper${variantClass || emphasizedClass}`}>
123
119
  {unstyled ? (
124
120
  <>
125
- <div>{handleNegative}{symbol}</div>
121
+ <div>{symbol}</div>
126
122
  <div>{getAmount}</div>
127
123
  <div>
128
124
  {getAbbreviation}
@@ -136,7 +132,7 @@ const Currency = (props: CurrencyProps): React.ReactElement => {
136
132
  color="light"
137
133
  dark={dark}
138
134
  >
139
- {handleNegative}{symbol}
135
+ {symbol}
140
136
  </Body>
141
137
 
142
138
  <Title
@@ -3,12 +3,12 @@
3
3
 
4
4
  <div class=<%= "pb_currency_wrapper#{object.variant_class || object.emphasized_class}" %>>
5
5
  <% if object.unstyled %>
6
- <div><%= object.negative_sign %><%= object.symbol %></div>
6
+ <div><%= object.symbol %></div>
7
7
  <div><%= object.title_props[:text] %></div>
8
8
  <div><%= object.body_props[:text] %></div>
9
9
  <% else %>
10
10
  <%= pb_rails("body", props: object.currency_wrapper_props) do %>
11
- <%= object.negative_sign %><%= object.symbol %>
11
+ <%= object.symbol %>
12
12
  <% end %>
13
13
  <%= pb_rails("title", props: object.title_props) %>
14
14
  <%= pb_rails("body", props: object.body_props) %>
@@ -68,20 +68,12 @@ module Playbook
68
68
  def title_props
69
69
  {
70
70
  size: size_value,
71
- text: swap_negative ? absolute_amount(abbr_or_format_amount) : abbr_or_format_amount,
71
+ text: abbreviate ? abbreviated_value : formatted_amount,
72
72
  classname: "pb_currency_value",
73
73
  dark: dark,
74
74
  }
75
75
  end
76
76
 
77
- def abbr_or_format_amount
78
- abbreviate ? abbreviated_value : formatted_amount
79
- end
80
-
81
- def negative_sign
82
- amount.starts_with?("-") && swap_negative ? "-" : ""
83
- end
84
-
85
77
  def body_props
86
78
  {
87
79
  text: units_element,
@@ -167,14 +159,6 @@ module Playbook
167
159
  whole_value
168
160
  end
169
161
  end
170
-
171
- def absolute_amount(amount_string)
172
- amount_string.sub(/^-/, "")
173
- end
174
-
175
- def swap_negative
176
- size == "sm" && symbol != ""
177
- end
178
162
  end
179
163
  end
180
164
  end
@@ -7,7 +7,7 @@ import {
7
7
  buildDataProps,
8
8
  buildHtmlProps,
9
9
  } from "../utilities/props";
10
- import { globalProps } from "../utilities/globalProps";
10
+ import { globalProps, globalInlineProps } from "../utilities/globalProps";
11
11
 
12
12
  import { DialogContext } from "../pb_dialog/_dialog_context";
13
13
 
@@ -101,6 +101,8 @@ const Drawer = (props: DrawerProps): React.ReactElement => {
101
101
 
102
102
  const classes = classnames(buildCss("pb_drawer_wrapper"), className);
103
103
 
104
+ const dynamicInlineProps = globalInlineProps(props)
105
+
104
106
  const [triggerOpened, setTriggerOpened] = useState(false);
105
107
 
106
108
  const breakpointWidths: Record<DrawerProps["breakpoint"], number> = {
@@ -198,6 +200,7 @@ const Drawer = (props: DrawerProps): React.ReactElement => {
198
200
  {...dataProps}
199
201
  {...htmlProps}
200
202
  className={classes}
203
+ style={dynamicInlineProps}
201
204
  >
202
205
  {isModalVisible && (
203
206
  <div
@@ -53,6 +53,7 @@
53
53
  }
54
54
 
55
55
  .pb_dropdown_container {
56
+ position: absolute;
56
57
  background-color: $white;
57
58
  overflow: hidden;
58
59
  box-shadow: $shadow_deep;
@@ -3,7 +3,6 @@
3
3
  class: object.classname,
4
4
  data: object.data,
5
5
  id: object.id,
6
- style: object.container_style,
7
6
  **combined_html_options) do %>
8
7
  <%= pb_rails("list", props: {ordered: false, borderless: false}) do %>
9
8
  <% if content.present? %>
@@ -7,10 +7,6 @@ module Playbook
7
7
  generate_classname("pb_dropdown_container", "close", separator: " ")
8
8
  end
9
9
 
10
- def container_style
11
- "position: absolute"
12
- end
13
-
14
10
  def data
15
11
  Hash(prop(:data)).merge(dropdown_container: true)
16
12
  end
@@ -23,7 +23,7 @@
23
23
  %>
24
24
 
25
25
  <%= pb_form_with(scope: :example, url: "", method: :get) do |form| %>
26
- <%= form.typeahead :example_user, props: { data: { typeahead_example1: true, user: {} }, placeholder: "Search for a user" } %>
26
+ <%= form.typeahead :example_typeahead, props: { data: { typeahead_example1: true, user: {} }, label: true, placeholder: "Search for a user" } %>
27
27
  <%= form.text_field :example_text_field, props: { label: true } %>
28
28
  <%= form.phone_number_field :example_phone_number_field, props: { label: "Example phone field" } %>
29
29
  <%= form.email_field :example_email_field, props: { label: true } %>
@@ -92,7 +92,7 @@
92
92
  const selectedUserData = JSON.parse(selectedUserJSON)
93
93
 
94
94
  // set the input field's value
95
- event.target.querySelector('input[name=example_user]').value = selectedUserData.login
95
+ event.target.querySelector('input[name=example_typeahead]').value = selectedUserData.login
96
96
 
97
97
  // log the selected option's dataset
98
98
  console.log('The selected user data:')
@@ -1,5 +1,5 @@
1
1
  <%= pb_form_with(scope: :example, url: "", method: :get, loading: true) do |form| %>
2
- <%= form.text_field :example_text_field, props: { label: true } %>
2
+ <%= form.text_field :example_text_field_loading, props: { label: true } %>
3
3
 
4
4
  <%= form.actions do |action| %>
5
5
  <%= action.submit %>
@@ -22,23 +22,74 @@
22
22
  %>
23
23
 
24
24
  <%= pb_form_with(scope: :example, method: :get, url: "", validate: true) do |form| %>
25
- <%= form.text_field :example_text_field, props: { label: true, required: true } %>
26
- <%= form.phone_number_field :example_phone_number_field, props: { label: "Example phone field" } %>
27
- <%= form.email_field :example_email_field, props: { label: true, required: true } %>
28
- <%= form.number_field :example_number_field, props: { label: true, required: true } %>
29
- <%= form.search_field :example_project_number, props: { label: true, required: true, validation: { pattern: "[0-9]{2}-[0-9]{5}", message: "Please enter a valid project number (example: 33-12345)." } } %>
30
- <%= form.password_field :example_password_field, props: { label: true, required: true } %>
31
- <%= form.url_field :example_url_field, props: { label: true, required: true } %>
32
- <%= form.text_area :example_text_area, props: { label: true, required: true } %>
33
- <%= form.dropdown_field :example_dropdown, props: { label: true, options: example_dropdown_options, required: true } %>
34
- <%= form.select :example_select, [ ["Yes", 1], ["No", 2] ], props: { label: true, blank_selection: "Select One...", required: true } %>
35
- <%= form.collection_select :example_collection_select, example_collection, :value, :name, props: { label: true, blank_selection: "Select One...", required: true } %>
25
+ <%= form.typeahead :example_typeahead_validation, props: { data: { typeahead_example2: true, user: {} }, label: true, placeholder: "Search for a user", required: true, validation: { message: "Please select a user." } } %>
26
+ <%= form.text_field :example_text_field_validation, props: { label: true, required: true } %>
27
+ <%= form.phone_number_field :example_phone_number_field_validation, props: { label: "Example phone field" } %>
28
+ <%= form.email_field :example_email_field_validation, props: { label: true, required: true } %>
29
+ <%= form.number_field :example_number_field_validation, props: { label: true, required: true } %>
30
+ <%= form.search_field :example_project_number_validation, props: { label: true, required: true, validation: { pattern: "[0-9]{2}-[0-9]{5}", message: "Please enter a valid project number (example: 33-12345)." } } %>
31
+ <%= form.password_field :example_password_field_validation, props: { label: true, required: true } %>
32
+ <%= form.url_field :example_url_field_validation, props: { label: true, required: true } %>
33
+ <%= form.text_area :example_text_area_validation, props: { label: true, required: true } %>
34
+ <%= form.dropdown_field :example_dropdown_validation, props: { label: true, options: example_dropdown_options, required: true } %>
35
+ <%= form.select :example_select_validation, [ ["Yes", 1], ["No", 2] ], props: { label: true, blank_selection: "Select One...", required: true } %>
36
+ <%= form.collection_select :example_collection_select_validation, example_collection, :value, :name, props: { label: true, blank_selection: "Select One...", required: true } %>
36
37
  <%= form.check_box :example_checkbox, props: { text: "Example Checkbox", label: true, required: true } %>
37
38
  <%= form.date_picker :example_date_picker_2, props: { label: true, required: true } %>
38
- <%= form.star_rating_field :example_star_rating, props: { variant: "interactive", label: true, required: true } %>
39
+ <%= form.star_rating_field :example_star_rating_validation, props: { variant: "interactive", label: true, required: true } %>
39
40
 
40
41
  <%= form.actions do |action| %>
41
42
  <%= action.submit %>
42
43
  <%= action.button props: { type: "reset", text: "Cancel", variant: "secondary" } %>
43
44
  <% end %>
44
45
  <% end %>
46
+
47
+ <!-- form.typeahead user results example template -->
48
+ <template data-typeahead-example-result-option>
49
+ <%= pb_rails("user", props: {
50
+ name: tag(:slot, name: "name"),
51
+ orientation: "horizontal",
52
+ align: "left",
53
+ avatar_url: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR4nGP6zwAAAgcBApocMXEAAAAASUVORK5CYII=",
54
+ avatar: true
55
+ }) %>
56
+ </template>
57
+
58
+ <!-- form.typeahead JS example implementation -->
59
+ <%= javascript_tag defer: "defer" do %>
60
+ document.addEventListener("pb-typeahead-kit-search", function(event) {
61
+ if (!event.target.dataset || !event.target.dataset.typeaheadExample2) return
62
+
63
+ fetch(`https://api.github.com/search/users?q=${encodeURIComponent(event.detail.searchingFor)}`)
64
+ .then(response => response.json())
65
+ .then((result) => {
66
+ const resultOptionTemplate = document.querySelector("[data-typeahead-example-result-option]")
67
+
68
+ event.detail.setResults((result.items || []).map((user) => {
69
+ const wrapper = resultOptionTemplate.content.cloneNode(true)
70
+ wrapper.children[0].dataset.user = JSON.stringify(user)
71
+ wrapper.querySelector('slot[name="name"]').replaceWith(user.login)
72
+ wrapper.querySelector('img').dataset.src = user.avatar_url
73
+ return wrapper
74
+ }))
75
+ })
76
+ })
77
+
78
+
79
+ document.addEventListener("pb-typeahead-kit-result-option-selected", function(event) {
80
+ if (!event.target.dataset.typeaheadExample2) return
81
+
82
+ const selectedUserJSON = event.detail.selected.firstElementChild.dataset.user
83
+ const selectedUserData = JSON.parse(selectedUserJSON)
84
+
85
+ // set the input field's value
86
+ event.target.querySelector('input[name=example_typeahead_validation]').value = selectedUserData.login
87
+
88
+ // log the selected option's dataset
89
+ console.log('The selected user data:')
90
+ console.dir(selectedUserData)
91
+
92
+ // do even more with the data later - TBD
93
+ event.target.dataset.user = selectedUserJSON
94
+ })
95
+ <% end %>
@@ -1,6 +1,6 @@
1
1
  import React from 'react'
2
2
  import classnames from 'classnames'
3
- import { GlobalProps, globalProps } from '../utilities/globalProps'
3
+ import { GlobalProps, globalProps, globalInlineProps } from '../utilities/globalProps'
4
4
  import { buildAriaProps, buildCss, buildDataProps, buildHtmlProps } from '../utilities/props'
5
5
 
6
6
  type ImageType = {
@@ -41,6 +41,7 @@ const Image = (props: ImageType): React.ReactElement => {
41
41
  globalProps(props),
42
42
  className
43
43
  )
44
+ const dynamicInlineProps = globalInlineProps(props)
44
45
  const dataProps = buildDataProps(data)
45
46
  const htmlProps = buildHtmlProps(htmlOptions)
46
47
 
@@ -56,6 +57,7 @@ const Image = (props: ImageType): React.ReactElement => {
56
57
  id={id}
57
58
  onError={onError}
58
59
  src={url}
60
+ style={dynamicInlineProps}
59
61
  />
60
62
  )
61
63
  }
@@ -2,7 +2,7 @@ import React from 'react'
2
2
  import classnames from 'classnames'
3
3
  import { buildAriaProps, buildCss, buildDataProps, buildHtmlProps } from '../utilities/props'
4
4
 
5
- import { globalProps } from '../utilities/globalProps'
5
+ import { GlobalProps, globalProps, globalInlineProps } from '../utilities/globalProps'
6
6
 
7
7
  type LayoutPropTypes = {
8
8
  aria?: {[key: string]: string},
@@ -19,7 +19,7 @@ type LayoutPropTypes = {
19
19
  variant?: "light" | "dark" | "gradient",
20
20
  transparent?: boolean,
21
21
  layout?: "sidebar" | "collection" | "kanban" | "content" | "masonry",
22
- }
22
+ } & GlobalProps
23
23
 
24
24
  type LayoutSideProps = {
25
25
  children: React.ReactNode[] | React.ReactNode,
@@ -159,6 +159,8 @@ const Layout = (props: LayoutPropTypes) => {
159
159
  const filteredProps = {...props}
160
160
  delete filteredProps?.position
161
161
 
162
+ const dynamicInlineProps = globalInlineProps(props)
163
+
162
164
  return (
163
165
  <div
164
166
  {...ariaProps}
@@ -171,7 +173,8 @@ const Layout = (props: LayoutPropTypes) => {
171
173
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
172
174
  //@ts-ignore
173
175
  globalProps(filteredProps)
174
- )}
176
+ )}
177
+ style={dynamicInlineProps}
175
178
  >
176
179
  {subComponentTags('Side')}
177
180
  {nonSideChildren}
@@ -1,7 +1,7 @@
1
1
  import React from 'react'
2
2
  import classnames from 'classnames'
3
3
  import { buildAriaProps, buildCss, buildDataProps, buildHtmlProps } from '../utilities/props'
4
- import { globalProps } from '../utilities/globalProps'
4
+ import { globalProps, globalInlineProps } from '../utilities/globalProps'
5
5
  import OverlayPercentage from './subcomponents/_overlay_percentage'
6
6
  import OverlayToken from './subcomponents/_overlay_token'
7
7
 
@@ -39,6 +39,7 @@ const Overlay = (props: OverlayProps) => {
39
39
  const dataProps = buildDataProps(data)
40
40
  const classes = classnames(buildCss('pb_overlay'), globalProps(props), className)
41
41
  const htmlProps = buildHtmlProps(htmlOptions)
42
+ const dynamicInlineProps = globalInlineProps(props)
42
43
 
43
44
  const getPosition = () => {
44
45
  return Object.keys(layout)[0]
@@ -57,6 +58,7 @@ const Overlay = (props: OverlayProps) => {
57
58
  {...htmlProps}
58
59
  className={classes}
59
60
  id={id}
61
+ style={dynamicInlineProps}
60
62
  >
61
63
  {isSizePercentage ?
62
64
  OverlayPercentage({
@@ -2,7 +2,7 @@ import React from 'react'
2
2
  import classnames from 'classnames'
3
3
 
4
4
  import { buildAriaProps, buildCss, buildDataProps, buildHtmlProps } from '../utilities/props'
5
- import { globalProps } from '../utilities/globalProps'
5
+ import { globalProps, globalInlineProps } from '../utilities/globalProps'
6
6
 
7
7
  import Caption from '../pb_caption/_caption'
8
8
 
@@ -38,6 +38,7 @@ const SectionSeparator = (props: SectionSeparatorProps): React.ReactElement => {
38
38
  const dataProps = buildDataProps(data)
39
39
  const htmlProps = buildHtmlProps(htmlOptions)
40
40
  const classes = classnames(buildCss('pb_section_separator_kit', variant, orientation, lineStyle === "dashed" ? lineStyle : ""), globalProps(props), className)
41
+ const dynamicInlineProps = globalInlineProps(props)
41
42
 
42
43
  return (
43
44
 
@@ -47,6 +48,7 @@ const SectionSeparator = (props: SectionSeparatorProps): React.ReactElement => {
47
48
  {...htmlProps}
48
49
  className={classes}
49
50
  id={id}
51
+ style={dynamicInlineProps}
50
52
  >
51
53
  {
52
54
  children && children ||
@@ -6,6 +6,7 @@
6
6
  value: "selected_with_icon",
7
7
  checked: true,
8
8
  icon: true,
9
+
9
10
  }) do %>
10
11
  Selected, with icon
11
12
  <% end %>
@@ -36,4 +37,4 @@
36
37
  Disabled
37
38
  <% end %>
38
39
 
39
- </div>
40
+ </div>
@@ -1,7 +1,7 @@
1
1
  import React, { useEffect } from 'react'
2
2
  import classnames from 'classnames'
3
3
  import { buildAriaProps, buildDataProps, buildHtmlProps } from '../utilities/props'
4
- import { globalProps, GlobalProps } from '../utilities/globalProps'
4
+ import { globalProps, GlobalProps, globalInlineProps } from '../utilities/globalProps'
5
5
  import PbTable from '.'
6
6
  import {
7
7
  TableHead,
@@ -64,6 +64,7 @@ const Table = (props: TableProps): React.ReactElement => {
64
64
  const spaceCssName = outerPadding !== 'none' ? 'space_' : ''
65
65
  const outerPaddingCss = outerPadding ? `outer_padding_${spaceCssName}${outerPadding}` : ''
66
66
  const isTableTag = tag === 'table'
67
+ const dynamicInlineProps = globalInlineProps(props)
67
68
 
68
69
  const classNames = classnames(
69
70
  'pb_table',
@@ -99,6 +100,7 @@ const Table = (props: TableProps): React.ReactElement => {
99
100
  {...htmlProps}
100
101
  className={classNames}
101
102
  id={id}
103
+ style={dynamicInlineProps}
102
104
  >
103
105
  {children}
104
106
  </table>
@@ -41,3 +41,50 @@
41
41
  }) %>
42
42
  <% end %>
43
43
  <% end %>
44
+
45
+ <br /><br /><br />
46
+
47
+ <%= pb_rails("timeline", props: {orientation: "vertical", show_date: true}) do %>
48
+ <%= pb_rails("timeline/item") do |item| %>
49
+
50
+ <% item.label do %>
51
+ <%= pb_rails("timeline/label") do %>
52
+ <%= pb_rails("title", props: { text: "Any Kit", size: 4 }) %>
53
+ <% end %>
54
+ <% end %>
55
+
56
+ <% item.step do %>
57
+ <%= pb_rails("timeline/step", props: { icon: 'user', icon_color: 'royal' }) %>
58
+ <% end %>
59
+
60
+ <% item.detail do %>
61
+ <%= pb_rails("title_detail", props: {
62
+ title: "Jackson Heights",
63
+ detail: "37-27 74th Street"
64
+ }) %>
65
+ <% end %>
66
+ <% end %>
67
+
68
+ <%= pb_rails("timeline/item", props: {icon: "map-marker-alt", icon_color: "purple", date: Date.today+1, line_style: "dotted" }) do |item| %>
69
+ <%= pb_rails("title_detail", props: {
70
+ title: "Society Hill",
71
+ detail: "72 E St Astoria"
72
+ }) %>
73
+ <% end %>
74
+
75
+ <%= pb_rails("timeline/item") do |item| %>
76
+
77
+ <% item.step do %>
78
+ <%= pb_rails("timeline/step") do %>
79
+ <%= pb_rails("pill", props: { text: "3" , variant: "success" }) %>
80
+ <% end %>
81
+ <% end %>
82
+
83
+ <% item.detail do %>
84
+ <%= pb_rails("title_detail", props: {
85
+ title: "Greenpoint",
86
+ detail: "81 Gate St Brooklyn"
87
+ }) %>
88
+ <% end %>
89
+ <% end %>
90
+ <% end %>