playbook_ui_docs 16.4.0.pre.alpha.PLAY2880selectablecardinputvariantstyle15361 → 16.4.0.pre.alpha.displaybreakpoints15091

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 (20) hide show
  1. checksums.yaml +4 -4
  2. data/app/pb_kits/playbook/pb_advanced_table/docs/example.yml +0 -1
  3. data/app/pb_kits/playbook/pb_button/docs/_button_full_width.md +1 -0
  4. data/app/pb_kits/playbook/pb_multi_level_select/docs/example.yml +0 -2
  5. data/app/pb_kits/playbook/pb_multi_level_select/docs/index.js +0 -1
  6. data/app/pb_kits/playbook/pb_table/docs/_sections.yml +0 -1
  7. data/app/pb_kits/playbook/pb_table/docs/_table_with_filter_variant_rails.md +1 -2
  8. data/app/pb_kits/playbook/pb_table/docs/example.yml +0 -1
  9. data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_with_highlight.jsx +8 -20
  10. metadata +3 -12
  11. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_pinned_rows_rails.html.erb +0 -57
  12. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_pinned_rows_rails.md +0 -7
  13. data/app/pb_kits/playbook/pb_button/docs/_button_full_width_rails.md +0 -19
  14. data/app/pb_kits/playbook/pb_button/docs/_button_full_width_react.md +0 -23
  15. data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_placeholder.html.erb +0 -109
  16. data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_placeholder.jsx +0 -127
  17. data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_placeholder.md +0 -1
  18. data/app/pb_kits/playbook/pb_table/docs/_table_with_filter_variant_external_filter_rails.html.erb +0 -45
  19. data/app/pb_kits/playbook/pb_table/docs/_table_with_filter_variant_external_filter_rails.md +0 -39
  20. data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_with_highlight.md +0 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5a635d8ee473cdf6e448404bc811663cd077069ec62032c45e253477bf989b39
4
- data.tar.gz: 11251803ecf88a4e910177e8c2e0bd21cc54d56cc935179e3069222f94fde6a2
3
+ metadata.gz: 4d76349497c9aed9fbdb3db641ffc35173b5b359a82e3002169c22dac3bd7bd5
4
+ data.tar.gz: 93ac2b9d7fb72999554b19883582e24168ec8e00ebc57cc6a4a01aefeb81b1e0
5
5
  SHA512:
6
- metadata.gz: abe24aeb08d411709b6263e7847a637bb05ed8b7eb6e3600a8617a2ce9ca0020af13dac4a99f35e1aa023a9dc8f5b8328bb47c8fc09f95fada625b0420010147
7
- data.tar.gz: f466ae2c5db1f13c53c4e49bc85ec60bce28ce28a5f9420ee93cba28cc54d2c06debe10dff6633aec083fdc606b5ca07a1dbcc611313d041f9869ff99da71be3
6
+ metadata.gz: 5f7a324c2d795c8f7950252bc26fda991c90b20a71620f53646fcae7dea1e12c3f2e3fe777f51dae18f6b82cb74a9ef5483a4fd355847b51305353d96a8698a2
7
+ data.tar.gz: ac4f91556a586902d24d8a647dee141c1501dea08671ac8791ec2decb7b5942bf2949f8220f774dd38d46854c6cce8c9ca511cdb8e5d8d31426a69fe1e32ba16
@@ -7,7 +7,6 @@ examples:
7
7
  - advanced_table_table_props: Table Props
8
8
  - advanced_table_sticky_header_rails: Sticky Header
9
9
  - advanced_table_table_props_sticky_header: Sticky Header for Responsive Table
10
- - advanced_table_pinned_rows_rails: Pinned Rows
11
10
  - advanced_table_beta_sort: Enable Sorting
12
11
  - advanced_table_responsive: Responsive Tables
13
12
  - advanced_table_custom_cell_rails: Custom Components for Cells
@@ -0,0 +1 @@
1
+ This button is used many times for mobile or other things like cards and sidebars.
@@ -18,7 +18,6 @@ examples:
18
18
  - multi_level_select_disabled_options_parent: Disabled Parent Option (Return All Selected)
19
19
  - multi_level_select_single_disabled: Disabled Options (Single Select)
20
20
  - multi_level_select_required_indicator: Required Indicator
21
- - multi_level_select_placeholder: Placeholder
22
21
 
