playbook_ui 15.1.0.pre.alpha.PLAY2468phonenuminputvalidation10803 → 15.1.0.pre.alpha.PLAY2468phonenuminputvalidation10959

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1607dd2475fc082a109f3ad1d2dc03b07887fba69f23a5754d96020c18e75397
4
- data.tar.gz: 3b597c713dd113e61049aea67c57d0e30e2c33a8c144e2f0611cd053c3fa1406
3
+ metadata.gz: 88274c3c7e238de269c7284f4116558bf44b3379e2ec480295248bbba34490e5
4
+ data.tar.gz: 6dc03d8d35e76d6493b88311ba93ed16d417a2ff1f991e3b2d106cfecf29360d
5
5
  SHA512:
6
- metadata.gz: 89b69260b005e8a057fe6ada81c6c09706ad2dd938d1a1ea3403a5b8e36c5b50802f7c8976312429b14e2a9cc4c881d148f46e2567593f8a9db801d994a0c231
7
- data.tar.gz: 6121137545315510e02d3cda537276fb12b196e93cb3032542a6dd4c84a81ca612ecd181304d52710c2b8eaf07ce8238daf8f4cbdb64f9e39b257235178bd132
6
+ metadata.gz: 5d21c2bba88adf2f18453ba9d0941ac6957c66fbdd03d289a8f422643daac32a7ff21085f4001f51d0b2022c9d83f7296be95d9f1d0dcd1e32635fc00bd24d10
7
+ data.tar.gz: 88300ecf5f50c839a38a26ea039f078a1fb74953b2436469a24b87c267987b08bbf85210a2f191d9f49db4ac9e70a91657225c53a010c134d784bea3cd72e460
@@ -0,0 +1,31 @@
1
+ <%= pb_rails("body", props: { text: "Click to disable the Buttons below", id: "toggle-disabled-demo", cursor: "pointer", color:"link", margin_bottom:"sm" }) %>
2
+ <%= pb_rails("body", props: { text: "Click to enable the Buttons below", id: "toggle-enabled-demo", cursor: "pointer", color:"link", margin_bottom:"sm" }) %>
3
+
4
+ <%= pb_rails("card", props:{display:"flex", flex_direction:"row", justify_content:"center"}) do %>
5
+ <%= pb_rails("button", props: { text: "I am a Button", id: "normal_managed_button", data:{pb_button_managed: true}, margin_right: "lg" }) %>
6
+ <%= pb_rails("button", props: { text: "I am an <a> Button", id: "a_tag_managed_button", tag:"a", data:{pb_button_managed: true}, link: "http://google.com"}) %>
7
+ <% end %>
8
+ <script>
9
+ document.addEventListener('DOMContentLoaded', function () {
10
+ const disableTrigger = document.querySelector('#toggle-disabled-demo')
11
+ const enableTrigger = document.querySelector('#toggle-enabled-demo')
12
+
13
+ // Find the Buttons you want to 'manage'
14
+ const btn = document.querySelector('#normal_managed_button');
15
+ const link = document.querySelector('#a_tag_managed_button');
16
+
17
+ disableTrigger.addEventListener('click', (e) => {
18
+ // Disable default button
19
+ btn.setAttribute('disabled', true)
20
+ // Disable a tag button
21
+ link.setAttribute('aria-disabled', 'true')
22
+ });
23
+
24
+ enableTrigger.addEventListener('click', (e) => {
25
+ // Enable default button
26
+ btn.removeAttribute('disabled')
27
+ // Enable a tag button
28
+ link.removeAttribute('aria-disabled')
29
+ });
30
+ });
31
+ </script>
@@ -0,0 +1,7 @@
1
+ If needing to toggle the disabled state of the Button dynamically (for example, within a Turbo or Stimulus context), you can now do so in rails using the `pb-button-managed` data attribute.
2
+
3
+ 1) Add the following data attribute to your button kit: `data:{ pb-button-managed: true }`
4
+
5
+ 2) To toggle enabled/disabled state via attributes: for buttons set/remove disabled, for links set/remove aria-disabled="true". This will handle disabling the button, preventing clicks as well as all style changes so you don't have to.
6
+
7
+ Click to enable or disable the buttons above and view the code snippet below for details!
@@ -0,0 +1,21 @@
1
+ <%= pb_rails("body", props: { text: "Click to disable the Button below", id: "toggle-disabled-demo-with-helper", cursor: "pointer", color:"link", margin_bottom:"sm" }) %>
2
+ <%= pb_rails("body", props: { text: "Click to enable the Button below", id: "toggle-enabled-demo-with-helper", cursor: "pointer", color:"link", margin_bottom:"sm" }) %>
3
+ <br/>
4
+ <%= pb_rails("card", props:{display:"flex", flex_direction:"row", justify_content:"center"}) do %>
5
+ <%= pb_rails("button", props: { text: "Watch me Change!", id: "managed_button_with_helper", data:{pb_button_managed: true} }) %>
6
+ <% end %>
7
+
8
+ <script>
9
+ document.addEventListener('DOMContentLoaded', function () {
10
+ const disable = document.querySelector('#toggle-disabled-demo-with-helper')
11
+ const enable = document.querySelector('#toggle-enabled-demo-with-helper')
12
+
13
+ // Find the Button you want to 'manage'
14
+ const demoBtn = document.querySelector('#managed_button_with_helper')
15
+
16
+ // Use the pbButton object created by the kit to call the enable/disable methods
17
+ disable.addEventListener('click', (e) => {demoBtn._pbButton.disable()});
18
+ enable.addEventListener('click', (e) => {demoBtn._pbButton.enable()});
19
+
20
+ });
21
+ </script>
@@ -0,0 +1,7 @@
1
+ The disabled state for the button can also be toggled via small helpers available through the `pb-button-managed` data attribute.
2
+
3
+ 1) Add the following data attribute to your button kit: `data:{ pb-button-managed: true }`
4
+
5
+ 2) Toggle state via the provided `_pbButton.disable()` and `_pbButton.enable()` helpers as shown in the code snippet below.
6
+
7
+ Click to enable or disable the buttons above to see this in action!
@@ -11,6 +11,8 @@ examples:
11
11
  - button_options: Button Additional Options
