playbook_ui 16.10.0.pre.rc.2 → 16.10.0.pre.rc.3

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 (37) hide show
  1. checksums.yaml +4 -4
  2. data/app/pb_kits/playbook/pb_advanced_table/Components/RegularTableView.tsx +12 -5
  3. data/app/pb_kits/playbook/pb_advanced_table/Hooks/useTableState.ts +2 -2
  4. data/app/pb_kits/playbook/pb_advanced_table/Utilities/CellRendererUtils.tsx +4 -2
  5. data/app/pb_kits/playbook/pb_advanced_table/Utilities/RowUtils.ts +17 -0
  6. data/app/pb_kits/playbook/pb_advanced_table/advanced_table.test.jsx +55 -1
  7. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_row_styling.html.erb +4 -0
  8. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_row_styling.jsx +4 -0
  9. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_row_styling_rails.md +1 -0
  10. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_row_styling_react.md +1 -0
  11. data/app/pb_kits/playbook/pb_advanced_table/docs/_playground.json +2 -1
  12. data/app/pb_kits/playbook/pb_advanced_table/docs/_playground.overrides.json +1 -1
  13. data/app/pb_kits/playbook/pb_advanced_table/table_row.html.erb +2 -1
  14. data/app/pb_kits/playbook/pb_advanced_table/table_row.rb +16 -2
  15. data/app/pb_kits/playbook/pb_card/card.rb +1 -1
  16. data/app/pb_kits/playbook/pb_card/kit.schema.json +2 -0
  17. data/app/pb_kits/playbook/pb_filter/docs/_playground.json +7 -0
  18. data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_breached.html.erb +1 -1
  19. data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_common.html.erb +1 -1
  20. data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_meter_settings.html.erb +5 -5
  21. data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_strength_change.html.erb +1 -1
  22. data/app/pb_kits/playbook/pb_passphrase/index.ts +58 -0
  23. data/app/pb_kits/playbook/pb_passphrase/kit.schema.json +13 -0
  24. data/app/pb_kits/playbook/pb_passphrase/passphrase.html.erb +70 -1
  25. data/app/pb_kits/playbook/pb_passphrase/passphrase.rb +70 -0
  26. data/app/pb_kits/playbook/tokens/_colors.scss +5 -1
  27. data/dist/chunks/{_pb_line_graph-D8PSzzEY.js → _pb_line_graph-DYysA_-M.js} +1 -1
  28. data/dist/chunks/_typeahead-B0yIrn2R.js +5 -0
  29. data/dist/chunks/{globalProps-B8stOeTI.js → globalProps-CC-0LNvd.js} +1 -1
  30. data/dist/chunks/{lib-BAri19Ko.js → lib-BQnni8Yf.js} +2 -2
  31. data/dist/chunks/vendor.js +4 -4
  32. data/dist/playbook-rails-react-bindings.js +1 -1
  33. data/dist/playbook-rails.js +1 -1
  34. data/dist/playbook.css +1 -1
  35. data/lib/playbook/version.rb +1 -1
  36. metadata +7 -6
  37. data/dist/chunks/_typeahead-CbiY8rnB.js +0 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9c106506aaabdf972085be91718db366bd7fedcd876fbb790451952f6be69f40
4
- data.tar.gz: 658df9449e22d82fee8e4faeaa020c81876b6cbb435e399f1deeb3f9ab877426
3
+ metadata.gz: 8d1bc0ec165e39d2c81fd5f45542521a178ac02b01c3814d73af5a26ba715c61
4
+ data.tar.gz: e5d599d230b0924967dd5bc31eb78dad5127251b1ee9d529ecbb7df9d0f6be31
5
5
  SHA512:
6
- metadata.gz: 04f3e7df0c8f462350f090b3da1b59becb573547690516c09e9f7e4836ade7afb78cf8bbf635741fc9d61da70cb63263ce67d6e56e29450575f32c38dcec98fe
7
- data.tar.gz: 8598d0d5d9884ae6bf320b3bd6538ef6db48edde4b853d4252aa20e9b6e5f4df5c5eb7e162a7d9ae0e139513ce5152fbcca5a8a0ae4f96cbca5b163a559a3865
6
+ metadata.gz: 10075c3c837ea6cd669638bd72e0ac1ffd7da0e8b765e89740f14696b9e22336453dde87390b995f987429ec7cfee854ca4129bd17c9bf4eebfb939a053188e7
7
+ data.tar.gz: be76110b2a91fef82760e0031fc61efd72bca27054293ced304a639db07a7cfe1be3a7a2ae5bf4809525077579f06b1751816195f69ef44d831313287cb6a3d8
@@ -6,7 +6,7 @@ import { GenericObject } from "../../types"
6
6
  import { isChrome } from "../Utilities/BrowserCheck"
7
7
  import { findColumnDefByAccessor } from "../Utilities/ColumnStylingHelper"
8
8
  import { playbookColumnLayoutStylesFromMeta } from "../Utilities/ColumnLayoutHelper"
9
- import { getRowColorClass, shouldShowLoadingIndicator } from "../Utilities/RowUtils"
9
+ import { getFontWeight, getRowColorClass, getRowStyle, shouldShowLoadingIndicator } from "../Utilities/RowUtils"
10
10
 
11
11
  import LoadingInline from "../../pb_loading_inline/_loading_inline"
12
12
  import Checkbox from "../../pb_checkbox/_checkbox"