23
22
  react:
24
23
  - multi_level_select_default: Default
@@ -41,4 +40,3 @@ examples:
41
40
  - multi_level_select_single_disabled: Disabled Options (Single Select)
42
41
  - multi_level_select_required_indicator: Required Indicator
43
42
  - multi_level_select_react_reset_key: Reset with Key (React)
44
- - multi_level_select_placeholder: Placeholder
@@ -18,4 +18,3 @@ export { default as MultiLevelSelectLabel } from "./_multi_level_select_label.js
18
18
  export { default as MultiLevelSelectSingleDisabled } from "./_multi_level_select_single_disabled.jsx"
19
19
  export { default as MultiLevelSelectRequiredIndicator } from "./_multi_level_select_required_indicator.jsx"
20
20
  export { default as MultiLevelSelectReactResetKey } from "./_multi_level_select_react_reset_key.jsx"
21
- export { default as MultiLevelSelectPlaceholder } from "./_multi_level_select_placeholder.jsx"
@@ -55,7 +55,6 @@ sections:
55
55
  - table_with_clickable_rows
56
56
  - table_with_selectable_rows
57
57
  - table_with_filter_variant
58
- - table_with_filter_variant_external_filter_rails
59
58
  - table_with_filter_variant_with_pagination
60
59
  - table_disable_hover
61
60
 