12
12
  - button_size: Button Size
13
13
  - button_form: Button Form Attribute
14
+ - button_managed_disabled: Button Toggle Disabled State
15
+ - button_managed_disabled_helper: Button Toggle Disabled State Helper
14
16
 
15
17
  react:
16
18
  - button_default: Button Variants
@@ -0,0 +1,99 @@
1
+ import PbEnhancedElement from "../pb_enhanced_element"
2
+
3
+ const BUTTON_SELECTOR = "[data-pb-button-managed]"
4
+
5
+ export default class PbButton extends PbEnhancedElement {
6
+ static get selector() {
7
+ return BUTTON_SELECTOR
8
+ }
9
+
10
+ connect() {
11
+ this._attrManaged = this._attributesPresent()
12
+ this.element._pbButton = this
13
+
14
+ this._onClick = (e) => {
15
+ if (this.isDisabled()) {
16
+ e.preventDefault()
17
+ e.stopImmediatePropagation()
18
+ }
19
+ }
20
+ this.element.addEventListener("click", this._onClick, true)
21
+
22
+ if (this._attrManaged) this._syncClassesFromAttributes()
23
+
24
+ this._observer = new MutationObserver(() => {
25
+ this._attrManaged = true
26
+ this._syncClassesFromAttributes()
27
+ })
28
+ this._observer.observe(this.element, {
29
+ attributes: true,
30
+ attributeFilter: ["disabled", "aria-disabled"],
31
+ })
32
+ }
33
+
34
+ disconnect() {
35
+ this.element.removeEventListener("click", this._onClick, true)
36
+ this._observer?.disconnect()
37
+ delete this.element._pbButton
38
+ }
39
+
40
+ disable() { this.setDisabled(true) }
41
+ enable() { this.setDisabled(false) }
42
+
43
+ setDisabled(state) {
44
+ if (this._isButton()) {
45
+ state
46
+ ? this.element.setAttribute("disabled", "disabled")
47
+ : this.element.removeAttribute("disabled")
48
+ } else {
49
+ state
50
+ ? this.element.setAttribute("aria-disabled", "true")
51
+ : this.element.removeAttribute("aria-disabled")
52
+ }
53
+ this._attrManaged = true
54
+ this._applyClassState(state)
55
+ }
56
+
57
+ isDisabled() {
58
+ if (this._isButton()) {
59
+ if (this.element.hasAttribute("disabled")) return true
60
+ if (this._attrManaged && !this.element.hasAttribute("disabled")) return false
61
+ } else {
62
+ const aria = this.element.getAttribute("aria-disabled")
63
+ if (aria === "true") return true
64
+ if (this._attrManaged && aria !== "true") return false
65
+ }
66
+ return this.element.classList.contains("pb_button_disabled")
67
+ }
68
+
69
+ _isButton() {
70
+ return this.element.tagName === "BUTTON"
71
+ }
72
+
73
+ _attributesPresent() {
74
+ return this.element.hasAttribute("disabled") || this.element.hasAttribute("aria-disabled")
75
+ }
76
+
77
+ _syncClassesFromAttributes() {
78
+ const state = this._attrDisabledState()
79
+ const disabled = (state === null) ? false : state
80
+ this._applyClassState(disabled)
81
+ }
82
+
83
+ _attrDisabledState() {
84
+ if (this._isButton()) {
85
+ return this.element.hasAttribute("disabled") ? true : null
86
+ } else {
87
+ const aria = this.element.getAttribute("aria-disabled")
88
+ if (aria === "true") return true
89
+ if (aria === "false") return false
90
+ return this.element.hasAttribute("aria-disabled") ? false : null
91
+ }
92
+ }
93
+
94
+ _applyClassState(disabled) {
95
+ this.element.classList.toggle("pb_button_disabled", !!disabled)
96
+ this.element.classList.toggle("pb_button_enabled", !disabled)
97
+ }
98
+ }
99
+
@@ -4,7 +4,6 @@ import { debounce } from '../utilities/object'
4
4
  // Kit selectors
5
5
  const KIT_SELECTOR = '[class^="pb_"][class*="_kit"]'
6
6
  const ERROR_MESSAGE_SELECTOR = '.pb_body_kit_negative'
7
- const PHONE_NUMBER_INPUT_SELECTOR = '.pb_phone_number_input'
8
7
 
9
8
  // Validation selectors
10
9
  const FORM_SELECTOR = 'form[data-pb-form-validation="true"]'