@@ -81,6 +81,7 @@ const TableCellRenderer = ({
81
81
 
82
82
  const paddingValue = colDef?.columnStyling?.cellPadding ?? customRowStyle?.cellPadding
83
83
  const paddingClass = paddingValue ? `p_${paddingValue}` : undefined
84
+ const fontWeight = getFontWeight(customRowStyle)
84
85
 
85
86
  return (
86
87
  <td
@@ -103,6 +104,7 @@ const TableCellRenderer = ({
103
104
  : undefined,
104
105
  backgroundColor: cellBackgroundColor || (i === 0 && customRowStyle?.backgroundColor),
105
106
  color: cellFontColor || customRowStyle?.fontColor,
107
+ fontWeight,
106
108
  }}
107
109
  >
108
110
  {collapsibleTrail && i === 0 && row.depth > 0 && renderCollapsibleTrail(row.depth)}
@@ -161,7 +163,7 @@ export const RegularTableView = ({
161
163
 
162
164
  // Row pinning
163
165
  function PinnedRow({ row }: { row: Row<any> }) {
164
- const customRowStyle = rowStyling?.length > 0 && rowStyling?.find((s: GenericObject) => s?.rowId === row.id);
166
+ const customRowStyle = getRowStyle(rowStyling, row);
165
167
  return (
166
168
  <tr
167
169
  className={classnames(
@@ -175,7 +177,8 @@ export const RegularTableView = ({
175
177
  row.getIsPinned() === 'top'
176
178
  ? `${row.getPinnedIndex() * rowHeight + headerHeight + actionBarHeight}px`
177
179
  : undefined,
178
- zIndex: '3'
180
+ zIndex: '3',
181
+ fontWeight: getFontWeight(customRowStyle),
179
182
  }}
180
183
  >
181
184
  <TableCellRenderer
@@ -205,7 +208,7 @@ export const RegularTableView = ({
205
208
  const isFirstChildofSubrow = row.depth > 0 && row.index === 0;
206
209
  const numberOfColumns = table.getAllFlatColumns().length;
207
210
  const isFirstRegularRow = rowIndex === 0 && !row.getIsPinned();
208
- const customRowStyle = rowStyling?.length > 0 && rowStyling?.find((s: GenericObject) => s?.rowId === row.id);
211
+ const customRowStyle = getRowStyle(rowStyling, row);
209
212
 
210
213
  // Use functions from RowUtils for consistent cell coloring
211
214
  const rowColor = getRowColorClass(row, inlineRowLoading || false);
@@ -228,7 +231,11 @@ export const RegularTableView = ({
228
231
  className={`${rowColor} ${row.depth > 0 ? `depth-sub-row-${row.depth}` : ""}`}
229
232
  id={`${row.index}-${row.id}-${row.depth}-row`}
230
233
  ref={isFirstRegularRow ? sampleRowRef : null}
231
- style={{backgroundColor: customRowStyle?.backgroundColor, color: customRowStyle?.fontColor}}
234
+ style={{
235
+ backgroundColor: customRowStyle?.backgroundColor,
236
+ color: customRowStyle?.fontColor,
237
+ fontWeight: getFontWeight(customRowStyle),
238
+ }}
232
239
  >
233
240
  {/* Render custom checkbox column when we want selectableRows for non-expanding tables */}
234
241
  {selectableRows && !hasAnySubRows && (
@@ -39,7 +39,7 @@ interface UseTableStateProps {
39
39
  tableOptions?: GenericObject;
40
40
  onRowSelectionChange?: (arg: RowSelectionState) => void;
41
41
  columnVisibilityControl?: GenericObject;
42
- rowStyling?: GenericObject;
42
+ rowStyling?: GenericObject[];
43
43
  inlineRowLoading?: boolean;
44
44
  sortParentOnly?: boolean;
45
45
  }
@@ -150,7 +150,7 @@ export function useTableState({
150
150
 
151
151
  return columnStructure;
152
152
  }) || [];
153
- }, [columnHelper, onRowToggleClick, selectableRows]);
153
+ }, [columnHelper, onRowToggleClick, rowStyling, selectableRows]);
154
154
 
155
155
  const columns = useMemo(() => buildColumns(columnDefinitions), [buildColumns, columnDefinitions]);
156
156
 
@@ -2,6 +2,7 @@ import React from "react";
2
2
  import { Row, Getter } from "@tanstack/react-table";
3
3
  import { GenericObject } from "../../types";
4
4
  import { CustomCell } from "../Components/CustomCell";
5
+ import { getRowStyle } from "./RowUtils";
5
6
 
6
7
  /**
7
8
  * Creates a cell render function for table columns
@@ -18,7 +19,7 @@ export const createCellFunction = (
18
19
  isFirstColumn?: boolean,
19
20
  onRowToggleClick?: (row: Row<GenericObject>) => void,
20
21
  selectableRows?: boolean,
21
- rowStyling?: GenericObject
22
+ rowStyling?: GenericObject[]
22
23
  ) => {
23
24
  // Add display name to the returned function
24
25
  const cellRenderer = ({
@@ -29,7 +30,7 @@ export const createCellFunction = (
29
30
  getValue: Getter<string>
30
31
  }) => {
31
32
  const rowData = row.original;
32
- const customStyle = rowStyling?.length > 0 && rowStyling?.find((s:GenericObject) => s?.rowId === row.id);
33
+ const customStyle = getRowStyle(rowStyling, row);
33
34
 
34
35
  if (isFirstColumn) {
35
36
  switch (row.depth) {
@@ -52,6 +53,7 @@ export const createCellFunction = (
52
53
  return accessorValue ? (
53
54
  <CustomCell
54
55
  customRenderer={customRenderer}
56
+ customStyle={customStyle}
55
57
  onRowToggleClick={onRowToggleClick}
56
58
  row={row}
57
59
  selectableRows={selectableRows}
@@ -36,6 +36,23 @@ export const shouldShowLoadingIndicator = (
36
36
  (row.depth < cellAccessorsLength);
37
37
  }
38
38
 
39
+ export const getRowStyle = (
40
+ rowStyling: GenericObject[] | undefined,
41
+ row: Row<GenericObject>
42
+ ) => {
43
+ const rowId = row.original?.id ?? row.id
44
+ if (rowId == null) return
45
+
46
+ return rowStyling?.find((style: GenericObject) => (
47
+ String(style?.rowId) === String(rowId)
48
+ ))
49
+ }
50
+
51
+ export const getFontWeight = (rowStyle?: GenericObject) => {
52
+ if (rowStyle?.fontWeight === "bold") return 700
53
+ if (rowStyle?.fontWeight === "regular") return 400
54
+ }
55
+
39
56
  /**
40
57
  * Creates a virtual item style object for virtualized rows
41
58
  */
@@ -1042,7 +1042,12 @@ test("rowStyling prop works as expected", () => {
1042
1042
  {
1043
1043
  rowId: "1",
1044
1044
  backgroundColor: colors.white,
1045
- fontColor: colors.black
1045
+ fontColor: colors.black,
1046
+ fontWeight: "bold",
1047
+ },
1048
+ {
1049
+ rowId: "2",
1050
+ fontWeight: "regular",
1046
1051
  },
1047
1052
  ];
1048
1053
 
@@ -1059,6 +1064,55 @@ test("rowStyling prop works as expected", () => {
1059
1064
  const tableBody = kit.querySelector('tbody')
1060
1065
  const row1 = tableBody.querySelector('tr:nth-child(1)')
1061
1066
  expect(row1).toHaveStyle({backgroundColor: colors.white, color: colors.black})
1067
+ expect(row1).toHaveStyle({fontWeight: "700"})
1068
+ const row2 = tableBody.querySelector('tr:nth-child(2)')
1069
+ expect(row2).toHaveStyle({fontWeight: "400"})
1070
+ })
1071
+
1072
+ test("rowStyling fontWeight applies to expandable rows", () => {
1073
+ const rowStyling = [
1074
+ {
1075
+ rowId: "1",
1076
+ fontWeight: "bold",
1077
+ },
1078
+ ];
1079
+
1080
+ const tableData = [
1081
+ {
1082
+ id: "1",
1083
+ year: "2021",
1084
+ quarter: null,
1085
+ month: null,
1086
+ day: null,
1087
+ newEnrollments: "20",
1088
+ scheduledMeetings: "10",
1089
+ children: [
1090
+ {
1091
+ id: "1-1",
1092
+ year: "2021",
1093
+ quarter: "Q1",
1094
+ month: null,
1095
+ day: null,
1096
+ newEnrollments: "2",
1097
+ scheduledMeetings: "35",
1098
+ },
1099
+ ],
1100
+ },
1101
+ ];
1102
+
1103
+ render(
1104
+ <AdvancedTable
1105
+ columnDefinitions={columnDefinitions}
1106
+ data={{ testid: testId }}
1107
+ rowStyling={rowStyling}
1108
+ tableData={tableData}
1109
+ />
1110
+ )
1111
+
1112
+ const kit = screen.getByTestId(testId)
1113
+ const tableBody = kit.querySelector('tbody')
1114
+ const expandableRow = tableBody.querySelector('tr:nth-child(1)')
1115
+ expect(expandableRow).toHaveStyle({fontWeight: "700"})
1062
1116
  })
1063
1117
 
1064
1118
  test("rowStyling prop to allow padding control", () => {
@@ -41,6 +41,10 @@
41
41
  font_color: "white",
42
42
  expand_button_color: "white",
43
43
  },
44
+ {
45
+ row_id: "15",
46
+ font_weight: "bold",
47
+ },
44
48
  ] %>
45
49
 
46
50
  <%= pb_rails("advanced_table", props: { id: "row-styling", table_data: @table_data_with_id, column_definitions: column_definitions, row_styling: row_styling }) %>
@@ -48,6 +48,10 @@ const rowStyling = [
48
48
  fontColor: colors.white,
49
49
  expandButtonColor: colors.white,
50
50
  },
51
+ {
52
+ rowId: "15",
53
+ fontWeight: "bold",
54
+ },
51
55
  ];
52
56
 
53
57
  return (
@@ -3,5 +3,6 @@ The `row_styling` prop can be used in conjunction with row ids to control certai
3
3
  - `background_color` : use this to control the background color of the row
4
4
  - `font_color`: use this to control font color for each row if needed, for example if using a darker background color.
5
5
  - `expand_button_color`: use this to control the color of the expand icon if needed, for example if using a darker background color.
6
+ - `font_weight`: use this to control row font weight. Accepted values are `regular` (default appearance) and `bold`.
6
7
 
7
8
  **NOTE:** 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.
@@ -3,5 +3,6 @@ The `rowStyling` prop can be used in conjunction with row ids to control certain
3
3
  - `backgroundColor` : use this to control the background color of the row
4
4
  - `fontColor`: use this to control font color for each row if needed, for example if using a darker background color.
5
5
  - `expandButtonColor`: use this to control the color of the expand icon if needed, for example if using a darker background color.
6
+ - `fontWeight`: use this to control row font weight. Accepted values are `regular` (default appearance) and `bold`.
6
7
 
7
8
  **NOTE:** Each object within the `tableData` Array must contain a unique id in order to attach an id to all Rows for this to function.
@@ -28,7 +28,8 @@
28
28
  "rowId": "1",
29
29
  "backgroundColor": "#0056CF",
30
30
  "fontColor": "#FFFFFF",
31
- "expandButtonColor": "#FFFFFF"
31
+ "expandButtonColor": "#FFFFFF",
32
+ "fontWeight": "bold"
32
33
  }
33
34
  ],
34
35
  "expandByDepth": [
@@ -104,7 +104,7 @@
104
104
  "tableProps": {
105
105
  "container": false
106
106
  },
107
- "rowStyling": [{ "rowId": "1", "backgroundColor": "#0056CF", "fontColor": "#FFFFFF", "expandButtonColor": "#FFFFFF" }],
107
+ "rowStyling": [{ "rowId": "1", "backgroundColor": "#0056CF", "fontColor": "#FFFFFF", "expandButtonColor": "#FFFFFF", "fontWeight": "bold" }],
108
108
  "expandByDepth": [
109
109
  {
110
110
  "depth": 0,
@@ -3,6 +3,7 @@
3
3
  button_color = row_style&.[](:expand_button_color)
4
4
  bg_color = row_style&.[](:background_color)
5
5
  font_color = row_style&.[](:font_color)
6
+ font_weight = row_style&.[](:font_weight)
6
7
  tr_options = (object.html_options || {}).stringify_keys
7
8
  tr_options["class"] = [tr_options["class"], object.classname].reject(&:blank?).join(" ")
8
9
  %>
@@ -14,7 +15,7 @@
14
15
  <% end %>
15
16
  <% object.column_definitions.each_with_index do |column, index| %>
16
17
  <% next unless column[:accessor].present? %>
17
- <% component_info = object.cell_component_info(column, index, bg_color, font_color) %>
18
+ <% component_info = object.cell_component_info(column, index, bg_color, font_color, font_weight) %>
18
19
  <%= pb_rails(component_info[:name], props: component_info[:props]) do %>
19
20
  <%= pb_rails("flex", props:{ align: "center", justify: object.justify_for(column, index), classname: object.loading ? "loading-cell" : "" }) do %>
20
21
  <% if collapsible_trail && index.zero? %>
@@ -107,9 +107,10 @@ module Playbook
107
107
  end
108
108
 
109
109
  # Uses a regular table/table_cell component if there is no custom background color; if there is a cell_background_color uses a background component with tag "td"
110
- def cell_component_info(column, index, bg_color, font_color)
110
+ def cell_component_info(column, index, bg_color, font_color, font_weight = nil)
111
111
  column_font_color = cell_font_color(column)
112
112
  effective_font_color = column_font_color || font_color
113
+ effective_font_weight = font_weight_value(font_weight)
113
114
 
114
115
  if has_custom_background_color?(column)
115
116
  custom_bg_color = cell_background_color(column)
@@ -119,11 +120,15 @@ module Playbook
119
120
  tag: "td",
120
121
  classname: td_classname(column, index),
121
122
  }
122
- component_props[:html_options] = { style: { color: effective_font_color } } if effective_font_color.present?
123
+ style_hash = {}
124
+ style_hash[:color] = effective_font_color if effective_font_color.present?
125
+ style_hash[:"font-weight"] = effective_font_weight if effective_font_weight.present?
126
+ component_props[:html_options] = { style: style_hash } if style_hash.present?
123
127
  else
124
128
  component_name = "table/table_cell"
125
129
  style_hash = { "background-color": bg_color }
126
130
  style_hash[:color] = effective_font_color if effective_font_color.present?
131
+ style_hash[:"font-weight"] = effective_font_weight if effective_font_weight.present?
127
132
  component_props = {
128
133
  html_options: {
129
134
  style: style_hash,
@@ -216,6 +221,15 @@ module Playbook
216
221
  end
217
222
  end
218
223
 
224
+ def font_weight_value(font_weight)
225
+ case font_weight.to_s
226
+ when "bold"
227
+ "700"
228
+ when "regular"
229
+ "400"
230
+ end
231
+ end
232
+
219
233
  private
220
234
 
221
235
  def custom_renderer_value(column, index)
@@ -15,7 +15,7 @@ module Playbook
15
15
  values: %w[xs sm md lg xl none rounded],
16
16
  default: "md"
17
17
  prop :background, type: Playbook::Props::Enum,
18
- values: %w[white light dark product_1_background product_1_highlight product_2_background product_2_highlight product_3_background product_3_highlight product_4_background product_4_highlight product_5_background product_5_highlight product_6_background product_6_highlight product_7_background product_7_highlight product_8_background product_8_highlight product_9_background product_9_highlight product_10_background product_10_highlight windows siding doors solar roofing gutters insulation none success_subtle warning_subtle error_subtle info_subtle neutral_subtle],
18
+ values: %w[white light dark product_1_background product_1_highlight product_2_background product_2_highlight product_3_background product_3_highlight product_4_background product_4_highlight product_5_background product_5_highlight product_6_background product_6_highlight product_7_background product_7_highlight product_8_background product_8_highlight product_9_background product_9_highlight product_10_background product_10_highlight product_11_background product_11_highlight windows siding doors solar roofing gutters insulation none success_subtle warning_subtle error_subtle info_subtle neutral_subtle],
19
19
  default: "none"
20
20
  prop :drag_id, type: Playbook::Props::String
21
21
  prop :draggable_item, type: Playbook::Props::Boolean,
@@ -37,6 +37,8 @@
37
37
  "product_9_highlight",
38
38
  "product_10_background",
39
39
  "product_10_highlight",
40
+ "product_11_background",
41
+ "product_11_highlight",
40
42
  "windows",
41
43
  "siding",
42
44
  "doors",
@@ -305,5 +305,12 @@
305
305
  "hiddenProps": [
306
306
  "isCollapsed",
307
307
  "onCollapse"
308
+ ],
309
+ "requiredCodeProps": [
310
+ "filters",
311
+ "results",
312
+ "sortOptions",
313
+ "sortValue",
314
+ "onSortChange"
308
315
  ]
309
316
  }
@@ -2,7 +2,7 @@
2
2
 
3
3
  <%= pb_rails("progress_simple", props: { percent: 0, id: "bar_breached" }) %>
4
4
 
5
- <%= pb_rails("caption", props: { size: 'xs', text: "hello", id: "caption_breached" }) %>
5
+ <%= pb_rails("caption", props: { size: 'xs', text: "", id: "caption_breached" }) %>
6
6
 
7
7
  <script>
8
8
  window.addEventListener("load", () => {
@@ -7,7 +7,7 @@
7
7
 
8
8
  <%= pb_rails("progress_simple", props: { percent: 0, id: "bar_common" }) %>
9
9
 
10
- <%= pb_rails("caption", props: { size: 'xs', text: "hello", id: "caption_common" }) %>
10
+ <%= pb_rails("caption", props: { size: 'xs', text: "", id: "caption_common" }) %>
11
11
 
12
12
 
13
13
  <script>
@@ -2,7 +2,7 @@
2
2
 
3
3
  <%= pb_rails("progress_simple", props: { percent: 0, id: "def_bar" }) %>
4
4
 
5
- <%= pb_rails("caption", props: { size: 'xs', text: "hello", id: "def_caption" }) %>
5
+ <%= pb_rails("caption", props: { size: 'xs', text: "", id: "def_caption" }) %>
6
6
 
7
7
  <%= pb_rails("text_input", props: { label: "Calculated Strength", value: "0", disabled: true, id: "calc_strength" }) %>
8
8
 
@@ -10,25 +10,25 @@
10
10
 
11
11
  <%= pb_rails("progress_simple", props: { percent: 0, id: "min_5_bar" }) %>
12
12
 
13
- <%= pb_rails("caption", props: { size: 'xs', text: "hello", id: "min_5_caption" }) %>
13
+ <%= pb_rails("caption", props: { size: 'xs', text: "", id: "min_5_caption" }) %>
14
14
 
15
15
  <%= pb_rails("passphrase", props: { label: "Min length = 30", classname: "min_30" }) %>
16
16
 
17
17
  <%= pb_rails("progress_simple", props: { percent: 0, id: "min_30_bar" }) %>
18
18
 
19
- <%= pb_rails("caption", props: { size: 'xs', text: "hello", id: "min_30_caption" }) %>
19
+ <%= pb_rails("caption", props: { size: 'xs', text: "", id: "min_30_caption" }) %>
20
20
 
21
21
  <%= pb_rails("passphrase", props: { label: "Average Threshold = 1", classname: "avg_1" }) %>
22
22
 
23
23
  <%= pb_rails("progress_simple", props: { percent: 0, id: "avg_1_bar" }) %>
24
24
 
25
- <%= pb_rails("caption", props: { size: 'xs', text: "hello", id: "avg_1_caption" }) %>
25
+ <%= pb_rails("caption", props: { size: 'xs', text: "", id: "avg_1_caption" }) %>
26
26
 
27
27
  <%= pb_rails("passphrase", props: { label: "Strong Threshold = 4", classname: "strong_4" }) %>
28
28
 
29
29
  <%= pb_rails("progress_simple", props: { percent: 0, id: "strong_4_bar" }) %>
30
30
 
31
- <%= pb_rails("caption", props: { size: 'xs', text: "hello", id: "strong_4_caption" }) %>
31
+ <%= pb_rails("caption", props: { size: 'xs', text: "", id: "strong_4_caption" }) %>
32
32
 
33
33
 
34
34
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  <%= pb_rails("progress_simple", props: { percent: 0, id: "bar_change" }) %>
4
4
 
5
- <%= pb_rails("caption", props: { size: 'xs', text: "hello", id: "caption_change" }) %>
5
+ <%= pb_rails("caption", props: { size: 'xs', text: "", id: "caption_change" }) %>
6
6
 
7
7
  <%= pb_rails("text_input", props: { label: "Passphrase Strength", value: "0", disabled: true, id: "calc_strength_change" }) %>
8
8
 
@@ -0,0 +1,58 @@
1
+ import PbEnhancedElement from '../pb_enhanced_element'
2
+
3
+ export default class PbPassphrase extends PbEnhancedElement {
4
+ static get selector() {
5
+ return '[data-pb-passphrase]'
6
+ }
7
+
8
+ toggle: HTMLElement | null
9
+ input: HTMLInputElement | null
10
+ visible: boolean
11
+
12
+ connect() {
13
+ this.toggle = this.element.querySelector('.show-passphrase-icon')
14
+ this.input = this.element.querySelector('.passphrase-text-input input')
15
+ this.visible = false
16
+
17
+ if (!this.toggle || !this.input) return
18
+
19
+ this.toggle.addEventListener('click', this.handleToggle)
20
+ this.toggle.addEventListener('keydown', this.handleKeydown)
21
+ }
22
+
23
+ disconnect() {
24
+ if (!this.toggle) return
25
+
26
+ this.toggle.removeEventListener('click', this.handleToggle)
27
+ this.toggle.removeEventListener('keydown', this.handleKeydown)
28
+ }
29
+
30
+ handleToggle = (event: Event) => {
31
+ event.preventDefault()
32
+ this.setVisible(!this.visible)
33
+ }
34
+
35
+ handleKeydown = (event: KeyboardEvent) => {
36
+ if (event.key !== 'Enter' && event.key !== ' ') return
37
+
38
+ event.preventDefault()
39
+ this.setVisible(!this.visible)
40
+ }
41
+
42
+ setVisible(visible: boolean) {
43
+ this.visible = visible
44
+ this.input.type = visible ? 'text' : 'password'
45
+ this.toggle.setAttribute('aria-pressed', String(visible))
46
+ this.toggle.setAttribute(
47
+ 'aria-label',
48
+ visible
49
+ ? 'Passphrase currently visible. Click icon to hide password'
50
+ : 'Passphrase currently hidden. Click icon to reveal password'
51
+ )
52
+
53
+ const icons = this.toggle.querySelectorAll('.passphrase-toggle-icon')
54
+ icons.forEach((iconWrapper, index) => {
55
+ iconWrapper.classList.toggle('hide-icon', visible ? index === 0 : index === 1)
56
+ })
57
+ }
58
+ }
@@ -84,6 +84,19 @@
84
84
  "react",
85
85
  "rails"
86
86
  ]
87
+ },
88
+ "required": {
89
+ "platforms": [
90
+ "rails"
91
+ ],
92
+ "type": "boolean",
93
+ "default": false
94
+ },
95
+ "minLength": {
96
+ "platforms": [
97
+ "rails"
98
+ ],
99
+ "type": "number"
87
100
  }
88
101
  },
89
102
  "globalProps": true,
@@ -1 +1,70 @@
1
- <%= react_component('Passphrase', object.passphrase_options, class: object.classname, **combined_html_options) %>
1
+ <%= pb_content_tag(:div) do %>
2
+ <label>
3
+ <%= pb_rails("flex", props: { align: "baseline", margin_bottom: show_label? ? "xs" : nil }.compact) do %>
4
+ <% if show_label? %>
5
+ <% if show_required_indicator? %>
6
+ <%= pb_rails("caption", props: { dark: object.dark, classname: "passphrase-label", color: "lighter" }) do %>
7
+ <%= object.display_label %> <span class="required_indicator">*</span>
8
+ <% end %>
9
+ <% else %>
10
+ <%= pb_rails("caption", props: {
11
+ dark: object.dark,
12
+ classname: "passphrase-label",
13
+ color: "lighter",
14
+ text: object.display_label,
15
+ }) %>
16
+ <% end %>
17
+ <% end %>
18
+
19
+ <% if object.show_tips? %>
20
+ <%= pb_rails("circle_icon_button", props: {
21
+ classname: object.tips_button_class,
22
+ dark: object.dark,
23
+ icon: "info-circle",
24
+ id: object.tips_trigger_id,
25
+ variant: "link",
26
+ }) %>
27
+ <%= pb_rails("popover", props: {
28
+ close_on_click: "outside",
29
+ position: "right",
30
+ trigger_element_id: object.tips_trigger_id,
31
+ tooltip_id: object.tips_tooltip_id,
32
+ }) do %>
33
+ <%= pb_rails("flex", props: { align: "center", orientation: "column" }) do %>
34
+ <%= pb_rails("caption", props: {
35
+ color: "lighter",
36
+ margin_bottom: "xs",
37
+ text: "Tips for a good passphrase",
38
+ }) %>
39
+ <div>
40
+ <% object.tips.each do |tip| %>
41
+ <%= pb_rails("flex", props: { align: "center", margin_bottom: "xs" }) do %>
42
+ <%= pb_rails("icon", props: { icon: "shield-check", margin_right: "xs" }) %>
43
+ <%= pb_rails("caption", props: { color: "lighter", size: "xs", text: tip }) %>
44
+ <% end %>
45
+ <% end %>
46
+ </div>
47
+ <% end %>
48
+ <% end %>
49
+ <% end %>
50
+ <% end %>
51
+
52
+ <div class="passphrase-text-input-wrapper">
53
+ <%= pb_rails("text_input", props: object.text_input_props) %>
54
+ <span
55
+ aria-label="Passphrase currently hidden. Click icon to reveal password"
56
+ aria-pressed="false"
57
+ class="show-passphrase-icon"
58
+ role="button"
59
+ tabindex="0"
60
+ >
61
+ <%= pb_rails("body", props: { classname: "passphrase-toggle-icon", color: "light", dark: object.dark }) do %>
62
+ <%= pb_rails("icon", props: { aria: { label: "eye icon" }, icon: "eye-slash" }) %>
63
+ <% end %>
64
+ <%= pb_rails("body", props: { classname: "passphrase-toggle-icon hide-icon", color: "light", dark: object.dark }) do %>
65
+ <%= pb_rails("icon", props: { aria: { label: "eye icon" }, icon: "eye" }) %>
66
+ <% end %>
67
+ </span>
68
+ </div>
69
+ </label>
70
+ <% end %>