@@ -26,9 +26,8 @@ The Table kit automatically sets these Filter defaults (which you can override v
26
26
  - `min_width: "xs"`
27
27
  - `popover_props: { width: "350px" }`
28
28
 
29
- Alternatively, you can pass pre-rendered filter markup via the `filter` prop (e.g. for manual submission or custom filter helpers)—scroll down for that approach.
30
29
 
31
30
  **IMPORTANT NOTE**:
32
31
  The purpose of this variant is to provide an easy way to set up a Table with a Filter with Design standards applied by default.
33
32
 
34
- If you are looking for more customization than this embedded variant provides, you may be better served by using the individual kits as demonstrated in our Table Filter Card Building Block as seen [here](https://playbook.powerapp.cloud/building_blocks/table_filter_card/rails).
33
+ If you are looking for more customization than this embedded variant provides, you may be better served by using the individual kits as demonstrating in our Table Filter Card Building Block as seen [here](https://playbook.powerapp.cloud/building_blocks/table_filter_card/rails).
@@ -41,7 +41,6 @@ examples:
41
41
  - table_with_header_style_borderless: Header Style Borderless
42
42
  - table_with_header_style_floating: Header Style Floating
43
43
  - table_with_filter_variant_rails: Variant with Filter
44
- - table_with_filter_variant_external_filter_rails: Variant with Filter (External Filter)
45
44
  - table_with_filter_variant_with_pagination_rails: Variant with Filter and Pagination
46
45
  - table_with_filter_with_card_title_props_rails: Variant with Filter (with Card and Title Props)
47
46
 
@@ -1,3 +1,4 @@
1
+ /* eslint-disable react/no-danger */
1
2
  /* eslint-disable react/no-multi-comp */
2
3
 
3
4
  import React, { useState } from 'react'
@@ -37,26 +38,14 @@ const TypeaheadWithHighlight = (props) => {
37
38
  const [selectedUser, setSelectedUser] = useState()
38
39
 
39
40
  const formatOptionLabel = ({name, territory, title}, {inputValue}) => {
40
- const escapeRegExp = (value = "") => (
41
- value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")
42
- )
43
41
 
44
- const highlighted = (text = "") => {
42
+ const highlighted = (text) => {
45
43
  if (!inputValue.length) return text
46
-
47
- const escapedInputValue = escapeRegExp(inputValue)
48
- const regex = new RegExp(`(${escapedInputValue})`, 'gi')
49
- const parts = text.split(regex)
50
-
51
- return parts.map((part, index) => {
52
- if (part.toLowerCase() === inputValue.toLowerCase()) {
53
- return <mark key={`${part}-${index}`}>{part}</mark>
54
- }
55
-
56
- return <React.Fragment key={`${part}-${index}`}>{part}</React.Fragment>
57
- })
44
+ return text.replace(
45
+ new RegExp(inputValue, 'gi'),
46
+ (highlighted) => `<mark>${highlighted}</mark>`
47
+ )
58
48
  }
59
-
60
49
  return (
61
50
  <Flex>
62
51
  <FlexItem>
@@ -72,12 +61,11 @@ const TypeaheadWithHighlight = (props) => {
72
61
  size={4}
73
62
  {...props}
74
63
  >
75
- {highlighted(name)}
76
- </Title>
64
+ <span dangerouslySetInnerHTML={{ __html: highlighted(name) }} /></Title>
77
65
  <Body color="light"
78
66
  {...props}
79
67
  >
80
- {highlighted(title)}{" • "}
68
+ <span dangerouslySetInnerHTML={{ __html: highlighted(title) }} />{" • "}
81
69
  {territory}
82
70
  </Body>
83
71
  </FlexItem>
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: playbook_ui_docs
3
3
  version: !ruby/object:Gem::Version
4
- version: 16.4.0.pre.alpha.PLAY2880selectablecardinputvariantstyle15361
4
+ version: 16.4.0.pre.alpha.displaybreakpoints15091
5
5
  platform: ruby
6
6
  authors:
7
7
  - Power UX
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2026-03-31 00:00:00.000000000 Z
12
+ date: 2026-03-18 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: playbook_ui
@@ -125,8 +125,6 @@ files:
125
125
  - app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_pagination_with_props.jsx
126
126
  - app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_pagination_with_props.md
127
127
  - app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_pinned_rows.jsx
128
- - app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_pinned_rows_rails.html.erb
129
- - app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_pinned_rows_rails.md
130
128
  - app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_pinned_rows_react.md
131
129
  - app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_responsive.html.erb
132
130
  - app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_responsive.jsx
@@ -309,8 +307,7 @@ files:
309
307
  - app/pb_kits/playbook/pb_button/docs/_button_form.jsx
310
308
  - app/pb_kits/playbook/pb_button/docs/_button_full_width.html.erb
311
309
  - app/pb_kits/playbook/pb_button/docs/_button_full_width.jsx
312
- - app/pb_kits/playbook/pb_button/docs/_button_full_width_rails.md
313
- - app/pb_kits/playbook/pb_button/docs/_button_full_width_react.md
310
+ - app/pb_kits/playbook/pb_button/docs/_button_full_width.md
314
311
  - app/pb_kits/playbook/pb_button/docs/_button_full_width_swift.md
315
312
  - app/pb_kits/playbook/pb_button/docs/_button_hover.html.erb
316
313
  - app/pb_kits/playbook/pb_button/docs/_button_hover.jsx
@@ -1462,9 +1459,6 @@ files:
1462
1459
  - app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_label.html.erb
1463
1460
  - app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_label.jsx
1464
1461
  - app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_label.md
1465
- - app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_placeholder.html.erb
1466
- - app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_placeholder.jsx
1467
- - app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_placeholder.md
1468
1462
  - app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_react_hook.jsx
1469
1463
  - app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_react_hook.md
1470
1464
  - app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_react_reset_key.jsx
@@ -2304,8 +2298,6 @@ files:
2304
2298
  - app/pb_kits/playbook/pb_table/docs/_table_with_dynamic_collapsible_react.md
2305
2299
  - app/pb_kits/playbook/pb_table/docs/_table_with_filter_variant.jsx
2306
2300
  - app/pb_kits/playbook/pb_table/docs/_table_with_filter_variant.md
2307
- - app/pb_kits/playbook/pb_table/docs/_table_with_filter_variant_external_filter_rails.html.erb
2308
- - app/pb_kits/playbook/pb_table/docs/_table_with_filter_variant_external_filter_rails.md
2309
2301
  - app/pb_kits/playbook/pb_table/docs/_table_with_filter_variant_rails.html.erb
2310
2302
  - app/pb_kits/playbook/pb_table/docs/_table_with_filter_variant_rails.md
2311
2303
  - app/pb_kits/playbook/pb_table/docs/_table_with_filter_variant_with_pagination.jsx
@@ -2662,7 +2654,6 @@ files:
2662
2654
  - app/pb_kits/playbook/pb_typeahead/docs/_typeahead_truncated_text.md
2663
2655
  - app/pb_kits/playbook/pb_typeahead/docs/_typeahead_with_context.html.erb
2664
2656
  - app/pb_kits/playbook/pb_typeahead/docs/_typeahead_with_highlight.jsx
2665
- - app/pb_kits/playbook/pb_typeahead/docs/_typeahead_with_highlight.md
2666
2657
  - app/pb_kits/playbook/pb_typeahead/docs/_typeahead_with_pills.html.erb
2667
2658
  - app/pb_kits/playbook/pb_typeahead/docs/_typeahead_with_pills.jsx
2668
2659
  - app/pb_kits/playbook/pb_typeahead/docs/_typeahead_with_pills.md
@@ -1,57 +0,0 @@
1
- <%# Example sort method for demonstration purposes %>
2
- <% if params["sort"] %>
3
- <% sort_param = params["sort"].gsub(/_(asc|desc)\z/, "") %>
4
- <% sort_direction = params["sort"].end_with?("_asc") ? 1 : -1 %>
5
- <% @table_data_with_id.sort! do |a, b|
6
- value_a = a[sort_param] || a[sort_param.to_sym]
7
- value_b = b[sort_param] || b[sort_param.to_sym]
8
-
9
- value_a = value_a.to_i if value_a.is_a?(String) && value_a.match?(/^\d+$/)
10
- value_b = value_b.to_i if value_b.is_a?(String) && value_b.match?(/^\d+$/)
11
-
12
- sort_direction * (value_a <=> value_b)
13
- end %>
14
- <% end %>
15
-
16
- <% column_definitions = [
17
- {
18
- accessor: "year",
19
- label: "Year",
20
- cellAccessors: ["quarter", "month", "day"],
21
- sort_menu: [
22
- { item: "Year", link: "?sort=year_asc#pinned_rows_table", active: params["sort"] == "year_asc", direction: "asc" },
23
- { item: "Year", link: "?sort=year_desc#pinned_rows_table", active: params["sort"] == "year_desc", direction: "desc" }
24
- ],
25
- },
26
- {
27
- accessor: "newEnrollments",
28
- label: "New Enrollments",
29
- },
30
- {
31
- accessor: "scheduledMeetings",
32
- label: "Scheduled Meetings",
33
- },
34
- {
35
- accessor: "attendanceRate",
36
- label: "Attendance Rate",
37
- },
38
- {
39
- accessor: "completedClasses",
40
- label: "Completed Classes",
41
- },
42
- {
43
- accessor: "classCompletionRate",
44
- label: "Class Completion Rate",
45
- },
46
- {
47
- accessor: "graduatedStudents",
48
- label: "Graduated Students",
49
- }
50
- ] %>
51
-
52
- <% pinned_rows = { top: ["8"] } %>
53
-
54
- <%= pb_rails("advanced_table", props: { id: "pinned_rows_table", table_data: @table_data_with_id, column_definitions: column_definitions, max_height: "xs", pinned_rows: pinned_rows, responsive: "none", table_props: { sticky: true }}) do %>
55
- <%= pb_rails("advanced_table/table_header", props: { table_id: "pinned_rows_table", column_definitions: column_definitions }) %>
56
- <%= pb_rails("advanced_table/table_body", props: { table_id: "pinned_rows_table", table_data: @table_data_with_id, column_definitions: column_definitions, pinned_rows: pinned_rows }) %>
57
- <% end %>
@@ -1,7 +0,0 @@
1
- Use the `pinned_rows` prop to pin specific rows to the top of an Advanced Table. Pinned rows will remain at the top when scrolling through table data and will not change position if sorting is used.
2
-
3
- **NOTE:**
4
- - Sticky header required: Pinned rows must be used with `sticky: true` via `table_props` (works with both responsive and non-responsive tables)
5
- - Row ids required: Each object within the `table_data` array must contain a unique `id` in order to attach an id to all Rows for this to function.
6
- - `pinned_rows` takes a hash with a `top` key containing an array of row ids, as shown in the code snippet below.
7
- - For expandable rows, use the parent id in `pinned_rows[:top]`; all its children will automatically be pinned with it. If a child id is passed without the parent being pinned, nothing will be pinned.
@@ -1,19 +0,0 @@
1
- This button is used many times for mobile or other things like cards and sidebars.
2
-
3
- ### Responsive `display` and `full_width`
4
-
5
- `full_width` applies block styling that includes `display: flex` on the **same element** as the button. The **`display` global prop** also sets `display` (via utility classes, often with `!important`).
6
-
7
- Putting **both** on one button means **two systems control `display` on one node**, which can cause wrong visibility (e.g. both a header and a full-width mobile button showing) or confusing cascade behavior.
8
-
9
- **Recommended:** Put responsive `display` on a **parent** (e.g. `Flex`, `Card`, or a plain wrapper) and keep `full_width` only on the `Button` inside. The wrapper handles show/hide by breakpoint; the button only handles full-width layout.
10
-
11
- ```erb
12
- <%= pb_rails("flex", props: {
13
- display: { xs: "flex", default: "none" },
14
- orientation: "column",
15
- width: "100%",
16
- }) do %>
17
- <%= pb_rails("button", props: { full_width: true, text: "Add" }) %>
18
- <% end %>
19
- ```
@@ -1,23 +0,0 @@
1
- This button is used many times for mobile or other things like cards and sidebars.
2
-
3
- ### Responsive `display` and `full_width`
4
-
5
- `full_width` applies block styling that includes `display: flex` on the **same element** as the button. The **`display` global prop** also sets `display` (via utility classes, often with `!important`).
6
-
7
- Putting **both** on one button means **two systems control `display` on one node**, which can cause wrong visibility (e.g. both a header and a full-width mobile button showing) or confusing cascade behavior.
8
-
9
- **Recommended:** Put responsive `display` on a **parent** (e.g. `Flex`, `Card`, or a plain wrapper) and keep `fullWidth` only on the `Button` inside. The wrapper handles show/hide by breakpoint; the button only handles full-width layout.
10
-
11
- ```jsx
12
- import { Flex, Button } from "playbook-ui"
13
-
14
- const Example = () => (
15
- <Flex
16
- display={{ xs: "flex", default: "none" }}
17
- orientation="column"
18
- width="100%"
19
- >
20
- <Button fullWidth text="Add" />
21
- </Flex>
22
- )
23
- ```
@@ -1,109 +0,0 @@
1
- <%
2
- tree_base = [{
3
- label: "Power Home Remodeling",
4
- value: "powerHomeRemodeling",
5
- id: "100",
6
- expanded: true,
7
- children: [
8
- {
9
- label: "People",
10
- value: "people",
11
- id: "101",
12
- expanded: true,
13
- children: [
14
- {
15
- label: "Talent Acquisition",
16
- value: "talentAcquisition",
17
- id: "102",
18
- },
19
- {
20
- label: "Business Affairs",
21
- value: "business Affairs",
22
- id: "103",
23
- children: [
24
- {
25
- label: "Initiatives",
26
- value: "initiatives",
27
- id: "104",
28
- },
29
- {
30
- label: "Learning & Development",
31
- value: "learningAndDevelopment",
32
- id: "105",
33
- },
34
- ],
35
- },
36
- {
37
- label: "People Experience",
38
- value: "peopleExperience",
39
- id: "106",
40
- },
41
- ],
42
- },
43
- {
44
- label: "Contact Center",
45
- value: "contactCenter",
46
- id: "107",
47
- children: [
48
- {
49
- label: "Appointment Management",
50
- value: "appointmentManagement",
51
- id: "108",
52
- },
53
- {
54
- label: "Customer Service",
55
- value: "customerService",
56
- id: "109",
57
- },
58
- {
59
- label: "Energy",
60
- value: "energy",
61
- id: "110",
62
- },
63
- ],
64
- },
65
- ],
66
- }]
67
-
68
- prefix_mls_ids = nil
69
- prefix_mls_ids = ->(nodes, pfx) {
70
- nodes.map do |n|
71
- h = n.dup
72
- h[:id] = "#{pfx}#{n[:id]}"
73
- h[:children] = prefix_mls_ids.call(n[:children], pfx) if n[:children].present?
74
- h
75
- end
76
- }
77
-
78
- tree_multi = prefix_mls_ids.call(tree_base, "phm_")
79
- tree_return_all = prefix_mls_ids.call(tree_base, "phr_")
80
- tree_single = prefix_mls_ids.call(tree_base, "phs_")
81
- %>
82
-
83
- <%= pb_rails("multi_level_select", props: {
84
- id: "multi-level-select-placeholder-multi-rails",
85
- label: "Multi (default)",
86
- margin_bottom: "sm",
87
- name: "placeholder_multi",
88
- tree_data: tree_multi,
89
- placeholder: "Search or choose options…",
90
- }) %>
91
-
92
- <%= pb_rails("multi_level_select", props: {
93
- id: "multi-level-select-placeholder-return-all-rails",
94
- label: "Multi (return all selected)",
95
- margin_bottom: "sm",
96
- name: "placeholder_return_all",
97
- placeholder: "Departments...",
98
- return_all_selected: true,
99
- tree_data: tree_return_all,
100
- }) %>
101
-
102
- <%= pb_rails("multi_level_select", props: {
103
- id: "multi-level-select-placeholder-single-rails",
104
- label: "Single",
105
- name: "placeholder_single",
106
- placeholder: "Select one option…",
107
- tree_data: tree_single,
108
- variant: "single",
109
- }) %>
@@ -1,127 +0,0 @@
1
- import React from "react";
2
-
3
- import MultiLevelSelect from "../_multi_level_select";
4
-
5
- const treeTemplate = [
6
- {
7
- label: "Power Home Remodeling",
8
- value: "powerHomeRemodeling",
9
- id: "powerhome1",
10
- expanded: true,
11
- children: [
12
- {
13
- label: "People",
14
- value: "people",
15
- id: "people1",
16
- expanded: true,
17
- children: [
18
- {
19
- label: "Talent Acquisition",
20
- value: "talentAcquisition",
21
- id: "talent1",
22
- },
23
- {
24
- label: "Business Affairs",
25
- value: "businessAffairs",
26
- id: "business1",
27
- children: [
28
- {
29
- label: "Initiatives",
30
- value: "initiatives",
31
- id: "initiative1",
32
- },
33
- {
34
- label: "Learning & Development",
35
- value: "learningAndDevelopment",
36
- id: "development1",
37
- },
38
- ],
39
- },
40
- {
41
- label: "People Experience",
42
- value: "peopleExperience",
43
- id: "experience1",
44
- },
45
- ],
46
- },
47
- {
48
- label: "Contact Center",
49
- value: "contactCenter",
50
- id: "contact1",
51
- children: [
52
- {
53
- label: "Appointment Management",
54
- value: "appointmentManagement",
55
- id: "appointment1",
56
- },
57
- {
58
- label: "Customer Service",
59
- value: "customerService",
60
- id: "customer1",
61
- },
62
- {
63
- label: "Energy",
64
- value: "energy",
65
- id: "energy1",
66
- },
67
- ],
68
- },
69
- ],
70
- },
71
- ];
72
-
73
- function prefixTreeIds(nodes, prefix) {
74
- return nodes.map((node) => ({
75
- ...node,
76
- id: `${prefix}${node.id}`,
77
- children:
78
- node.children && node.children.length > 0
79
- ? prefixTreeIds(node.children, prefix)
80
- : node.children,
81
- }));
82
- }
83
-
84
- const treeDataMulti = prefixTreeIds(treeTemplate, "phm_");
85
- const treeDataReturnAll = prefixTreeIds(treeTemplate, "phr_");
86
- const treeDataSingle = prefixTreeIds(treeTemplate, "phs_");
87
-
88
- const MultiLevelSelectPlaceholder = () => (
89
- <>
90
- <MultiLevelSelect
91
- id="multi-level-select-placeholder-multi"
92
- label="Multi (default)"
93
- marginBottom="sm"
94
- name="placeholder_multi"
95
- onSelect={(selectedNodes) =>
96
- console.log("Multi — default", selectedNodes)
97
- }
98
- placeholder="Search or choose options…"
99
- treeData={treeDataMulti}
100
- />
101
- <MultiLevelSelect
102
- id="multi-level-select-placeholder-return-all"
103
- label="Multi (return all selected)"
104
- marginBottom="sm"
105
- name="placeholder_return_all"
106
- onSelect={(selectedNodes) =>
107
- console.log("Multi — return all selected", selectedNodes)
108
- }
109
- placeholder="Departments..."
110
- returnAllSelected
111
- treeData={treeDataReturnAll}
112
- />
113
- <MultiLevelSelect
114
- id="multi-level-select-placeholder-single"
115
- label="Single"
116
- name="placeholder_single"
117
- onSelect={(selectedNodes) =>
118
- console.log("Single", selectedNodes)
119
- }
120
- placeholder="Select one option…"
121
- treeData={treeDataSingle}
122
- variant="single"
123
- />
124
- </>
125
- );
126
-
127
- export default MultiLevelSelectPlaceholder;
@@ -1 +0,0 @@
1
- Use the `placeholder` prop to customize the initial text shown in the input when nothing is selected. The default is `Start typing...`.
@@ -1,45 +0,0 @@
1
- <%# External filter: capture any filter markup and pass it via the filter prop.
2
- Use your own helper (e.g. a search/filter form) or pb_rails("filter") as shown here. %>
3
- <% users = [
4
- { name: "Alex", role: "Engineer" },
5
- { name: "Sam", role: "Designer" },
6
- { name: "Jordan", role: "Manager" },
7
- ] %>
8
-
9
- <% filter_output = capture do %>
10
- <%= pb_rails("filter", props: {
11
- id: "external-filter-demo",
12
- template: "single",
13
- results: 3,
14
- background: false,
15
- sort_menu: [
16
- { item: "Name", link: "#", active: true, direction: "asc" },
17
- { item: "Role", link: "#", active: false },
18
- ],
19
- }) do %>
20
- <%= pb_rails("text_input", props: { label: "Name", placeholder: "Search by name" }) %>
21
- <%= pb_rails("text_input", props: { label: "Role", placeholder: "e.g. Engineer, Designer" }) %>
22
- <%= pb_rails("button", props: { text: "Apply" }) %>
23
- <% end %>
24
- <% end %>
25
-
26
- <%= pb_rails("table", props: {
27
- variant: "with_filter",
28
- title: "Table with External Filter",
29
- filter: filter_output,
30
- }) do %>
31
- <%= pb_rails("table/table_head") do %>
32
- <%= pb_rails("table/table_row") do %>
33
- <%= pb_rails("table/table_header", props: { text: "Name" }) %>
34
- <%= pb_rails("table/table_header", props: { text: "Role" }) %>
35
- <% end %>
36
- <% end %>
37
- <%= pb_rails("table/table_body") do %>
38
- <% users.each do |user| %>
39
- <%= pb_rails("table/table_row") do %>
40
- <%= pb_rails("table/table_cell") { user[:name] } %>
41
- <%= pb_rails("table/table_cell") { user[:role] } %>
42
- <% end %>
43
- <% end %>
44
- <% end %>
45
- <% end %>
@@ -1,39 +0,0 @@
1
- Use the **"with_filter"** variant with an **external filter** (Option B): pass pre-rendered filter markup via the `filter` prop. Same layout as Variant with Filter (card, title, separator, flex); only the filter slot is supplied by you. Use this when you need:
2
-
3
- - **Manual filter submission** – Apply / Filter button instead of automatic application
4
- - **Full control** – Over filter props, template, sort menu, and submission
5
- - **Custom or app-specific filter helpers** – Any helper that returns filter markup (e.g. search/filter forms)
6
-
7
- #### Required props
8
-
9
- - `variant: "with_filter"`
10
- - `filter` – Pre-rendered filter HTML (e.g. from `capture { ... }`)
11
-
12
- When `filter` is present, `filter_content` and `filter_props` are ignored.
13
-
14
- #### How to do it
15
-
16
- 1. **Render your filter** (e.g. `pb_rails("filter", ...)` or any helper that returns filter markup).
17
- 2. **Capture the output** with `capture do ... end`.
18
- 3. **Pass it to the Table** as the `filter` prop.
19
-
20
- **Example (generic pattern):**
21
-
22
- ```erb
23
- <% filter_output = capture do %>
24
- <%= pb_rails("filter", props: { template: "single", results: 10, background: false }) do %>
25
- <%= pb_rails("text_input", props: { label: "Name", placeholder: "Search by name" }) %>
26
- <%= pb_rails("button", props: { text: "Apply" }) %>
27
- <% end %>
28
- <% end %>
29
-
30
- <%= pb_rails("table", props: {
31
- variant: "with_filter",
32
- title: "My Table",
33
- filter: filter_output,
34
- }) do %>
35
- <%# table_head / table_body ... %>
36
- <% end %>
37
- ```
38
-
39
- For Nitro apps that use a shared search/filter pattern, reference the example on Alpha for implementation details.
@@ -1,3 +0,0 @@
1
- Use `formatOptionLabel` to customize each option row and highlight text that matches the current search input. Split each field (for example, `name` and `title`) by the typed value, then render matching parts inside `<mark>` so users can quickly see why a result matched.
2
-
3
- See the code snippet below for more details.