@@ -24,6 +23,10 @@ class PbFormValidation extends PbEnhancedElement {
24
23
 
25
24
  connect() {
26
25
  this.formValidationFields.forEach((field) => {
26
+ // Skip phone number inputs - they handle their own validation
27
+ const isPhoneNumberInput = field.closest('.pb_phone_number_input')
28
+ if (isPhoneNumberInput) return
29
+
27
30
  FIELD_EVENTS.forEach((e) => {
28
31
  field.addEventListener(e, debounce((event) => {
29
32
  this.validateFormField(event)
@@ -57,41 +60,30 @@ class PbFormValidation extends PbEnhancedElement {
57
60
  const { parentElement } = target
58
61
  const kitElement = parentElement.closest(KIT_SELECTOR)
59
62
 
60
- // Skip error message container for Phone Number Input as it handles its own errors
61
- // as the closest kitElement is "pb_text_input_kit mb_sm" for Phone Number Input,
62
- // we target the parent element of kitElement to check
63
- if (kitElement && kitElement.parentElement.matches(PHONE_NUMBER_INPUT_SELECTOR)) {
64
- return
65
- }
63
+ // Check if this is a phone number input
64
+ const isPhoneNumberInput = kitElement && kitElement.classList.contains('pb_phone_number_input')
66
65
 
67
66
  // ensure clean error message state
68
67
  this.clearError(target)
69
68
  kitElement.classList.add('error')
70
69
 
71
- // set the error message element
72
- const errorMessageContainer = this.errorMessageContainer
73
-
74
- if (target.dataset.message) target.setCustomValidity(target.dataset.message)
70
+ // Only add error message if it's NOT a phone number input
71
+ if (!isPhoneNumberInput) {
72
+ // set the error message element
73
+ const errorMessageContainer = this.errorMessageContainer
74
+ if (target.dataset.message) target.setCustomValidity(target.dataset.message)
75
+ errorMessageContainer.innerHTML = target.validationMessage
75
76
 
76
- errorMessageContainer.innerHTML = target.validationMessage
77
-
78
- // add the error message element to the dom tree
79
- parentElement.appendChild(errorMessageContainer)
77
+ // add the error message element to the dom tree
78
+ parentElement.appendChild(errorMessageContainer)
79
+ }
80
80
  }
81
81
 
82
82
  clearError(target) {
83
83
  const { parentElement } = target
84
- const kitElement = parentElement.closest(KIT_SELECTOR)
85
-
86
- if (kitElement) {
87
- kitElement.classList.remove('error')
88
-
89
- // Only remove error message container for non-Phone Number Input kits
90
- if (!kitElement.matches(PHONE_NUMBER_INPUT_SELECTOR)) {
91
- const errorMessageContainer = parentElement.querySelector(ERROR_MESSAGE_SELECTOR)
92
- if (errorMessageContainer) errorMessageContainer.remove()
93
- }
94
- }
84
+ parentElement.closest(KIT_SELECTOR).classList.remove('error')
85
+ const errorMessageContainer = parentElement.querySelector(ERROR_MESSAGE_SELECTOR)
86
+ if (errorMessageContainer) errorMessageContainer.remove()
95
87
  }
96
88
 
97
89
  // Check if there are phone number input errors
@@ -110,12 +110,13 @@ const PhoneNumberInput = (props: PhoneNumberInputProps, ref?: React.Ref<unknown>
110
110
 
111
111
  const inputRef = useRef<HTMLInputElement | null>(null)
112
112
  const itiRef = useRef<any>(null);
113
- const wrapperRef = useRef<HTMLDivElement | null>(null); // Add wrapper ref
113
+ const wrapperRef = useRef<HTMLDivElement | null>(null);
114
114
  const [inputValue, setInputValue] = useState(value)
115
- const [error, setError] = useState(props.error)
115
+ const [error, setError] = useState("")
116
116
  const [dropDownIsOpen, setDropDownIsOpen] = useState(false)
117
117
  const [selectedData, setSelectedData] = useState()
118
118
  const [hasTyped, setHasTyped] = useState(false)
119
+ const [formSubmitted, setFormSubmitted] = useState(false)
119
120
 
120
121
  // Function to update validation state on the wrapper element
121
122
  // Only applies when input is required
@@ -129,8 +130,13 @@ const PhoneNumberInput = (props: PhoneNumberInputProps, ref?: React.Ref<unknown>
129
130
  }
130
131
  }
131
132
 
133
+ // Determine which error to display
134
+ // Show internal errors on blur (hasTyped) or on form submission (formSubmitted)
135
+ const shouldShowInternalError = (hasTyped || formSubmitted) && required && error
136
+ const displayError = props.error || (shouldShowInternalError ? error : "")
137
+
132
138
  useEffect(() => {
133
- const hasError = (error ?? '').length > 0
139
+ const hasError = error.length > 0
134
140
  if (hasError) {
135
141
  onValidate(false)
136
142
  } else {
@@ -141,28 +147,6 @@ const PhoneNumberInput = (props: PhoneNumberInputProps, ref?: React.Ref<unknown>
141
147
  updateValidationState(hasError)
142
148
  }, [error, onValidate])
143
149
 
144
- /*
145
- useImperativeHandle exposes the kit's input element to a parent component via a ref.
146
- See the Playbook docs for use cases.
147
- Read: https://react.dev/reference/react/useImperativeHandle
148
- */
149
- useImperativeHandle(ref, () => {
150
- return {
151
- clearField() {
152
- setInputValue("")
153
- setError("")
154
- setHasTyped(false)
155
- // Only clear validation state if field was required
156
- if (required) {
157
- updateValidationState(false)
158
- }
159
- },
160
- inputNode() {
161
- return inputRef.current
162
- }
163
- }
164
- })
165
-
166
150
  const unformatNumber = (formattedNumber: any) => {
167
151
  return formattedNumber.replace(/\D/g, "")
168
152
  }
@@ -234,7 +218,7 @@ const PhoneNumberInput = (props: PhoneNumberInputProps, ref?: React.Ref<unknown>
234
218
 
235
219
  const validateRepeatCountryCode = (itiInit: any) => {
236
220
  if (!itiInit) return
237
- const countryDialCode = itiInit.getSelectedCountryData().dialCode;
221
+ const countryDialCode = itiRef.current.getSelectedCountryData().dialCode;
238
222
  if (unformatNumber(inputValue).startsWith(countryDialCode)) {
239
223
  return showFormattedError('repeat country code')
240
224
  }
@@ -260,8 +244,7 @@ const PhoneNumberInput = (props: PhoneNumberInputProps, ref?: React.Ref<unknown>
260
244
  return
261
245
  }
262
246
 
263
- if (!hasTyped && !error) return
264
-
247
+ // Run validation checks
265
248
  if (itiRef.current) isValid(itiRef.current.isValidNumber())
266
249
  if (validateOnlyNumbers(itiRef.current)) return
267
250
  if (validateTooLongNumber(itiRef.current)) return
@@ -271,6 +254,89 @@ const PhoneNumberInput = (props: PhoneNumberInputProps, ref?: React.Ref<unknown>
271
254
  if (validateRepeatCountryCode(itiRef.current)) return
272
255
  }
273
256
 
257
+ // Add listener for form validation to track when validation should be shown
258
+ useEffect(() => {
259
+ const handleInvalid = (event: Event) => {
260
+ const target = event.target as HTMLInputElement
261
+ const phoneNumberContainer = target.closest('.pb_phone_number_input')
262
+
263
+ if (phoneNumberContainer && phoneNumberContainer === wrapperRef.current) {
264
+ const invalidInputName = target.name || target.getAttribute('name')
265
+ if (invalidInputName === name) {
266
+ setFormSubmitted(true)
267
+ // Trigger validation when form is submitted
268
+ validateErrors()
269
+ }
270
+ }
271
+ }
272
+
273
+ document.addEventListener('invalid', handleInvalid, true)
274
+
275
+ return () => {
276
+ document.removeEventListener('invalid', handleInvalid, true)
277
+ }
278
+ }, [name, inputValue])
279
+
280
+ /*
281
+ useImperativeHandle exposes the kit's input element to a parent component via a ref.
282
+ See the Playbook docs for use cases.
283
+ Read: https://react.dev/reference/react/useImperativeHandle
284
+ */
285
+ useImperativeHandle(ref, () => {
286
+ return {
287
+ clearField() {
288
+ setInputValue("")
289
+ setError("")
290
+ setHasTyped(false)
291
+ setFormSubmitted(false)
292
+ // Only clear validation state if field was required
293
+ if (required) {
294
+ updateValidationState(false)
295
+ }
296
+ },
297
+ inputNode() {
298
+ return inputRef.current
299
+ },
300
+ // Expose validation method for React Hook Form
301
+ validate() {
302
+ // Run validation and return error message or true
303
+ const isEmpty = !inputValue || inputValue.trim() === ''
304
+
305
+ if (required && isEmpty) {
306
+ return 'Missing phone number'
307
+ }
308
+
309
+ if (isEmpty) {
310
+ return true
311
+ }
312
+
313
+ if (!itiRef.current) {
314
+ return true
315
+ }
316
+
317
+ // Check if valid number
318
+ if (!itiRef.current.isValidNumber()) {
319
+ const countryName = itiRef.current.getSelectedCountryData().name
320
+ const validationError = itiRef.current.getValidationError()
321
+
322
+ if (validationError === ValidationError.TooShort) {
323
+ return `Invalid ${countryName} phone number (too short)`
324
+ } else if (validationError === ValidationError.TooLong) {
325
+ return `Invalid ${countryName} phone number (too long)`
326
+ } else if (validationError === ValidationError.MissingAreaCode) {
327
+ return `Invalid ${countryName} phone number (missing area code)`
328
+ } else if (!containOnlyNumbers(inputValue)) {
329
+ return `Invalid ${countryName} phone number (enter numbers only)`
330
+ } else {
331
+ return `Invalid ${countryName} phone number`
332
+ }
333
+ }
334
+
335
+ return true
336
+ }
337
+ }
338
+ })
339
+
274
340
  const getCurrentSelectedData = (itiInit: any, inputValue: string) => {
275
341
  return { ...itiInit.getSelectedCountryData(), number: inputValue }
276
342
  }
@@ -278,6 +344,12 @@ const PhoneNumberInput = (props: PhoneNumberInputProps, ref?: React.Ref<unknown>
278
344
  const handleOnChange = (evt: React.ChangeEvent<HTMLInputElement>) => {
279
345
  if (!hasTyped) setHasTyped(true)
280
346
  setInputValue(evt.target.value)
347
+
348
+ // Reset form submitted state when user types
349
+ if (formSubmitted) {
350
+ setFormSubmitted(false)
351
+ }
352
+
281
353
  let phoneNumberData
282
354
  if (formatAsYouType) {
283
355
  const formattedPhoneNumberData = getCurrentSelectedData(itiRef.current, evt.target.value)
@@ -286,8 +358,28 @@ const PhoneNumberInput = (props: PhoneNumberInputProps, ref?: React.Ref<unknown>
286
358
  phoneNumberData = getCurrentSelectedData(itiRef.current, evt.target.value)
287
359
  }
288
360
  setSelectedData(phoneNumberData)
289
- onChange(phoneNumberData)
361
+
362
+ // Check if this is React Hook Form by checking if onChange expects target format
363
+ const isReactHookForm = onChange.toString().includes("target")
364
+ if (isReactHookForm) {
365
+ // For React Hook Form, pass the event with modified target value
366
+ onChange({
367
+ ...evt,
368
+ target: {
369
+ ...evt.target,
370
+ name,
371
+ value: phoneNumberData
372
+ }
373
+ } as any)
374
+ } else {
375
+ onChange(phoneNumberData)
376
+ }
377
+
290
378
  isValid(itiRef.current.isValidNumber())
379
+
380
+ // Trigger validation after onChange for React Hook Form
381
+ // This ensures validation state is up-to-date
382
+ setTimeout(() => validateErrors(), 0)
291
383
  }
292
384
 
293
385
  // Separating Concerns as React Docs Recommend
@@ -346,7 +438,7 @@ const PhoneNumberInput = (props: PhoneNumberInputProps, ref?: React.Ref<unknown>
346
438
  dark,
347
439
  "data-phone-number": JSON.stringify(selectedData),
348
440
  disabled,
349
- error,
441
+ error: displayError,
350
442
  type: 'tel',
351
443
  id,
352
444
  label,
@@ -358,7 +450,7 @@ const PhoneNumberInput = (props: PhoneNumberInputProps, ref?: React.Ref<unknown>
358
450
 
359
451
  let wrapperProps: Record<string, unknown> = {
360
452
  className: classes,
361
- ref: wrapperRef // Add ref to wrapper
453
+ ref: wrapperRef
362
454
  }
363
455
 
364
456
  if (!isEmpty(aria)) textInputProps = {...textInputProps, ...ariaProps}
@@ -1 +1 @@
1
- import{jsx,Fragment,jsxs}from"react/jsx-runtime";import{useState,useEffect}from"react";import{d as buildAriaProps,e as buildDataProps,f as buildHtmlProps,H as HighchartsReact,g as Highcharts,h as classnames,i as globalProps,j as HighchartsMore,S as SolidGauge,k as buildCss}from"./_typeahead-DkRYiut7.js";import{c as colors,h as highchartsTheme,m as merge,a as highchartsDarkTheme,t as typography}from"./lib-QZuu1ltS.js";const mapColors=array=>{const regex=/(data)\-[1-8]/;const newArray=array.map((item=>regex.test(item)?`${colors[`data_${item[item.length-1]}`]}`:item));return newArray};const BarGraph=({aria:aria={},data:data={},align:align="center",axisTitle:axisTitle,dark:dark=false,chartData:chartData,className:className="pb_bar_graph",colors:colors2,htmlOptions:htmlOptions={},customOptions:customOptions={},axisFormat:axisFormat,id:id,pointStart:pointStart,stacking:stacking,subTitle:subTitle,type:type="column",title:title="Title",xAxisCategories:xAxisCategories,yAxisMin:yAxisMin,yAxisMax:yAxisMax,legend:legend=false,toggleLegendClick:toggleLegendClick=true,height:height,layout:layout="horizontal",verticalAlign:verticalAlign="bottom",x:x=0,y:y=0,...props})=>{const ariaProps=buildAriaProps(aria);const dataProps=buildDataProps(data);const htmlProps=buildHtmlProps(htmlOptions);const setupTheme=()=>{dark?Highcharts.setOptions(highchartsDarkTheme):Highcharts.setOptions(highchartsTheme)};setupTheme();const staticOptions={title:{text:title},chart:{height:height,type:type},subtitle:{text:subTitle},yAxis:[{labels:{format:typeof axisFormat==="string"?axisFormat:axisFormat&&axisFormat[0]?axisFormat[0].format:""},min:yAxisMin,max:yAxisMax,opposite:false,title:{text:Array.isArray(axisTitle)?axisTitle.length>0?axisTitle[0].name:null:axisTitle},plotLines:typeof yAxisMin!=="undefined"&&yAxisMin!==null?[]:[{value:0,zIndex:10,color:"#E4E8F0"}]}],xAxis:{categories:xAxisCategories},legend:{enabled:legend,align:align,verticalAlign:verticalAlign,layout:layout,x:x,y:y},colors:colors2!==void 0&&colors2.length>0?mapColors(colors2):highchartsTheme.colors,plotOptions:{series:{stacking:stacking,pointStart:pointStart,borderWidth:stacking?0:"",events:{},dataLabels:{enabled:false}}},series:chartData,credits:false};if(Array.isArray(axisTitle)&&axisTitle.length>1&&axisTitle[1].name){staticOptions.yAxis.push({labels:{format:typeof axisFormat==="string"?axisFormat:axisFormat[1].format},min:yAxisMin,max:yAxisMax,opposite:true,title:{text:axisTitle[1].name},plotLines:typeof yAxisMin!=="undefined"&&yAxisMin!==null?[]:[{value:0,zIndex:10,color:"#E4E8F0"}]})}if(!toggleLegendClick){staticOptions.plotOptions.series.events={legendItemClick:()=>false}}const filteredProps={...props};delete filteredProps.verticalAlign;const[options,setOptions]=useState({});useEffect((()=>{setOptions(merge(staticOptions,customOptions))}),[chartData]);return jsx(HighchartsReact,{containerProps:{className:classnames(globalProps(filteredProps),className),id:id,...ariaProps,...dataProps,...htmlProps},highcharts:Highcharts,options:options})};const alignBlockElement=event=>{const itemToMove=document.querySelector(`#wrapper-circle-chart-${event.target.renderTo.id} .pb-circle-chart-block`);const chartContainer=document.querySelector(`#${event.target.renderTo.id}`);if(itemToMove!==null&&chartContainer!==null){itemToMove.style.height=`${event.target.chartHeight}px`;itemToMove.style.width=`${event.target.chartWidth}px`;if(chartContainer.firstChild!==null){chartContainer.firstChild.before(itemToMove)}}};const CircleChart=({align:align="center",aria:aria={},rounded:rounded=false,borderColor:borderColor=(rounded?null:""),borderWidth:borderWidth=(rounded?20:null),chartData:chartData,children:children,className:className,colors:colors2=[],customOptions:customOptions={},dark:dark=false,data:data={},dataLabelHtml:dataLabelHtml="<div>{point.name}</div>",dataLabels:dataLabels=false,height:height,htmlOptions:htmlOptions={},id:id,innerSize:innerSize="md",legend:legend=false,maxPointSize:maxPointSize=null,minPointSize:minPointSize=null,startAngle:startAngle=null,style:style="pie",title:title,tooltipHtml:tooltipHtml,useHtml:useHtml=false,zMin:zMin=null,layout:layout="horizontal",verticalAlign:verticalAlign="bottom",x:x=0,y:y=0,...props})=>{const ariaProps=buildAriaProps(aria);const dataProps=buildDataProps(data);const htmlProps=buildHtmlProps(htmlOptions);HighchartsMore(Highcharts);const setupTheme=()=>{dark?Highcharts.setOptions(highchartsDarkTheme):Highcharts.setOptions(highchartsTheme)};setupTheme();Highcharts.setOptions({tooltip:{headerFormat:null,pointFormat:tooltipHtml?tooltipHtml:'<span style="font-weight: bold; color:{point.color};">●</span>{point.name}: <b>{point.y}</b>',useHTML:useHtml}});const innerSizes={sm:"35%",md:"50%",lg:"85%",none:"0%"};const innerSizeFormat=size=>innerSizes[size];const filteredProps={...props};delete filteredProps.verticalAlign;const[options,setOptions]=useState({});useEffect((()=>{const formattedChartData=chartData.map((obj=>{obj.y=obj.value;delete obj.value;return obj}));const staticOptions={title:{text:title},chart:{height:height,type:style,events:{render:event=>alignBlockElement(event),redraw:event=>alignBlockElement(event)}},legend:{align:align,verticalAlign:verticalAlign,layout:layout,x:x,y:y},plotOptions:{pie:{colors:colors2.length>0?mapColors(colors2):highchartsTheme.colors,dataLabels:{enabled:dataLabels,connectorShape:"straight",connectorWidth:3,format:dataLabelHtml},showInLegend:legend}},series:[{minPointSize:minPointSize,maxPointSize:maxPointSize,innerSize:borderWidth==20?"100%":innerSizeFormat(innerSize),data:formattedChartData,zMin:zMin,startAngle:startAngle,borderWidth:borderWidth,borderColor:borderColor}],credits:false};setOptions(merge(staticOptions,customOptions))}),[chartData]);return jsx(Fragment,{children:children?jsxs("div",{id:`wrapper-circle-chart-${id}`,children:[jsx(HighchartsReact,{containerProps:{className:classnames("pb_circle_chart",globalProps(filteredProps)),id:id,...ariaProps,...dataProps,...htmlProps},highcharts:Highcharts,options:options}),jsx("div",{className:"pb-circle-chart-block",children:children})]}):jsx(HighchartsReact,{containerProps:{className:classnames("pb_circle_chart",globalProps(filteredProps)),id:id,...ariaProps,...dataProps,...htmlProps},highcharts:Highcharts,options:options})})};const Gauge=({aria:aria={},chartData:chartData,customOptions:customOptions={},dark:dark=false,data:data={},disableAnimation:disableAnimation=false,fullCircle:fullCircle=false,height:height=null,htmlOptions:htmlOptions={},id:id,max:max=100,min:min=0,prefix:prefix="",showLabels:showLabels=false,style:style="solidgauge",suffix:suffix="",title:title="",tooltipHtml:tooltipHtml='<span style="font-weight: bold; color:{point.color};">●</span>{point.name}: <b>{point.y}</b>',colors:colors$1=[],minorTickInterval:minorTickInterval=null,circumference:circumference=(fullCircle?[0,360]:[-100,100]),...props})=>{const ariaProps=buildAriaProps(aria);const dataProps=buildDataProps(data);const htmlProps=buildHtmlProps(htmlOptions);HighchartsMore(Highcharts);SolidGauge(Highcharts);const setupTheme=()=>{dark?Highcharts.setOptions(highchartsDarkTheme):Highcharts.setOptions(highchartsTheme)};setupTheme();Highcharts.setOptions({tooltip:{pointFormat:tooltipHtml,followPointer:true}});const css=buildCss({pb_gauge_kit:true});const[options,setOptions]=useState({});useEffect((()=>{const formattedChartData=chartData.map((obj=>{obj.y=obj.value;delete obj.value;return obj}));const staticOptions={chart:{events:{load(){setTimeout(this.reflow.bind(this),0)}},type:style,height:height},title:{text:title},yAxis:{min:min,max:max,lineWidth:0,tickWidth:0,minorTickInterval:minorTickInterval,tickAmount:2,tickPositions:[min,max],labels:{y:26,enabled:showLabels}},credits:false,series:[{data:formattedChartData}],pane:{center:["50%","50%"],size:"90%",startAngle:circumference[0],endAngle:circumference[1],background:{borderWidth:20,innerRadius:"90%",outerRadius:"90%",shape:"arc",className:"gauge-pane"}},colors:colors$1!==void 0&&colors$1.length>0?mapColors(colors$1):highchartsTheme.colors,plotOptions:{series:{animation:!disableAnimation},solidgauge:{borderColor:colors$1!==void 0&&colors$1.length===1?mapColors(colors$1).join():highchartsTheme.colors[0],borderWidth:20,radius:90,innerRadius:"90%",dataLabels:{borderWidth:0,color:colors.text_lt_default,enabled:true,format:`<span class="prefix${dark?" dark":""}">${prefix}</span><span class="fix${dark?" dark":""}">{y:,f}</span><span class="suffix${dark?" dark":""}">${suffix}</span>`,style:{fontFamily:typography.font_family_base,fontWeight:typography.regular,fontSize:typography.heading_2},y:-26}}}};setOptions(merge(staticOptions,customOptions));if(document.querySelector(".prefix")){document.querySelectorAll(".prefix").forEach((prefix2=>{prefix2.setAttribute("y","28")}));document.querySelectorAll(".fix").forEach((fix=>fix.setAttribute("y","38")))}}),[chartData]);return jsx(HighchartsReact,{containerProps:{className:classnames(css,globalProps(props)),id:id,...ariaProps,...dataProps,...htmlProps},highcharts:Highcharts,options:options})};const LineGraph=({aria:aria={},data:data={},align:align="center",className:className="pb_bar_graph",customOptions:customOptions={},dark:dark=false,gradient:gradient=false,type:type="line",htmlOptions:htmlOptions={},id:id,legend:legend=false,toggleLegendClick:toggleLegendClick=true,layout:layout="horizontal",verticalAlign:verticalAlign="bottom",x:x=0,y:y=0,axisTitle:axisTitle,xAxisCategories:xAxisCategories,yAxisMin:yAxisMin,yAxisMax:yAxisMax,chartData:chartData,pointStart:pointStart,subTitle:subTitle,title:title,height:height,colors:colors2=[],...props})=>{const ariaProps=buildAriaProps(aria);const dataProps=buildDataProps(data);const htmlProps=buildHtmlProps(htmlOptions);const setupTheme=()=>{dark?Highcharts.setOptions(highchartsDarkTheme):Highcharts.setOptions(highchartsTheme)};setupTheme();const staticOptions={title:{text:title},chart:{height:height,type:type},subtitle:{text:subTitle},yAxis:{min:yAxisMin,max:yAxisMax,title:{text:axisTitle}},xAxis:{categories:xAxisCategories},legend:{enabled:legend,align:align,verticalAlign:verticalAlign,layout:layout,x:x,y:y},colors:colors2!==void 0&&colors2.length>0?mapColors(colors2):highchartsTheme.colors,plotOptions:{series:{pointStart:pointStart,events:{},dataLabels:{enabled:false}}},series:chartData,credits:false};if(!toggleLegendClick){staticOptions.plotOptions.series.events={legendItemClick:()=>false}}const filteredProps={...props};delete filteredProps.verticalAlign;const[options,setOptions]=useState({});useEffect((()=>{setOptions(merge(staticOptions,customOptions))}),[chartData]);return jsx(HighchartsReact,{containerProps:{className:classnames(globalProps(filteredProps),className),id:id,...ariaProps,...dataProps,...htmlProps},highcharts:Highcharts,options:options})};export{BarGraph as B,CircleChart as C,Gauge as G,LineGraph as L};
1
+ import{jsx,Fragment,jsxs}from"react/jsx-runtime";import{useState,useEffect}from"react";import{d as buildAriaProps,e as buildDataProps,f as buildHtmlProps,H as HighchartsReact,g as Highcharts,h as classnames,i as globalProps,j as HighchartsMore,S as SolidGauge,k as buildCss}from"./_typeahead-8Buo6A1G.js";import{c as colors,h as highchartsTheme,m as merge,a as highchartsDarkTheme,t as typography}from"./lib-QZuu1ltS.js";const mapColors=array=>{const regex=/(data)\-[1-8]/;const newArray=array.map((item=>regex.test(item)?`${colors[`data_${item[item.length-1]}`]}`:item));return newArray};const BarGraph=({aria:aria={},data:data={},align:align="center",axisTitle:axisTitle,dark:dark=false,chartData:chartData,className:className="pb_bar_graph",colors:colors2,htmlOptions:htmlOptions={},customOptions:customOptions={},axisFormat:axisFormat,id:id,pointStart:pointStart,stacking:stacking,subTitle:subTitle,type:type="column",title:title="Title",xAxisCategories:xAxisCategories,yAxisMin:yAxisMin,yAxisMax:yAxisMax,legend:legend=false,toggleLegendClick:toggleLegendClick=true,height:height,layout:layout="horizontal",verticalAlign:verticalAlign="bottom",x:x=0,y:y=0,...props})=>{const ariaProps=buildAriaProps(aria);const dataProps=buildDataProps(data);const htmlProps=buildHtmlProps(htmlOptions);const setupTheme=()=>{dark?Highcharts.setOptions(highchartsDarkTheme):Highcharts.setOptions(highchartsTheme)};setupTheme();const staticOptions={title:{text:title},chart:{height:height,type:type},subtitle:{text:subTitle},yAxis:[{labels:{format:typeof axisFormat==="string"?axisFormat:axisFormat&&axisFormat[0]?axisFormat[0].format:""},min:yAxisMin,max:yAxisMax,opposite:false,title:{text:Array.isArray(axisTitle)?axisTitle.length>0?axisTitle[0].name:null:axisTitle},plotLines:typeof yAxisMin!=="undefined"&&yAxisMin!==null?[]:[{value:0,zIndex:10,color:"#E4E8F0"}]}],xAxis:{categories:xAxisCategories},legend:{enabled:legend,align:align,verticalAlign:verticalAlign,layout:layout,x:x,y:y},colors:colors2!==void 0&&colors2.length>0?mapColors(colors2):highchartsTheme.colors,plotOptions:{series:{stacking:stacking,pointStart:pointStart,borderWidth:stacking?0:"",events:{},dataLabels:{enabled:false}}},series:chartData,credits:false};if(Array.isArray(axisTitle)&&axisTitle.length>1&&axisTitle[1].name){staticOptions.yAxis.push({labels:{format:typeof axisFormat==="string"?axisFormat:axisFormat[1].format},min:yAxisMin,max:yAxisMax,opposite:true,title:{text:axisTitle[1].name},plotLines:typeof yAxisMin!=="undefined"&&yAxisMin!==null?[]:[{value:0,zIndex:10,color:"#E4E8F0"}]})}if(!toggleLegendClick){staticOptions.plotOptions.series.events={legendItemClick:()=>false}}const filteredProps={...props};delete filteredProps.verticalAlign;const[options,setOptions]=useState({});useEffect((()=>{setOptions(merge(staticOptions,customOptions))}),[chartData]);return jsx(HighchartsReact,{containerProps:{className:classnames(globalProps(filteredProps),className),id:id,...ariaProps,...dataProps,...htmlProps},highcharts:Highcharts,options:options})};const alignBlockElement=event=>{const itemToMove=document.querySelector(`#wrapper-circle-chart-${event.target.renderTo.id} .pb-circle-chart-block`);const chartContainer=document.querySelector(`#${event.target.renderTo.id}`);if(itemToMove!==null&&chartContainer!==null){itemToMove.style.height=`${event.target.chartHeight}px`;itemToMove.style.width=`${event.target.chartWidth}px`;if(chartContainer.firstChild!==null){chartContainer.firstChild.before(itemToMove)}}};const CircleChart=({align:align="center",aria:aria={},rounded:rounded=false,borderColor:borderColor=(rounded?null:""),borderWidth:borderWidth=(rounded?20:null),chartData:chartData,children:children,className:className,colors:colors2=[],customOptions:customOptions={},dark:dark=false,data:data={},dataLabelHtml:dataLabelHtml="<div>{point.name}</div>",dataLabels:dataLabels=false,height:height,htmlOptions:htmlOptions={},id:id,innerSize:innerSize="md",legend:legend=false,maxPointSize:maxPointSize=null,minPointSize:minPointSize=null,startAngle:startAngle=null,style:style="pie",title:title,tooltipHtml:tooltipHtml,useHtml:useHtml=false,zMin:zMin=null,layout:layout="horizontal",verticalAlign:verticalAlign="bottom",x:x=0,y:y=0,...props})=>{const ariaProps=buildAriaProps(aria);const dataProps=buildDataProps(data);const htmlProps=buildHtmlProps(htmlOptions);HighchartsMore(Highcharts);const setupTheme=()=>{dark?Highcharts.setOptions(highchartsDarkTheme):Highcharts.setOptions(highchartsTheme)};setupTheme();Highcharts.setOptions({tooltip:{headerFormat:null,pointFormat:tooltipHtml?tooltipHtml:'<span style="font-weight: bold; color:{point.color};">●</span>{point.name}: <b>{point.y}</b>',useHTML:useHtml}});const innerSizes={sm:"35%",md:"50%",lg:"85%",none:"0%"};const innerSizeFormat=size=>innerSizes[size];const filteredProps={...props};delete filteredProps.verticalAlign;const[options,setOptions]=useState({});useEffect((()=>{const formattedChartData=chartData.map((obj=>{obj.y=obj.value;delete obj.value;return obj}));const staticOptions={title:{text:title},chart:{height:height,type:style,events:{render:event=>alignBlockElement(event),redraw:event=>alignBlockElement(event)}},legend:{align:align,verticalAlign:verticalAlign,layout:layout,x:x,y:y},plotOptions:{pie:{colors:colors2.length>0?mapColors(colors2):highchartsTheme.colors,dataLabels:{enabled:dataLabels,connectorShape:"straight",connectorWidth:3,format:dataLabelHtml},showInLegend:legend}},series:[{minPointSize:minPointSize,maxPointSize:maxPointSize,innerSize:borderWidth==20?"100%":innerSizeFormat(innerSize),data:formattedChartData,zMin:zMin,startAngle:startAngle,borderWidth:borderWidth,borderColor:borderColor}],credits:false};setOptions(merge(staticOptions,customOptions))}),[chartData]);return jsx(Fragment,{children:children?jsxs("div",{id:`wrapper-circle-chart-${id}`,children:[jsx(HighchartsReact,{containerProps:{className:classnames("pb_circle_chart",globalProps(filteredProps)),id:id,...ariaProps,...dataProps,...htmlProps},highcharts:Highcharts,options:options}),jsx("div",{className:"pb-circle-chart-block",children:children})]}):jsx(HighchartsReact,{containerProps:{className:classnames("pb_circle_chart",globalProps(filteredProps)),id:id,...ariaProps,...dataProps,...htmlProps},highcharts:Highcharts,options:options})})};const Gauge=({aria:aria={},chartData:chartData,customOptions:customOptions={},dark:dark=false,data:data={},disableAnimation:disableAnimation=false,fullCircle:fullCircle=false,height:height=null,htmlOptions:htmlOptions={},id:id,max:max=100,min:min=0,prefix:prefix="",showLabels:showLabels=false,style:style="solidgauge",suffix:suffix="",title:title="",tooltipHtml:tooltipHtml='<span style="font-weight: bold; color:{point.color};">●</span>{point.name}: <b>{point.y}</b>',colors:colors$1=[],minorTickInterval:minorTickInterval=null,circumference:circumference=(fullCircle?[0,360]:[-100,100]),...props})=>{const ariaProps=buildAriaProps(aria);const dataProps=buildDataProps(data);const htmlProps=buildHtmlProps(htmlOptions);HighchartsMore(Highcharts);SolidGauge(Highcharts);const setupTheme=()=>{dark?Highcharts.setOptions(highchartsDarkTheme):Highcharts.setOptions(highchartsTheme)};setupTheme();Highcharts.setOptions({tooltip:{pointFormat:tooltipHtml,followPointer:true}});const css=buildCss({pb_gauge_kit:true});const[options,setOptions]=useState({});useEffect((()=>{const formattedChartData=chartData.map((obj=>{obj.y=obj.value;delete obj.value;return obj}));const staticOptions={chart:{events:{load(){setTimeout(this.reflow.bind(this),0)}},type:style,height:height},title:{text:title},yAxis:{min:min,max:max,lineWidth:0,tickWidth:0,minorTickInterval:minorTickInterval,tickAmount:2,tickPositions:[min,max],labels:{y:26,enabled:showLabels}},credits:false,series:[{data:formattedChartData}],pane:{center:["50%","50%"],size:"90%",startAngle:circumference[0],endAngle:circumference[1],background:{borderWidth:20,innerRadius:"90%",outerRadius:"90%",shape:"arc",className:"gauge-pane"}},colors:colors$1!==void 0&&colors$1.length>0?mapColors(colors$1):highchartsTheme.colors,plotOptions:{series:{animation:!disableAnimation},solidgauge:{borderColor:colors$1!==void 0&&colors$1.length===1?mapColors(colors$1).join():highchartsTheme.colors[0],borderWidth:20,radius:90,innerRadius:"90%",dataLabels:{borderWidth:0,color:colors.text_lt_default,enabled:true,format:`<span class="prefix${dark?" dark":""}">${prefix}</span><span class="fix${dark?" dark":""}">{y:,f}</span><span class="suffix${dark?" dark":""}">${suffix}</span>`,style:{fontFamily:typography.font_family_base,fontWeight:typography.regular,fontSize:typography.heading_2},y:-26}}}};setOptions(merge(staticOptions,customOptions));if(document.querySelector(".prefix")){document.querySelectorAll(".prefix").forEach((prefix2=>{prefix2.setAttribute("y","28")}));document.querySelectorAll(".fix").forEach((fix=>fix.setAttribute("y","38")))}}),[chartData]);return jsx(HighchartsReact,{containerProps:{className:classnames(css,globalProps(props)),id:id,...ariaProps,...dataProps,...htmlProps},highcharts:Highcharts,options:options})};const LineGraph=({aria:aria={},data:data={},align:align="center",className:className="pb_bar_graph",customOptions:customOptions={},dark:dark=false,gradient:gradient=false,type:type="line",htmlOptions:htmlOptions={},id:id,legend:legend=false,toggleLegendClick:toggleLegendClick=true,layout:layout="horizontal",verticalAlign:verticalAlign="bottom",x:x=0,y:y=0,axisTitle:axisTitle,xAxisCategories:xAxisCategories,yAxisMin:yAxisMin,yAxisMax:yAxisMax,chartData:chartData,pointStart:pointStart,subTitle:subTitle,title:title,height:height,colors:colors2=[],...props})=>{const ariaProps=buildAriaProps(aria);const dataProps=buildDataProps(data);const htmlProps=buildHtmlProps(htmlOptions);const setupTheme=()=>{dark?Highcharts.setOptions(highchartsDarkTheme):Highcharts.setOptions(highchartsTheme)};setupTheme();const staticOptions={title:{text:title},chart:{height:height,type:type},subtitle:{text:subTitle},yAxis:{min:yAxisMin,max:yAxisMax,title:{text:axisTitle}},xAxis:{categories:xAxisCategories},legend:{enabled:legend,align:align,verticalAlign:verticalAlign,layout:layout,x:x,y:y},colors:colors2!==void 0&&colors2.length>0?mapColors(colors2):highchartsTheme.colors,plotOptions:{series:{pointStart:pointStart,events:{},dataLabels:{enabled:false}}},series:chartData,credits:false};if(!toggleLegendClick){staticOptions.plotOptions.series.events={legendItemClick:()=>false}}const filteredProps={...props};delete filteredProps.verticalAlign;const[options,setOptions]=useState({});useEffect((()=>{setOptions(merge(staticOptions,customOptions))}),[chartData]);return jsx(HighchartsReact,{containerProps:{className:classnames(globalProps(filteredProps),className),id:id,...ariaProps,...dataProps,...htmlProps},highcharts:Highcharts,options:options})};export{BarGraph as B,CircleChart as C,Gauge as G,LineGraph as L};