no-frills-ui 0.0.14-rc.1 → 0.0.14-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 (56) hide show
  1. package/dist/index.js +446 -225
  2. package/dist/index.js.map +1 -1
  3. package/lib-esm/components/Accordion/AccordionStep.js +9 -8
  4. package/lib-esm/components/Accordion/AccordionStep.js.map +1 -1
  5. package/lib-esm/components/Chip/Chip.js +5 -4
  6. package/lib-esm/components/Chip/Chip.js.map +1 -1
  7. package/lib-esm/components/ChipInput/ChipInput.js +80 -51
  8. package/lib-esm/components/ChipInput/ChipInput.js.map +1 -1
  9. package/lib-esm/components/DragAndDrop/DragAndDrop.js +2 -2
  10. package/lib-esm/components/DragAndDrop/DragItem.js +2 -2
  11. package/lib-esm/components/Drawer/Drawer.d.ts +1 -1
  12. package/lib-esm/components/Drawer/Drawer.js +2 -3
  13. package/lib-esm/components/Drawer/Drawer.js.map +1 -1
  14. package/lib-esm/components/Groups/Group.js +3 -3
  15. package/lib-esm/components/Groups/Group.js.map +1 -1
  16. package/lib-esm/components/Input/Checkbox.d.ts +2 -0
  17. package/lib-esm/components/Input/Checkbox.js +54 -23
  18. package/lib-esm/components/Input/Checkbox.js.map +1 -1
  19. package/lib-esm/components/Input/Dropdown.d.ts +2 -0
  20. package/lib-esm/components/Input/Dropdown.js +123 -59
  21. package/lib-esm/components/Input/Dropdown.js.map +1 -1
  22. package/lib-esm/components/Input/Input.js +17 -8
  23. package/lib-esm/components/Input/Input.js.map +1 -1
  24. package/lib-esm/components/Input/Radio.d.ts +2 -0
  25. package/lib-esm/components/Input/Radio.js +22 -10
  26. package/lib-esm/components/Input/Radio.js.map +1 -1
  27. package/lib-esm/components/Input/RadioButton.d.ts +2 -0
  28. package/lib-esm/components/Input/RadioButton.js +21 -9
  29. package/lib-esm/components/Input/RadioButton.js.map +1 -1
  30. package/lib-esm/components/Input/Select.js +21 -11
  31. package/lib-esm/components/Input/Select.js.map +1 -1
  32. package/lib-esm/components/Input/TextArea.js +17 -8
  33. package/lib-esm/components/Input/TextArea.js.map +1 -1
  34. package/lib-esm/components/Input/Toggle.d.ts +2 -0
  35. package/lib-esm/components/Input/Toggle.js +45 -15
  36. package/lib-esm/components/Input/Toggle.js.map +1 -1
  37. package/lib-esm/components/Input/index.d.ts +1 -0
  38. package/lib-esm/components/Menu/MenuItem.d.ts +1 -1
  39. package/lib-esm/components/Menu/MenuItem.js +1 -1
  40. package/lib-esm/components/Menu/MenuItem.js.map +1 -1
  41. package/lib-esm/components/Modal/Modal.d.ts +1 -1
  42. package/lib-esm/components/Modal/Modal.js +1 -2
  43. package/lib-esm/components/Modal/Modal.js.map +1 -1
  44. package/lib-esm/components/Notification/NotificationManager.js +1 -0
  45. package/lib-esm/components/Notification/NotificationManager.js.map +1 -1
  46. package/lib-esm/components/Popover/Popover.d.ts +1 -1
  47. package/lib-esm/components/Popover/Popover.js +3 -3
  48. package/lib-esm/components/Popover/Popover.js.map +1 -1
  49. package/lib-esm/components/Stepper/Stepper.js +14 -5
  50. package/lib-esm/components/Stepper/Stepper.js.map +1 -1
  51. package/lib-esm/index.js +1 -1
  52. package/lib-esm/shared/LayerManager.js +2 -2
  53. package/lib-esm/shared/styles.d.ts +4 -0
  54. package/lib-esm/shared/styles.js +10 -6
  55. package/lib-esm/shared/styles.js.map +1 -1
  56. package/package.json +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"Dropdown.js","sources":["../../../src/components/Input/Dropdown.tsx"],"sourcesContent":["import React, { useEffect, useState } from 'react';\nimport styled from '@emotion/styled';\nimport { ExpandMore } from '../../icons';\nimport { Menu } from '../Menu';\nimport { Popover, POPOVER_POSITION } from '../Popover';\nimport Input from './Input';\n\ntype DropdownProps<T> = React.PropsWithChildren<{\n /** Value of the control */\n value?: T | T[];\n /**\n * If multiple elements can be selected\n * @default false\n */\n multiSelect?: boolean;\n /** Change handler */\n onChange?: (v: T | T[]) => void;\n /** Label of the control */\n label?: string;\n /** Error message */\n errorText?: string;\n /** Makes field required */\n required?: boolean;\n /** Disables the field */\n disabled?: boolean;\n}> &\n Omit<React.InputHTMLAttributes<HTMLInputElement>, 'value'>;\n\nconst ArrowContainer = styled.span`\n position: absolute;\n right: 12px;\n top: 16px;\n pointer-events: none;\n`;\n\n/**\n * Dropdown component that allows selection from a list of options.\n * Supports single and multi-select modes.\n *\n * @template T - The type of the value(s) in the dropdown.\n * @param props - The properties for the Dropdown component.\n * @returns The rendered Dropdown component.\n */\n/**\n * Dropdown Component\n * @template T - The type of value(s) in the dropdown.\n * @param props - Component props\n * @param outerRef - Ref forwarded to the underlying HTMLInputElement\n */\nfunction DropdownComponent<T extends object>(\n props: DropdownProps<T>,\n outerRef: React.Ref<HTMLInputElement>,\n) {\n const {\n multiSelect = false,\n onChange,\n children,\n value: propValue,\n label,\n errorText,\n required,\n disabled,\n ...rest\n } = props;\n const [open, setOpen] = useState(false);\n const [value, setValue] = useState<T | T[] | undefined>(propValue);\n const id = React.useId();\n const menuId = `${id}-menu`;\n const menuRef = React.useRef<HTMLDivElement | null>(null);\n const triggerRef = React.useRef<HTMLInputElement | null>(null);\n\n // Focus menu when opened\n useEffect(() => {\n if (open) {\n // Wait for Popover to fully open and focus itself first\n // Then move focus to the first menu item\n const timer = setTimeout(() => {\n const firstItem = menuRef.current?.querySelector('[role=\"option\"]') as HTMLElement;\n if (firstItem) {\n firstItem.focus();\n }\n }, 100); // Wait after Popover has set initial focus\n return () => clearTimeout(timer);\n }\n }, [open]);\n\n /**\n * Handles keydown events on the input trigger.\n * Opens the menu on 'Enter', 'Space', 'ArrowDown', or 'ArrowUp'.\n *\n * @param {React.KeyboardEvent<HTMLInputElement>} e - The keyboard event.\n */\n const onKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {\n if (['ArrowDown', 'ArrowUp', 'Enter', ' '].includes(e.key)) {\n e.preventDefault();\n setOpen(true);\n }\n };\n\n /**\n * Handles changes to the dropdown value.\n * Updates local state and calls the external onChange handler.\n * Closes the dropdown if not in multi-select mode.\n *\n * @param {T | T[]} val - The new value(s).\n */\n const changeHandler = (val: T | T[]) => {\n setValue(val);\n onChange?.(val);\n\n // Close dropdown after selection if not multiSelect\n if (!multiSelect) {\n setOpen(false);\n triggerRef.current?.focus();\n }\n };\n\n /**\n * Toggles the dropdown open state on click.\n */\n const clickHandler = () => setOpen(true);\n\n const TriggerElement = React.forwardRef<HTMLInputElement>((passedProps, ref) => {\n // Helper to assign both internal triggerRef and external forwarded ref\n const assignRefs = (node: HTMLInputElement | null) => {\n triggerRef.current = node;\n\n if (!outerRef) return;\n if (typeof outerRef === 'function') {\n outerRef(node);\n } else {\n (outerRef as React.MutableRefObject<HTMLInputElement | null>).current = node;\n }\n };\n\n // Combine the ref passed by parent with our assignRefs so both are updated\n const combinedRef: React.Ref<HTMLInputElement> = (node) => {\n assignRefs(node);\n if (typeof ref === 'function') {\n ref(node);\n } else if (ref) {\n (ref as React.MutableRefObject<HTMLInputElement | null>).current = node;\n }\n };\n\n return (\n <>\n <Input\n {...rest}\n {...passedProps}\n ref={combinedRef}\n type=\"text\"\n value={value && String(value)}\n label={label}\n errorText={errorText}\n onClick={clickHandler}\n onKeyDown={onKeyDown}\n required={required}\n disabled={disabled}\n readOnly\n role=\"combobox\"\n aria-haspopup=\"listbox\"\n aria-expanded={open}\n aria-controls={menuId}\n />\n <ArrowContainer aria-hidden=\"true\">\n <ExpandMore />\n </ArrowContainer>\n </>\n );\n });\n TriggerElement.displayName = 'DropdownTrigger';\n\n return (\n <Popover\n position={POPOVER_POSITION.BOTTOM_LEFT}\n open={open}\n element={TriggerElement}\n onClose={() => {\n setOpen(false);\n triggerRef.current?.focus();\n }}\n >\n <Menu\n ref={menuRef}\n id={menuId}\n value={value}\n multiSelect={multiSelect}\n onChange={changeHandler}\n >\n {children}\n </Menu>\n </Popover>\n );\n}\n\nconst Dropdown = React.forwardRef(DropdownComponent) as <T>(\n props: DropdownProps<T> & React.RefAttributes<HTMLInputElement>,\n) => React.ReactElement | null;\nexport default Dropdown;\n"],"names":["ArrowContainer","styled","DropdownComponent","props","outerRef","multiSelect","onChange","children","value","propValue","label","errorText","required","disabled","rest","open","setOpen","useState","setValue","id","React","useId","menuId","menuRef","useRef","triggerRef","useEffect","timer","setTimeout","firstItem","current","querySelector","focus","clearTimeout","onKeyDown","e","includes","key","preventDefault","changeHandler","val","clickHandler","TriggerElement","forwardRef","passedProps","ref","assignRefs","node","combinedRef","_jsxs","_Fragment","_jsx","Input","type","String","onClick","readOnly","role","aria-haspopup","aria-expanded","aria-controls","aria-hidden","ExpandMore","displayName","Popover","position","POPOVER_POSITION","BOTTOM_LEFT","element","onClose","Menu","Dropdown"],"mappings":"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"}
1
+ {"version":3,"file":"Dropdown.js","sources":["../../../src/components/Input/Dropdown.tsx"],"sourcesContent":["import React, { useEffect, useRef, useState } from 'react';\nimport styled from '@emotion/styled';\nimport { ExpandMore } from '../../icons';\nimport { Menu } from '../Menu';\nimport { MenuItemProps } from '../Menu/MenuItem';\nimport { Popover, POPOVER_POSITION } from '../Popover';\nimport Input from './Input';\n\ntype DropdownProps<T> = React.PropsWithChildren<{\n /** Value of the control */\n value?: T | T[];\n /**\n * If multiple elements can be selected\n * @default false\n */\n multiSelect?: boolean;\n /** Change handler */\n onChange?: (v: T | T[]) => void;\n /** Label of the control */\n label?: string;\n /** Error message */\n errorText?: string;\n /** Makes field required */\n required?: boolean;\n /** Disables the field */\n disabled?: boolean;\n children?: React.ReactElement<MenuItemProps<T>> | React.ReactElement<MenuItemProps<T>>[];\n}> &\n Omit<React.InputHTMLAttributes<HTMLInputElement>, 'value'>;\n\nconst ArrowContainer = styled.span`\n position: absolute;\n right: 12px;\n top: 16px;\n pointer-events: none;\n`;\n\n/**\n * DropdownTrigger Component\n */\nconst DropdownTrigger = React.forwardRef<\n HTMLInputElement,\n Omit<React.InputHTMLAttributes<HTMLInputElement>, 'value'> & {\n displayValue: string;\n label?: string;\n errorText?: string;\n open: boolean;\n menuId: string;\n toggleOpen: () => void;\n onKeyDown: (e: React.KeyboardEvent<HTMLInputElement>) => void;\n forwardedRef?: React.Ref<HTMLInputElement>;\n }\n>((props, ref) => {\n const {\n displayValue,\n label,\n errorText,\n open,\n menuId,\n toggleOpen,\n onKeyDown,\n forwardedRef,\n ...rest\n } = props;\n const triggerRef = React.useRef<HTMLInputElement | null>(null);\n\n // Helper to assign both internal triggerRef and external forwarded ref\n const assignRefs = React.useCallback(\n (node: HTMLInputElement | null) => {\n triggerRef.current = node;\n\n if (!forwardedRef) return;\n if (typeof forwardedRef === 'function') {\n forwardedRef(node);\n } else {\n (forwardedRef as React.MutableRefObject<HTMLInputElement | null>).current = node;\n }\n },\n [forwardedRef],\n );\n\n // Combine the ref passed by parent with our assignRefs so both are updated\n const combinedRef = React.useCallback(\n (node: HTMLInputElement | null) => {\n assignRefs(node);\n if (typeof ref === 'function') {\n ref(node);\n } else if (ref) {\n (ref as React.MutableRefObject<HTMLInputElement | null>).current = node;\n }\n },\n [assignRefs, ref],\n );\n\n return (\n <>\n <Input\n {...rest}\n ref={combinedRef}\n type=\"text\"\n value={displayValue}\n label={label}\n errorText={errorText}\n onClick={toggleOpen}\n onKeyDown={onKeyDown}\n inputMode=\"none\"\n role=\"combobox\"\n aria-haspopup=\"listbox\"\n aria-expanded={open}\n aria-controls={menuId}\n />\n <ArrowContainer aria-hidden=\"true\">\n <ExpandMore />\n </ArrowContainer>\n </>\n );\n});\nDropdownTrigger.displayName = 'DropdownTrigger';\n\n/**\n * Dropdown component that allows selection from a list of options.\n * Supports single and multi-select modes.\n *\n * @template T - The type of the value(s) in the dropdown.\n * @param props - The properties for the Dropdown component.\n * @returns The rendered Dropdown component.\n */\nfunction DropdownComponent<T extends object>(\n props: DropdownProps<T>,\n outerRef: React.Ref<HTMLInputElement>,\n) {\n const {\n multiSelect = false,\n onChange,\n children,\n value: propValue,\n label,\n errorText,\n required,\n disabled,\n ...rest\n } = props;\n const [open, setOpen] = useState(false);\n const [value, setValue] = useState<T | T[] | undefined>(propValue);\n const id = React.useId();\n const menuId = `${id}-menu`;\n const menuRef = React.useRef<HTMLDivElement | null>(null);\n const triggerRef = React.useRef<HTMLInputElement | null>(null);\n\n /**\n * Gets the display value for the dropdown based on the current value and children.\n *\n * @param currentValue - The current value of the dropdown.\n * @param currentChildren - The children of the dropdown.\n * @returns The display value.\n */\n const getDisplayValue = (\n currentValue: T | T[] | undefined,\n currentChildren: React.ReactNode,\n ): string => {\n if (currentValue === undefined || currentValue === null) return '';\n\n const findLabel = (val: T): string => {\n let label = '';\n React.Children.forEach(currentChildren, (child) => {\n if (React.isValidElement(child)) {\n const props = child.props as MenuItemProps<T> & React.PropsWithChildren;\n if ('value' in props && props.value === val) {\n label = String(props.children);\n }\n }\n });\n return label;\n };\n\n if (Array.isArray(currentValue)) {\n return currentValue.map(findLabel).filter(Boolean).join(', ');\n }\n\n return findLabel(currentValue as T);\n };\n\n const displayValue = getDisplayValue(value, children) || (value ? String(value) : '');\n\n // Sync prop value with state\n const prevValueRef = useRef<T | T[] | undefined>(undefined);\n useEffect(() => {\n if (propValue !== prevValueRef.current) {\n setValue(propValue);\n prevValueRef.current = propValue;\n }\n }, [propValue]);\n\n // Focus menu when opened\n useEffect(() => {\n if (open) {\n // Wait for Popover to fully open and focus itself first\n // Then move focus to the first menu item\n const timer = setTimeout(() => {\n const firstItem = menuRef.current?.querySelector('[role=\"option\"]') as HTMLElement;\n if (firstItem) {\n firstItem.focus();\n }\n }, 100); // Wait after Popover has set initial focus\n return () => clearTimeout(timer);\n }\n }, [open]);\n\n /**\n * Handles keydown events on the input trigger.\n * Opens the menu on 'Enter', 'Space', 'ArrowDown', or 'ArrowUp'.\n *\n * @param {React.KeyboardEvent<HTMLInputElement>} e - The keyboard event.\n */\n const onKeyDown = React.useCallback((e: React.KeyboardEvent<HTMLInputElement>) => {\n if (['ArrowDown', 'ArrowUp', 'Enter', ' '].includes(e.key)) {\n e.preventDefault();\n setOpen(true);\n } else if (e.key !== 'Tab') {\n // Prevent typing to mimic readOnly behavior while allowing native validation\n e.preventDefault();\n }\n }, []);\n\n /**\n * Handles changes to the dropdown value.\n * Updates local state and calls the external onChange handler.\n * Closes the dropdown if not in multi-select mode.\n *\n * @param {T | T[]} val - The new value(s).\n */\n const changeHandler = (val: T | T[]) => {\n setValue(val);\n onChange?.(val);\n\n // Close dropdown after selection if not multiSelect\n if (!multiSelect) {\n setOpen(false);\n triggerRef.current?.focus();\n }\n };\n\n /**\n * Toggles the dropdown open state on click.\n */\n const clickHandler = React.useCallback(() => setOpen(true), []);\n\n /**\n * Forwarded ref handler for the trigger input.\n */\n const handleForwardedRef = React.useCallback(\n (node: HTMLInputElement | null) => {\n triggerRef.current = node;\n if (typeof outerRef === 'function') {\n outerRef(node);\n } else if (outerRef) {\n (outerRef as React.MutableRefObject<HTMLInputElement | null>).current = node;\n }\n },\n [outerRef],\n );\n\n return (\n <Popover\n position={POPOVER_POSITION.BOTTOM_LEFT}\n open={open}\n element={\n <DropdownTrigger\n {...rest}\n displayValue={displayValue}\n label={label}\n errorText={errorText}\n open={open}\n menuId={menuId}\n toggleOpen={clickHandler}\n onKeyDown={onKeyDown}\n required={required}\n disabled={disabled}\n forwardedRef={handleForwardedRef}\n />\n }\n onClose={() => {\n setOpen(false);\n triggerRef.current?.focus();\n }}\n >\n <Menu\n ref={menuRef}\n id={menuId}\n value={value}\n multiSelect={multiSelect}\n onChange={changeHandler}\n >\n {children}\n </Menu>\n </Popover>\n );\n}\n\nconst Dropdown = React.forwardRef(DropdownComponent) as <T>(\n props: DropdownProps<T> & React.RefAttributes<HTMLInputElement>,\n) => React.ReactElement | null;\nexport default Dropdown;\n"],"names":["ArrowContainer","styled","DropdownTrigger","React","forwardRef","props","ref","displayValue","label","errorText","open","menuId","toggleOpen","onKeyDown","forwardedRef","rest","triggerRef","useRef","assignRefs","useCallback","node","current","combinedRef","_jsxs","_Fragment","_jsx","Input","type","value","onClick","inputMode","role","aria-haspopup","aria-expanded","aria-controls","aria-hidden","ExpandMore","displayName","DropdownComponent","outerRef","multiSelect","onChange","children","propValue","required","disabled","setOpen","useState","setValue","id","useId","menuRef","getDisplayValue","currentValue","currentChildren","undefined","findLabel","val","Children","forEach","child","isValidElement","String","Array","isArray","map","filter","Boolean","join","prevValueRef","useEffect","timer","setTimeout","firstItem","querySelector","focus","clearTimeout","e","includes","key","preventDefault","changeHandler","clickHandler","handleForwardedRef","Popover","position","POPOVER_POSITION","BOTTOM_LEFT","element","onClose","Menu","Dropdown"],"mappings":"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"}
@@ -1,14 +1,14 @@
1
1
  import { jsxs, jsx } from '@emotion/react/jsx-runtime';
2
- import React, { useState, useId, useRef, useEffect } from 'react';
2
+ import React, { useState, useId, useRef, useImperativeHandle, useEffect } from 'react';
3
3
  import styled from '@emotion/styled';
4
4
  import { getThemeValue, THEME_NAME } from '../../shared/constants.js';
5
5
 
6
6
  const Label$5 = /*#__PURE__*/ styled("label", {
7
- target: "el9i5v60",
7
+ target: "e1g8e2pu0",
8
8
  label: "Label"
9
9
  })("display:inline-flex;flex-direction:column;position:relative;margin:10px 5px;");
10
10
  const TextField$1 = /*#__PURE__*/ styled("input", {
11
- target: "el9i5v61",
11
+ target: "e1g8e2pu1",
12
12
  label: "TextField"
13
13
  })("outline:none;color:inherit;padding:0 8px;line-height:30px;min-height:30px;width:250px;border-radius:3px;border:1px solid ", getThemeValue(THEME_NAME.BORDER_COLOR), ";display:inline-block;background-color:", getThemeValue(THEME_NAME.BACKGROUND), ";&:focus,&:active{border-color:", getThemeValue(THEME_NAME.PRIMARY), ";box-shadow:0 0 0 4px ", getThemeValue(THEME_NAME.PRIMARY_LIGHT), ";}&:focus + span,&:active + span{color:", getThemeValue(THEME_NAME.PRIMARY), ";}&:disabled{border-color:", getThemeValue(THEME_NAME.DISABLED_BORDER), ";background-color:", getThemeValue(THEME_NAME.DISABLED_BACKGROUND), ";padding:0 8px;}&:disabled + span{color:", getThemeValue(THEME_NAME.DISABLED), ";}&:focus:invalid{border-color:", getThemeValue(THEME_NAME.ERROR), ";box-shadow:0 0 0 4px ", getThemeValue(THEME_NAME.ERROR_LIGHT), ";}", (props)=>props.touched ? `
14
14
  &:invalid {
@@ -32,19 +32,21 @@ const TextField$1 = /*#__PURE__*/ styled("input", {
32
32
  line-height: 14px;
33
33
  }
34
34
  ` : '', " &:focus + span,&:placeholder-shown + span{top:-8px;background:", getThemeValue(THEME_NAME.BACKGROUND), ";font-size:12px;line-height:14px;}");
35
- const ErrorContainer$3 = /*#__PURE__*/ styled("div", {
36
- target: "el9i5v62",
35
+ const ErrorContainer$5 = /*#__PURE__*/ styled("div", {
36
+ target: "e1g8e2pu2",
37
37
  label: "ErrorContainer"
38
38
  })("color:", getThemeValue(THEME_NAME.ERROR), ";padding-top:3px;font-size:12px;line-height:14px;margin-left:3px;");
39
39
  /**
40
40
  * Input Component
41
41
  * @param props - Component props
42
42
  * @param ref - Ref forwarded to the underlying HTMLInputElement
43
- */ const Input$2 = /*#__PURE__*/ React.forwardRef((props, ref)=>{
43
+ */ const Input$2 = /*#__PURE__*/ React.forwardRef((props, forwardedRef)=>{
44
44
  const [touched, setTouched] = useState(false);
45
45
  const [value, setValue] = useState(props.value || '');
46
46
  const errorId = useId();
47
47
  const prevValueRef = useRef(undefined);
48
+ const internalRef = useRef(null);
49
+ useImperativeHandle(forwardedRef, ()=>internalRef.current);
48
50
  useEffect(()=>{
49
51
  if (props.value !== undefined && props.value !== prevValueRef.current) {
50
52
  setValue(props.value);
@@ -53,6 +55,13 @@ const ErrorContainer$3 = /*#__PURE__*/ styled("div", {
53
55
  }, [
54
56
  props.value
55
57
  ]);
58
+ useEffect(()=>{
59
+ if (internalRef.current) {
60
+ internalRef.current.setCustomValidity(props.errorText || '');
61
+ }
62
+ }, [
63
+ props.errorText
64
+ ]);
56
65
  const handleFocus = (e)=>{
57
66
  setTouched(true);
58
67
  if (props.onFocus) {
@@ -71,7 +80,7 @@ const ErrorContainer$3 = /*#__PURE__*/ styled("div", {
71
80
  children: [
72
81
  /*#__PURE__*/ jsx(TextField$1, {
73
82
  ...props,
74
- ref: ref,
83
+ ref: internalRef,
75
84
  value: value,
76
85
  onChange: onChangeHandler,
77
86
  onFocus: handleFocus,
@@ -83,7 +92,7 @@ const ErrorContainer$3 = /*#__PURE__*/ styled("div", {
83
92
  /*#__PURE__*/ jsx("span", {
84
93
  children: props.label
85
94
  }),
86
- props.errorText && /*#__PURE__*/ jsx(ErrorContainer$3, {
95
+ props.errorText && /*#__PURE__*/ jsx(ErrorContainer$5, {
87
96
  id: errorId,
88
97
  children: props.errorText
89
98
  })
@@ -1 +1 @@
1
- {"version":3,"file":"Input.js","sources":["../../../src/components/Input/Input.tsx"],"sourcesContent":["import React, { useState, useEffect, useId, useRef } from 'react';\nimport styled from '@emotion/styled';\nimport { getThemeValue, THEME_NAME } from '../../shared/constants';\n\ntype InputProps = {\n /** Label for the field */\n label?: string;\n /** Error text to be shown below the field */\n errorText?: string;\n} & React.AllHTMLAttributes<HTMLInputElement>;\n\ntype InputInternalProps = InputProps & {\n touched: boolean;\n};\n\nconst Label = styled.label`\n display: inline-flex;\n flex-direction: column;\n position: relative;\n margin: 10px 5px;\n`;\n\nconst TextField = styled.input<InputInternalProps>`\n outline: none;\n color: inherit;\n padding: 0 8px;\n line-height: 30px;\n min-height: 30px;\n width: 250px;\n border-radius: 3px;\n border: 1px solid ${getThemeValue(THEME_NAME.BORDER_COLOR)};\n display: inline-block;\n background-color: ${getThemeValue(THEME_NAME.BACKGROUND)};\n\n /** Focused */\n &:focus,\n &:active {\n border-color: ${getThemeValue(THEME_NAME.PRIMARY)};\n box-shadow: 0 0 0 4px ${getThemeValue(THEME_NAME.PRIMARY_LIGHT)};\n }\n\n &:focus + span,\n &:active + span {\n color: ${getThemeValue(THEME_NAME.PRIMARY)};\n }\n\n /** Disabled */\n &:disabled {\n border-color: ${getThemeValue(THEME_NAME.DISABLED_BORDER)};\n background-color: ${getThemeValue(THEME_NAME.DISABLED_BACKGROUND)};\n padding: 0 8px;\n }\n\n &:disabled + span {\n color: ${getThemeValue(THEME_NAME.DISABLED)};\n }\n\n /** Invalid */\n &:focus:invalid {\n border-color: ${getThemeValue(THEME_NAME.ERROR)};\n box-shadow: 0 0 0 4px ${getThemeValue(THEME_NAME.ERROR_LIGHT)};\n }\n\n ${(props) =>\n props.touched\n ? `\n &:invalid {\n border-color: ${getThemeValue(THEME_NAME.ERROR)};\n }\n\n &:invalid + span {\n color: ${getThemeValue(THEME_NAME.ERROR)};\n }\n `\n : ''}\n\n /** Error */\n ${(props) =>\n props.errorText\n ? `\n border-color: ${getThemeValue(THEME_NAME.ERROR)};\n\n & + span {\n color: ${getThemeValue(THEME_NAME.ERROR)};\n }\n `\n : ''}\n\n /** Required */\n &:required + span:after {\n content: '*';\n margin-left: 2px;\n color: ${getThemeValue(THEME_NAME.ERROR)};\n }\n\n /** Label Animation */\n & + span {\n position: absolute;\n padding: 0 5px;\n top: 0px;\n left: 4px;\n font-size: 14px;\n line-height: 32px;\n transition: all 300ms ease;\n }\n\n ${(props) =>\n props.value !== ''\n ? `\n & + span {\n top: -8px;\n background: ${getThemeValue(THEME_NAME.BACKGROUND)};\n font-size: 12px;\n line-height: 14px;\n }\n `\n : ''}\n\n &:focus + span, &:placeholder-shown + span {\n top: -8px;\n background: ${getThemeValue(THEME_NAME.BACKGROUND)};\n font-size: 12px;\n line-height: 14px;\n }\n`;\n\nconst ErrorContainer = styled.div`\n color: ${getThemeValue(THEME_NAME.ERROR)};\n padding-top: 3px;\n font-size: 12px;\n line-height: 14px;\n margin-left: 3px;\n`;\n\n/**\n * Input Component\n * @param props - Component props\n * @param ref - Ref forwarded to the underlying HTMLInputElement\n */\nconst Input = React.forwardRef<HTMLInputElement, Omit<InputProps, 'as'>>((props, ref) => {\n const [touched, setTouched] = useState(false);\n const [value, setValue] = useState(props.value || '');\n const errorId = useId();\n const prevValueRef = useRef<string>(undefined);\n\n useEffect(() => {\n if (props.value !== undefined && props.value !== prevValueRef.current) {\n setValue(props.value);\n prevValueRef.current = props.value as string;\n }\n }, [props.value]);\n\n const handleFocus = (e: React.FocusEvent<HTMLInputElement>) => {\n setTouched(true);\n if (props.onFocus) {\n props.onFocus(e);\n }\n };\n\n const onChangeHandler = (e: React.ChangeEvent<HTMLInputElement>) => {\n if (props.onChange) {\n setValue(e.target.value);\n props.onChange(e);\n } else {\n setValue(e.target.value);\n }\n };\n\n return (\n <Label>\n <TextField\n {...props}\n ref={ref}\n value={value}\n onChange={onChangeHandler}\n onFocus={handleFocus}\n touched={touched}\n aria-invalid={!!props.errorText}\n aria-required={props.required}\n aria-describedby={props.errorText ? errorId : undefined}\n />\n <span>{props.label}</span>\n {props.errorText && <ErrorContainer id={errorId}>{props.errorText}</ErrorContainer>}\n </Label>\n );\n});\n\nInput.displayName = 'Input';\nexport default Input;\n"],"names":["Label","styled","TextField","getThemeValue","THEME_NAME","BORDER_COLOR","BACKGROUND","PRIMARY","PRIMARY_LIGHT","DISABLED_BORDER","DISABLED_BACKGROUND","DISABLED","ERROR","ERROR_LIGHT","props","touched","errorText","value","ErrorContainer","Input","React","forwardRef","ref","setTouched","useState","setValue","errorId","useId","prevValueRef","useRef","undefined","useEffect","current","handleFocus","e","onFocus","onChangeHandler","onChange","target","_jsxs","_jsx","aria-invalid","aria-required","required","aria-describedby","span","label","id","displayName"],"mappings":"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"}
1
+ {"version":3,"file":"Input.js","sources":["../../../src/components/Input/Input.tsx"],"sourcesContent":["import React, { useState, useEffect, useId, useRef, useImperativeHandle } from 'react';\nimport styled from '@emotion/styled';\nimport { getThemeValue, THEME_NAME } from '../../shared/constants';\n\ntype InputProps = {\n /** Label for the field */\n label?: string;\n /** Error text to be shown below the field */\n errorText?: string;\n} & React.AllHTMLAttributes<HTMLInputElement>;\n\ntype InputInternalProps = InputProps & {\n touched: boolean;\n};\n\nconst Label = styled.label`\n display: inline-flex;\n flex-direction: column;\n position: relative;\n margin: 10px 5px;\n`;\n\nconst TextField = styled.input<InputInternalProps>`\n outline: none;\n color: inherit;\n padding: 0 8px;\n line-height: 30px;\n min-height: 30px;\n width: 250px;\n border-radius: 3px;\n border: 1px solid ${getThemeValue(THEME_NAME.BORDER_COLOR)};\n display: inline-block;\n background-color: ${getThemeValue(THEME_NAME.BACKGROUND)};\n\n /** Focused */\n &:focus,\n &:active {\n border-color: ${getThemeValue(THEME_NAME.PRIMARY)};\n box-shadow: 0 0 0 4px ${getThemeValue(THEME_NAME.PRIMARY_LIGHT)};\n }\n\n &:focus + span,\n &:active + span {\n color: ${getThemeValue(THEME_NAME.PRIMARY)};\n }\n\n /** Disabled */\n &:disabled {\n border-color: ${getThemeValue(THEME_NAME.DISABLED_BORDER)};\n background-color: ${getThemeValue(THEME_NAME.DISABLED_BACKGROUND)};\n padding: 0 8px;\n }\n\n &:disabled + span {\n color: ${getThemeValue(THEME_NAME.DISABLED)};\n }\n\n /** Invalid */\n &:focus:invalid {\n border-color: ${getThemeValue(THEME_NAME.ERROR)};\n box-shadow: 0 0 0 4px ${getThemeValue(THEME_NAME.ERROR_LIGHT)};\n }\n\n ${(props) =>\n props.touched\n ? `\n &:invalid {\n border-color: ${getThemeValue(THEME_NAME.ERROR)};\n }\n\n &:invalid + span {\n color: ${getThemeValue(THEME_NAME.ERROR)};\n }\n `\n : ''}\n\n /** Error */\n ${(props) =>\n props.errorText\n ? `\n border-color: ${getThemeValue(THEME_NAME.ERROR)};\n\n & + span {\n color: ${getThemeValue(THEME_NAME.ERROR)};\n }\n `\n : ''}\n\n /** Required */\n &:required + span:after {\n content: '*';\n margin-left: 2px;\n color: ${getThemeValue(THEME_NAME.ERROR)};\n }\n\n /** Label Animation */\n & + span {\n position: absolute;\n padding: 0 5px;\n top: 0px;\n left: 4px;\n font-size: 14px;\n line-height: 32px;\n transition: all 300ms ease;\n }\n\n ${(props) =>\n props.value !== ''\n ? `\n & + span {\n top: -8px;\n background: ${getThemeValue(THEME_NAME.BACKGROUND)};\n font-size: 12px;\n line-height: 14px;\n }\n `\n : ''}\n\n &:focus + span, &:placeholder-shown + span {\n top: -8px;\n background: ${getThemeValue(THEME_NAME.BACKGROUND)};\n font-size: 12px;\n line-height: 14px;\n }\n`;\n\nconst ErrorContainer = styled.div`\n color: ${getThemeValue(THEME_NAME.ERROR)};\n padding-top: 3px;\n font-size: 12px;\n line-height: 14px;\n margin-left: 3px;\n`;\n\n/**\n * Input Component\n * @param props - Component props\n * @param ref - Ref forwarded to the underlying HTMLInputElement\n */\nconst Input = React.forwardRef<HTMLInputElement, Omit<InputProps, 'as'>>((props, forwardedRef) => {\n const [touched, setTouched] = useState(false);\n const [value, setValue] = useState(props.value || '');\n const errorId = useId();\n const prevValueRef = useRef<string>(undefined);\n const internalRef = useRef<HTMLInputElement>(null);\n\n useImperativeHandle(forwardedRef, () => internalRef.current as HTMLInputElement);\n\n useEffect(() => {\n if (props.value !== undefined && props.value !== prevValueRef.current) {\n setValue(props.value);\n prevValueRef.current = props.value as string;\n }\n }, [props.value]);\n\n useEffect(() => {\n if (internalRef.current) {\n internalRef.current.setCustomValidity(props.errorText || '');\n }\n }, [props.errorText]);\n\n const handleFocus = (e: React.FocusEvent<HTMLInputElement>) => {\n setTouched(true);\n if (props.onFocus) {\n props.onFocus(e);\n }\n };\n\n const onChangeHandler = (e: React.ChangeEvent<HTMLInputElement>) => {\n if (props.onChange) {\n setValue(e.target.value);\n props.onChange(e);\n } else {\n setValue(e.target.value);\n }\n };\n\n return (\n <Label>\n <TextField\n {...props}\n ref={internalRef}\n value={value}\n onChange={onChangeHandler}\n onFocus={handleFocus}\n touched={touched}\n aria-invalid={!!props.errorText}\n aria-required={props.required}\n aria-describedby={props.errorText ? errorId : undefined}\n />\n <span>{props.label}</span>\n {props.errorText && <ErrorContainer id={errorId}>{props.errorText}</ErrorContainer>}\n </Label>\n );\n});\n\nInput.displayName = 'Input';\nexport default Input;\n"],"names":["Label","styled","TextField","getThemeValue","THEME_NAME","BORDER_COLOR","BACKGROUND","PRIMARY","PRIMARY_LIGHT","DISABLED_BORDER","DISABLED_BACKGROUND","DISABLED","ERROR","ERROR_LIGHT","props","touched","errorText","value","ErrorContainer","Input","React","forwardRef","forwardedRef","setTouched","useState","setValue","errorId","useId","prevValueRef","useRef","undefined","internalRef","useImperativeHandle","current","useEffect","setCustomValidity","handleFocus","e","onFocus","onChangeHandler","onChange","target","_jsxs","_jsx","ref","aria-invalid","aria-required","required","aria-describedby","span","label","id","displayName"],"mappings":"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"}
@@ -2,5 +2,7 @@ import React from 'react';
2
2
  declare const Radio: React.ForwardRefExoticComponent<{
3
3
  /** Label for the field */
4
4
  label?: string;
5
+ /** Error text to be shown below the field */
6
+ errorText?: string;
5
7
  } & React.InputHTMLAttributes<HTMLInputElement> & React.RefAttributes<HTMLInputElement>>;
6
8
  export default Radio;
@@ -1,32 +1,44 @@
1
1
  import { jsxs, jsx } from '@emotion/react/jsx-runtime';
2
- import React from 'react';
2
+ import React, { useRef, useId, useImperativeHandle, useEffect } from 'react';
3
3
  import styled from '@emotion/styled';
4
4
  import { getThemeValue, THEME_NAME } from '../../shared/constants.js';
5
5
 
6
6
  const Label$1 = /*#__PURE__*/ styled("label", {
7
- target: "e12cx2u30",
7
+ target: "edovkv60",
8
8
  label: "Label"
9
- })("display:inline-flex;align-items:center;margin:5px 0;cursor:pointer;position:relative;");
9
+ })("display:inline-flex;align-items:center;margin:5px 10px 5px 0;cursor:pointer;position:relative;");
10
10
  const StyledRadio = /*#__PURE__*/ styled("span", {
11
- target: "e12cx2u31",
11
+ target: "edovkv61",
12
12
  label: "StyledRadio"
13
13
  })("width:16px;height:16px;margin-right:5px;border:1px solid ", getThemeValue(THEME_NAME.BORDER_COLOR), ";border-radius:50%;display:block;transition:background-color 0.3s ease;position:relative;flex-shrink:0;&::after{content:'';width:100%;height:100%;border-radius:50%;position:absolute;top:0;left:0;box-shadow:inset 0 0 0 3px ", getThemeValue(THEME_NAME.BACKGROUND), ";opacity:0;transition:opacity 0.2s ease;}");
14
14
  const HiddenInput = /*#__PURE__*/ styled("input", {
15
- target: "e12cx2u32",
15
+ target: "edovkv62",
16
16
  label: "HiddenInput"
17
17
  })("opacity:0;width:0;height:0;position:absolute;margin:0;&:checked + ", StyledRadio, "{border-color:", getThemeValue(THEME_NAME.PRIMARY), ";background-color:", getThemeValue(THEME_NAME.PRIMARY), ";}&:checked + ", StyledRadio, "::after{opacity:1;}&:enabled:focus + ", StyledRadio, "{border-color:", getThemeValue(THEME_NAME.PRIMARY), ";box-shadow:0 0 0 3px ", getThemeValue(THEME_NAME.PRIMARY_LIGHT), ";}&:enabled:checked:focus + ", StyledRadio, "{border-color:", getThemeValue(THEME_NAME.PRIMARY), ";box-shadow:0 0 0 3px ", getThemeValue(THEME_NAME.PRIMARY_LIGHT), ";}&:enabled:hover + ", StyledRadio, "{border-color:", getThemeValue(THEME_NAME.PRIMARY), ";}&:enabled:hover ~ span{color:", getThemeValue(THEME_NAME.PRIMARY), ";}&:disabled + ", StyledRadio, "{border-color:", getThemeValue(THEME_NAME.DISABLED_BORDER), ";background-color:", getThemeValue(THEME_NAME.LIGHT_GREY), ";cursor:not-allowed;}&:disabled:checked + ", StyledRadio, "{border-color:", getThemeValue(THEME_NAME.DISABLED_BORDER), ";background-color:", getThemeValue(THEME_NAME.DISABLED_BORDER), ";}&:disabled ~ span{color:", getThemeValue(THEME_NAME.DISABLED_BORDER), ";cursor:not-allowed;}");
18
18
  /**
19
19
  * Radio Component
20
20
  * @param props - Component props
21
- * @param ref - Ref forwarded to the underlying HTMLInputElement
22
- */ function RadioComponent(props, ref) {
23
- const { label, ...rest } = props;
21
+ * @param forwardedRef - Ref forwarded to the underlying HTMLInputElement
22
+ */ function RadioComponent(props, forwardedRef) {
23
+ const { label, errorText, ...rest } = props;
24
+ const internalRef = useRef(null);
25
+ const errorId = useId();
26
+ useImperativeHandle(forwardedRef, ()=>internalRef.current);
27
+ useEffect(()=>{
28
+ if (internalRef.current) {
29
+ internalRef.current.setCustomValidity(errorText || '');
30
+ }
31
+ }, [
32
+ errorText
33
+ ]);
24
34
  return /*#__PURE__*/ jsxs(Label$1, {
25
35
  children: [
26
36
  /*#__PURE__*/ jsx(HiddenInput, {
27
37
  ...rest,
28
- ref: ref,
29
- type: "radio"
38
+ ref: internalRef,
39
+ type: "radio",
40
+ "aria-invalid": !!errorText,
41
+ "aria-describedby": errorText ? errorId : undefined
30
42
  }),
31
43
  /*#__PURE__*/ jsx(StyledRadio, {}),
32
44
  /*#__PURE__*/ jsx("span", {
@@ -1 +1 @@
1
- {"version":3,"file":"Radio.js","sources":["../../../src/components/Input/Radio.tsx"],"sourcesContent":["import React from 'react';\nimport styled from '@emotion/styled';\nimport { getThemeValue, THEME_NAME } from '../../shared/constants';\n\nconst Label = styled.label`\n display: inline-flex;\n align-items: center;\n margin: 5px 0;\n cursor: pointer;\n position: relative;\n`;\n\nconst StyledRadio = styled.span`\n width: 16px;\n height: 16px;\n margin-right: 5px;\n border: 1px solid ${getThemeValue(THEME_NAME.BORDER_COLOR)};\n border-radius: 50%;\n display: block;\n transition: background-color 0.3s ease;\n position: relative;\n flex-shrink: 0;\n\n &::after {\n content: '';\n width: 100%;\n height: 100%;\n border-radius: 50%;\n position: absolute;\n top: 0;\n left: 0;\n box-shadow: inset 0 0 0 3px ${getThemeValue(THEME_NAME.BACKGROUND)};\n opacity: 0;\n transition: opacity 0.2s ease;\n }\n`;\n\nconst HiddenInput = styled.input`\n opacity: 0;\n width: 0;\n height: 0;\n position: absolute;\n margin: 0;\n\n /* checked */\n &:checked + ${StyledRadio} {\n border-color: ${getThemeValue(THEME_NAME.PRIMARY)};\n background-color: ${getThemeValue(THEME_NAME.PRIMARY)};\n }\n\n &:checked + ${StyledRadio}::after {\n opacity: 1;\n }\n\n /* focus */\n &:enabled:focus + ${StyledRadio} {\n border-color: ${getThemeValue(THEME_NAME.PRIMARY)};\n box-shadow: 0 0 0 3px ${getThemeValue(THEME_NAME.PRIMARY_LIGHT)};\n }\n\n &:enabled:checked:focus + ${StyledRadio} {\n border-color: ${getThemeValue(THEME_NAME.PRIMARY)};\n box-shadow: 0 0 0 3px ${getThemeValue(THEME_NAME.PRIMARY_LIGHT)};\n }\n\n /* hover */\n &:enabled:hover + ${StyledRadio} {\n border-color: ${getThemeValue(THEME_NAME.PRIMARY)};\n }\n\n &:enabled:hover ~ span {\n color: ${getThemeValue(THEME_NAME.PRIMARY)};\n }\n\n /* disabled */\n &:disabled + ${StyledRadio} {\n border-color: ${getThemeValue(THEME_NAME.DISABLED_BORDER)};\n background-color: ${getThemeValue(THEME_NAME.LIGHT_GREY)};\n cursor: not-allowed;\n }\n\n &:disabled:checked + ${StyledRadio} {\n border-color: ${getThemeValue(THEME_NAME.DISABLED_BORDER)};\n background-color: ${getThemeValue(THEME_NAME.DISABLED_BORDER)};\n }\n\n &:disabled ~ span {\n color: ${getThemeValue(THEME_NAME.DISABLED_BORDER)};\n cursor: not-allowed;\n }\n`;\n\ntype RadioProps = {\n /** Label for the field */\n label?: string;\n} & React.InputHTMLAttributes<HTMLInputElement>;\n\n/**\n * Radio Component\n * @param props - Component props\n * @param ref - Ref forwarded to the underlying HTMLInputElement\n */\nfunction RadioComponent(props: RadioProps, ref: React.Ref<HTMLInputElement>) {\n const { label, ...rest } = props;\n\n return (\n <Label>\n <HiddenInput {...rest} ref={ref} type=\"radio\" />\n <StyledRadio />\n <span>{label}</span>\n </Label>\n );\n}\n\nconst Radio = React.forwardRef<HTMLInputElement, RadioProps>(RadioComponent);\nexport default Radio;\n"],"names":["Label","styled","StyledRadio","getThemeValue","THEME_NAME","BORDER_COLOR","BACKGROUND","HiddenInput","PRIMARY","PRIMARY_LIGHT","DISABLED_BORDER","LIGHT_GREY","RadioComponent","props","ref","label","rest","_jsxs","_jsx","type","span","Radio","React","forwardRef"],"mappings":";;;;;AAIA,MAAMA,OAAAA,iBAAQC,MAAAA,CAAAA,OAAAA,EAAAA;;;;AAQd,MAAMC,WAAAA,iBAAcD,MAAAA,CAAAA,MAAAA,EAAAA;;;AAIIE,CAAAA,CAAAA,CAAAA,2DAAAA,EAAAA,aAAAA,CAAcC,UAAAA,CAAWC,YAAY,CAAA,EAAA,gOAAA,EAevBF,aAAAA,CAAcC,WAAWE,UAAU,CAAA,EAAA,2CAAA,CAAA;AAMzE,MAAMC,WAAAA,iBAAcN,MAAAA,CAAAA,OAAAA,EAAAA;;;yEAQFC,WAAAA,EAAAA,gBAAAA,EACMC,aAAAA,CAAcC,UAAAA,CAAWI,OAAO,CAAA,EAAA,oBAAA,EAC5BL,aAAAA,CAAcC,UAAAA,CAAWI,OAAO,CAAA,EAAA,gBAAA,EAG1CN,WAAAA,EAAAA,uCAAAA,EAKMA,WAAAA,EAAAA,gBAAAA,EACAC,aAAAA,CAAcC,UAAAA,CAAWI,OAAO,6BACxBL,aAAAA,CAAcC,UAAAA,CAAWK,aAAa,CAAA,EAAA,8BAAA,EAGtCP,WAAAA,EAAAA,gBAAAA,EACRC,aAAAA,CAAcC,UAAAA,CAAWI,OAAO,CAAA,EAAA,wBAAA,EACxBL,aAAAA,CAAcC,UAAAA,CAAWK,aAAa,CAAA,EAAA,sBAAA,EAI9CP,WAAAA,EAAAA,gBAAAA,EACAC,cAAcC,UAAAA,CAAWI,OAAO,CAAA,EAAA,iCAAA,EAIvCL,aAAAA,CAAcC,UAAAA,CAAWI,OAAO,CAAA,EAAA,iBAAA,EAI9BN,WAAAA,EAAAA,gBAAAA,EACKC,aAAAA,CAAcC,UAAAA,CAAWM,eAAe,CAAA,EAAA,oBAAA,EACpCP,aAAAA,CAAcC,UAAAA,CAAWO,UAAU,CAAA,EAAA,4CAAA,EAIpCT,WAAAA,EAAAA,gBAAAA,EACHC,aAAAA,CAAcC,UAAAA,CAAWM,eAAe,CAAA,EAAA,oBAAA,EACpCP,aAAAA,CAAcC,UAAAA,CAAWM,eAAe,CAAA,EAAA,4BAAA,EAInDP,aAAAA,CAAcC,UAAAA,CAAWM,eAAe,CAAA,EAAA,uBAAA,CAAA;AAUzD;;;;AAIC,IACD,SAASE,cAAAA,CAAeC,KAAiB,EAAEC,GAAgC,EAAA;AACvE,IAAA,MAAM,EAAEC,KAAK,EAAE,GAAGC,MAAM,GAAGH,KAAAA;AAE3B,IAAA,qBACII,IAAA,CAACjB,OAAAA,EAAAA;;0BACGkB,GAAA,CAACX,WAAAA,EAAAA;AAAa,gBAAA,GAAGS,IAAI;gBAAEF,GAAAA,EAAKA,GAAAA;gBAAKK,IAAAA,EAAK;;0BACtCD,GAAA,CAAChB,WAAAA,EAAAA,EAAAA,CAAAA;0BACDgB,GAAA,CAACE,MAAAA,EAAAA;AAAML,gBAAAA,QAAAA,EAAAA;;;;AAGnB;AAEA,MAAMM,KAAAA,iBAAQC,KAAAA,CAAMC,UAAU,CAA+BX,cAAAA;;;;"}
1
+ {"version":3,"file":"Radio.js","sources":["../../../src/components/Input/Radio.tsx"],"sourcesContent":["import React, { useEffect, useId, useRef, useImperativeHandle } from 'react';\nimport styled from '@emotion/styled';\nimport { getThemeValue, THEME_NAME } from '../../shared/constants';\n\nconst Label = styled.label`\n display: inline-flex;\n align-items: center;\n margin: 5px 10px 5px 0;\n cursor: pointer;\n position: relative;\n`;\n\nconst StyledRadio = styled.span`\n width: 16px;\n height: 16px;\n margin-right: 5px;\n border: 1px solid ${getThemeValue(THEME_NAME.BORDER_COLOR)};\n border-radius: 50%;\n display: block;\n transition: background-color 0.3s ease;\n position: relative;\n flex-shrink: 0;\n\n &::after {\n content: '';\n width: 100%;\n height: 100%;\n border-radius: 50%;\n position: absolute;\n top: 0;\n left: 0;\n box-shadow: inset 0 0 0 3px ${getThemeValue(THEME_NAME.BACKGROUND)};\n opacity: 0;\n transition: opacity 0.2s ease;\n }\n`;\n\nconst HiddenInput = styled.input`\n opacity: 0;\n width: 0;\n height: 0;\n position: absolute;\n margin: 0;\n\n /* checked */\n &:checked + ${StyledRadio} {\n border-color: ${getThemeValue(THEME_NAME.PRIMARY)};\n background-color: ${getThemeValue(THEME_NAME.PRIMARY)};\n }\n\n &:checked + ${StyledRadio}::after {\n opacity: 1;\n }\n\n /* focus */\n &:enabled:focus + ${StyledRadio} {\n border-color: ${getThemeValue(THEME_NAME.PRIMARY)};\n box-shadow: 0 0 0 3px ${getThemeValue(THEME_NAME.PRIMARY_LIGHT)};\n }\n\n &:enabled:checked:focus + ${StyledRadio} {\n border-color: ${getThemeValue(THEME_NAME.PRIMARY)};\n box-shadow: 0 0 0 3px ${getThemeValue(THEME_NAME.PRIMARY_LIGHT)};\n }\n\n /* hover */\n &:enabled:hover + ${StyledRadio} {\n border-color: ${getThemeValue(THEME_NAME.PRIMARY)};\n }\n\n &:enabled:hover ~ span {\n color: ${getThemeValue(THEME_NAME.PRIMARY)};\n }\n\n /* disabled */\n &:disabled + ${StyledRadio} {\n border-color: ${getThemeValue(THEME_NAME.DISABLED_BORDER)};\n background-color: ${getThemeValue(THEME_NAME.LIGHT_GREY)};\n cursor: not-allowed;\n }\n\n &:disabled:checked + ${StyledRadio} {\n border-color: ${getThemeValue(THEME_NAME.DISABLED_BORDER)};\n background-color: ${getThemeValue(THEME_NAME.DISABLED_BORDER)};\n }\n\n &:disabled ~ span {\n color: ${getThemeValue(THEME_NAME.DISABLED_BORDER)};\n cursor: not-allowed;\n }\n`;\n\ntype RadioProps = {\n /** Label for the field */\n label?: string;\n /** Error text to be shown below the field */\n errorText?: string;\n} & React.InputHTMLAttributes<HTMLInputElement>;\n\n/**\n * Radio Component\n * @param props - Component props\n * @param forwardedRef - Ref forwarded to the underlying HTMLInputElement\n */\nfunction RadioComponent(props: RadioProps, forwardedRef: React.Ref<HTMLInputElement>) {\n const { label, errorText, ...rest } = props;\n const internalRef = useRef<HTMLInputElement>(null);\n const errorId = useId();\n\n useImperativeHandle(forwardedRef, () => internalRef.current as HTMLInputElement);\n\n useEffect(() => {\n if (internalRef.current) {\n internalRef.current.setCustomValidity(errorText || '');\n }\n }, [errorText]);\n\n return (\n <Label>\n <HiddenInput\n {...rest}\n ref={internalRef}\n type=\"radio\"\n aria-invalid={!!errorText}\n aria-describedby={errorText ? errorId : undefined}\n />\n <StyledRadio />\n <span>{label}</span>\n </Label>\n );\n}\n\nconst Radio = React.forwardRef<HTMLInputElement, RadioProps>(RadioComponent);\nexport default Radio;\n"],"names":["Label","styled","StyledRadio","getThemeValue","THEME_NAME","BORDER_COLOR","BACKGROUND","HiddenInput","PRIMARY","PRIMARY_LIGHT","DISABLED_BORDER","LIGHT_GREY","RadioComponent","props","forwardedRef","label","errorText","rest","internalRef","useRef","errorId","useId","useImperativeHandle","current","useEffect","setCustomValidity","_jsxs","_jsx","ref","type","aria-invalid","aria-describedby","undefined","span","Radio","React","forwardRef"],"mappings":";;;;;AAIA,MAAMA,OAAAA,iBAAQC,MAAAA,CAAAA,OAAAA,EAAAA;;;;AAQd,MAAMC,WAAAA,iBAAcD,MAAAA,CAAAA,MAAAA,EAAAA;;;AAIIE,CAAAA,CAAAA,CAAAA,2DAAAA,EAAAA,aAAAA,CAAcC,UAAAA,CAAWC,YAAY,CAAA,EAAA,gOAAA,EAevBF,aAAAA,CAAcC,WAAWE,UAAU,CAAA,EAAA,2CAAA,CAAA;AAMzE,MAAMC,WAAAA,iBAAcN,MAAAA,CAAAA,OAAAA,EAAAA;;;yEAQFC,WAAAA,EAAAA,gBAAAA,EACMC,aAAAA,CAAcC,UAAAA,CAAWI,OAAO,CAAA,EAAA,oBAAA,EAC5BL,aAAAA,CAAcC,UAAAA,CAAWI,OAAO,CAAA,EAAA,gBAAA,EAG1CN,WAAAA,EAAAA,uCAAAA,EAKMA,WAAAA,EAAAA,gBAAAA,EACAC,aAAAA,CAAcC,UAAAA,CAAWI,OAAO,6BACxBL,aAAAA,CAAcC,UAAAA,CAAWK,aAAa,CAAA,EAAA,8BAAA,EAGtCP,WAAAA,EAAAA,gBAAAA,EACRC,aAAAA,CAAcC,UAAAA,CAAWI,OAAO,CAAA,EAAA,wBAAA,EACxBL,aAAAA,CAAcC,UAAAA,CAAWK,aAAa,CAAA,EAAA,sBAAA,EAI9CP,WAAAA,EAAAA,gBAAAA,EACAC,cAAcC,UAAAA,CAAWI,OAAO,CAAA,EAAA,iCAAA,EAIvCL,aAAAA,CAAcC,UAAAA,CAAWI,OAAO,CAAA,EAAA,iBAAA,EAI9BN,WAAAA,EAAAA,gBAAAA,EACKC,aAAAA,CAAcC,UAAAA,CAAWM,eAAe,CAAA,EAAA,oBAAA,EACpCP,aAAAA,CAAcC,UAAAA,CAAWO,UAAU,CAAA,EAAA,4CAAA,EAIpCT,WAAAA,EAAAA,gBAAAA,EACHC,aAAAA,CAAcC,UAAAA,CAAWM,eAAe,CAAA,EAAA,oBAAA,EACpCP,aAAAA,CAAcC,UAAAA,CAAWM,eAAe,CAAA,EAAA,4BAAA,EAInDP,aAAAA,CAAcC,UAAAA,CAAWM,eAAe,CAAA,EAAA,uBAAA,CAAA;AAYzD;;;;AAIC,IACD,SAASE,cAAAA,CAAeC,KAAiB,EAAEC,YAAyC,EAAA;AAChF,IAAA,MAAM,EAAEC,KAAK,EAAEC,SAAS,EAAE,GAAGC,MAAM,GAAGJ,KAAAA;AACtC,IAAA,MAAMK,cAAcC,MAAAA,CAAyB,IAAA,CAAA;AAC7C,IAAA,MAAMC,OAAAA,GAAUC,KAAAA,EAAAA;IAEhBC,mBAAAA,CAAoBR,YAAAA,EAAc,IAAMI,WAAAA,CAAYK,OAAO,CAAA;IAE3DC,SAAAA,CAAU,IAAA;QACN,IAAIN,WAAAA,CAAYK,OAAO,EAAE;AACrBL,YAAAA,WAAAA,CAAYK,OAAO,CAACE,iBAAiB,CAACT,SAAAA,IAAa,EAAA,CAAA;AACvD,QAAA;IACJ,CAAA,EAAG;AAACA,QAAAA;AAAU,KAAA,CAAA;AAEd,IAAA,qBACIU,IAAA,CAAC1B,OAAAA,EAAAA;;0BACG2B,GAAA,CAACpB,WAAAA,EAAAA;AACI,gBAAA,GAAGU,IAAI;gBACRW,GAAAA,EAAKV,WAAAA;gBACLW,IAAAA,EAAK,OAAA;AACLC,gBAAAA,cAAAA,EAAc,CAAC,CAACd,SAAAA;AAChBe,gBAAAA,kBAAAA,EAAkBf,YAAYI,OAAAA,GAAUY;;0BAE5CL,GAAA,CAACzB,WAAAA,EAAAA,EAAAA,CAAAA;0BACDyB,GAAA,CAACM,MAAAA,EAAAA;AAAMlB,gBAAAA,QAAAA,EAAAA;;;;AAGnB;AAEA,MAAMmB,KAAAA,iBAAQC,KAAAA,CAAMC,UAAU,CAA+BxB,cAAAA;;;;"}
@@ -6,5 +6,7 @@ export declare const RadioGroup: import("@emotion/styled").StyledComponent<{
6
6
  declare const RadioButton: React.ForwardRefExoticComponent<{
7
7
  /** Label for the field */
8
8
  label?: string;
9
+ /** Error text to be shown below the field */
10
+ errorText?: string;
9
11
  } & React.InputHTMLAttributes<HTMLInputElement> & React.RefAttributes<HTMLInputElement>>;
10
12
  export default RadioButton;
@@ -1,32 +1,44 @@
1
1
  import { jsxs, jsx } from '@emotion/react/jsx-runtime';
2
- import React from 'react';
2
+ import React, { useRef, useId, useImperativeHandle, useEffect } from 'react';
3
3
  import styled from '@emotion/styled';
4
4
  import { getThemeValue, THEME_NAME } from '../../shared/constants.js';
5
5
 
6
6
  const Input = /*#__PURE__*/ styled("input", {
7
- target: "e1yp0s5y0",
7
+ target: "e76n0060",
8
8
  label: "Input"
9
9
  })("appearance:none;margin:0;width:0;& + span{color:", getThemeValue(THEME_NAME.PRIMARY), ";padding:6px 12px;border:none;border:1px solid ", getThemeValue(THEME_NAME.PRIMARY), ";cursor:pointer;margin-right:-1px;line-height:18px;}&:enabled:focus + span{box-shadow:0 0 0 4px ", getThemeValue(THEME_NAME.PRIMARY_LIGHT), ";}&:enabled:hover + span{background-color:", getThemeValue(THEME_NAME.PRIMARY_LIGHT), ";color:", getThemeValue(THEME_NAME.TEXT_COLOR_LIGHT), ";}&:enabled:checked + span{background-color:", getThemeValue(THEME_NAME.PRIMARY), ";color:", getThemeValue(THEME_NAME.TEXT_COLOR_LIGHT), ";}&:disabled + span{background-color:", getThemeValue(THEME_NAME.BORDER_LIGHT_COLOR), ";color:", getThemeValue(THEME_NAME.DISABLED_BORDER), ";}&:disabled:checked + span{background-color:", getThemeValue(THEME_NAME.DISABLED_BORDER), ";color:", getThemeValue(THEME_NAME.TEXT_COLOR_LIGHT), ";}");
10
10
  const Label = /*#__PURE__*/ styled("label", {
11
- target: "e1yp0s5y1",
11
+ target: "e76n0061",
12
12
  label: "Label"
13
13
  })("display:inline-flex;&:focus-within{z-index:1;}");
14
14
  const RadioGroup = /*#__PURE__*/ styled("div", {
15
- target: "e1yp0s5y2",
15
+ target: "e76n0062",
16
16
  label: "RadioGroup"
17
- })("display:inline-flex;align-items:center;border-radius:3px;margin:5px 0;& ", Label, ":first-child > span{border-radius:3px 0 0 3px;}& ", Label, ":last-child > span{border-radius:0 3px 3px 0;}");
17
+ })("display:inline-flex;align-items:center;border-radius:3px;margin:5px 0;& > ", Label, ":first-of-type > span{border-radius:3px 0 0 3px;}& > ", Label, ":last-of-type > span{border-radius:0 3px 3px 0;}");
18
18
  /**
19
19
  * RadioButton Component
20
20
  * @param props - Component props
21
- * @param ref - Ref forwarded to the underlying HTMLInputElement
22
- */ function RadioButtonComponent(props, ref) {
23
- const { label, ...rest } = props;
21
+ * @param forwardedRef - Ref forwarded to the underlying HTMLInputElement
22
+ */ function RadioButtonComponent(props, forwardedRef) {
23
+ const { label, errorText, ...rest } = props;
24
+ const internalRef = useRef(null);
25
+ const errorId = useId();
26
+ useImperativeHandle(forwardedRef, ()=>internalRef.current);
27
+ useEffect(()=>{
28
+ if (internalRef.current) {
29
+ internalRef.current.setCustomValidity(errorText || '');
30
+ }
31
+ }, [
32
+ errorText
33
+ ]);
24
34
  return /*#__PURE__*/ jsxs(Label, {
25
35
  children: [
26
36
  /*#__PURE__*/ jsx(Input, {
27
37
  ...rest,
28
38
  type: "radio",
29
- ref: ref
39
+ ref: internalRef,
40
+ "aria-invalid": !!errorText,
41
+ "aria-describedby": errorText ? errorId : undefined
30
42
  }),
31
43
  /*#__PURE__*/ jsx("span", {
32
44
  children: label
@@ -1 +1 @@
1
- {"version":3,"file":"RadioButton.js","sources":["../../../src/components/Input/RadioButton.tsx"],"sourcesContent":["import React from 'react';\nimport styled from '@emotion/styled';\nimport { getThemeValue, THEME_NAME } from '../../shared/constants';\n\nconst Input = styled.input`\n appearance: none;\n margin: 0;\n width: 0;\n\n & + span {\n color: ${getThemeValue(THEME_NAME.PRIMARY)};\n padding: 6px 12px;\n border: none;\n border: 1px solid ${getThemeValue(THEME_NAME.PRIMARY)};\n cursor: pointer;\n margin-right: -1px;\n line-height: 18px;\n }\n\n &:enabled:focus + span {\n box-shadow: 0 0 0 4px ${getThemeValue(THEME_NAME.PRIMARY_LIGHT)};\n }\n\n &:enabled:hover + span {\n background-color: ${getThemeValue(THEME_NAME.PRIMARY_LIGHT)};\n color: ${getThemeValue(THEME_NAME.TEXT_COLOR_LIGHT)};\n }\n\n &:enabled:checked + span {\n background-color: ${getThemeValue(THEME_NAME.PRIMARY)};\n color: ${getThemeValue(THEME_NAME.TEXT_COLOR_LIGHT)};\n }\n\n &:disabled + span {\n background-color: ${getThemeValue(THEME_NAME.BORDER_LIGHT_COLOR)};\n color: ${getThemeValue(THEME_NAME.DISABLED_BORDER)};\n }\n\n &:disabled:checked + span {\n background-color: ${getThemeValue(THEME_NAME.DISABLED_BORDER)};\n color: ${getThemeValue(THEME_NAME.TEXT_COLOR_LIGHT)};\n }\n`;\n\nconst Label = styled.label`\n display: inline-flex;\n\n &:focus-within {\n z-index: 1;\n }\n`;\n\nexport const RadioGroup = styled.div`\n display: inline-flex;\n align-items: center;\n border-radius: 3px;\n margin: 5px 0;\n\n & ${Label}:first-child > span {\n border-radius: 3px 0 0 3px;\n }\n\n & ${Label}:last-child > span {\n border-radius: 0 3px 3px 0;\n }\n`;\n\ntype RadioButtonProps = {\n /** Label for the field */\n label?: string;\n} & React.InputHTMLAttributes<HTMLInputElement>;\n\n/**\n * RadioButton Component\n * @param props - Component props\n * @param ref - Ref forwarded to the underlying HTMLInputElement\n */\nfunction RadioButtonComponent(props: RadioButtonProps, ref: React.Ref<HTMLInputElement>) {\n const { label, ...rest } = props;\n return (\n <Label>\n <Input {...rest} type=\"radio\" ref={ref} />\n <span>{label}</span>\n </Label>\n );\n}\n\nconst RadioButton = React.forwardRef(RadioButtonComponent);\nexport default RadioButton;\n"],"names":["Input","styled","getThemeValue","THEME_NAME","PRIMARY","PRIMARY_LIGHT","TEXT_COLOR_LIGHT","BORDER_LIGHT_COLOR","DISABLED_BORDER","Label","RadioGroup","RadioButtonComponent","props","ref","label","rest","_jsxs","_jsx","type","span","RadioButton","React","forwardRef"],"mappings":";;;;;AAIA,MAAMA,KAAAA,iBAAQC,MAAAA,CAAAA,OAAAA,EAAAA;;;AAMGC,CAAAA,CAAAA,CAAAA,kDAAAA,EAAAA,aAAAA,CAAcC,WAAWC,OAAO,CAAA,EAAA,iDAAA,EAGrBF,cAAcC,UAAAA,CAAWC,OAAO,uGAO5BF,aAAAA,CAAcC,UAAAA,CAAWE,aAAa,CAAA,EAAA,4CAAA,EAI1CH,cAAcC,UAAAA,CAAWE,aAAa,cACjDH,aAAAA,CAAcC,UAAAA,CAAWG,gBAAgB,CAAA,EAAA,8CAAA,EAI9BJ,aAAAA,CAAcC,UAAAA,CAAWC,OAAO,cAC3CF,aAAAA,CAAcC,UAAAA,CAAWG,gBAAgB,CAAA,EAAA,uCAAA,EAI9BJ,aAAAA,CAAcC,WAAWI,kBAAkB,CAAA,EAAA,SAAA,EACtDL,cAAcC,UAAAA,CAAWK,eAAe,oDAI7BN,aAAAA,CAAcC,UAAAA,CAAWK,eAAe,CAAA,EAAA,SAAA,EACnDN,aAAAA,CAAcC,WAAWG,gBAAgB,CAAA,EAAA,IAAA,CAAA;AAI1D,MAAMG,KAAAA,iBAAQR,MAAAA,CAAAA,OAAAA,EAAAA;;;;MAQDS,UAAAA,iBAAaT,MAAAA,CAAAA,KAAAA,EAAAA;;;AAMlBQ,CAAAA,CAAAA,CAAAA,0EAAAA,EAAAA,KAAAA,EAAAA,mDAAAA,EAIAA,KAAAA,EAAAA,gDAAAA;AAUR;;;;AAIC,IACD,SAASE,oBAAAA,CAAqBC,KAAuB,EAAEC,GAAgC,EAAA;AACnF,IAAA,MAAM,EAAEC,KAAK,EAAE,GAAGC,MAAM,GAAGH,KAAAA;AAC3B,IAAA,qBACII,IAAA,CAACP,KAAAA,EAAAA;;0BACGQ,GAAA,CAACjB,KAAAA,EAAAA;AAAO,gBAAA,GAAGe,IAAI;gBAAEG,IAAAA,EAAK,OAAA;gBAAQL,GAAAA,EAAKA;;0BACnCI,GAAA,CAACE,MAAAA,EAAAA;AAAML,gBAAAA,QAAAA,EAAAA;;;;AAGnB;AAEA,MAAMM,WAAAA,iBAAcC,KAAAA,CAAMC,UAAU,CAACX,oBAAAA;;;;"}
1
+ {"version":3,"file":"RadioButton.js","sources":["../../../src/components/Input/RadioButton.tsx"],"sourcesContent":["import React, { useEffect, useId, useRef, useImperativeHandle } from 'react';\nimport styled from '@emotion/styled';\nimport { getThemeValue, THEME_NAME } from '../../shared/constants';\n\nconst Input = styled.input`\n appearance: none;\n margin: 0;\n width: 0;\n\n & + span {\n color: ${getThemeValue(THEME_NAME.PRIMARY)};\n padding: 6px 12px;\n border: none;\n border: 1px solid ${getThemeValue(THEME_NAME.PRIMARY)};\n cursor: pointer;\n margin-right: -1px;\n line-height: 18px;\n }\n\n &:enabled:focus + span {\n box-shadow: 0 0 0 4px ${getThemeValue(THEME_NAME.PRIMARY_LIGHT)};\n }\n\n &:enabled:hover + span {\n background-color: ${getThemeValue(THEME_NAME.PRIMARY_LIGHT)};\n color: ${getThemeValue(THEME_NAME.TEXT_COLOR_LIGHT)};\n }\n\n &:enabled:checked + span {\n background-color: ${getThemeValue(THEME_NAME.PRIMARY)};\n color: ${getThemeValue(THEME_NAME.TEXT_COLOR_LIGHT)};\n }\n\n &:disabled + span {\n background-color: ${getThemeValue(THEME_NAME.BORDER_LIGHT_COLOR)};\n color: ${getThemeValue(THEME_NAME.DISABLED_BORDER)};\n }\n\n &:disabled:checked + span {\n background-color: ${getThemeValue(THEME_NAME.DISABLED_BORDER)};\n color: ${getThemeValue(THEME_NAME.TEXT_COLOR_LIGHT)};\n }\n`;\n\nconst Label = styled.label`\n display: inline-flex;\n\n &:focus-within {\n z-index: 1;\n }\n`;\n\nexport const RadioGroup = styled.div`\n display: inline-flex;\n align-items: center;\n border-radius: 3px;\n margin: 5px 0;\n\n & > ${Label}:first-of-type > span {\n border-radius: 3px 0 0 3px;\n }\n\n & > ${Label}:last-of-type > span {\n border-radius: 0 3px 3px 0;\n }\n`;\n\ntype RadioButtonProps = {\n /** Label for the field */\n label?: string;\n /** Error text to be shown below the field */\n errorText?: string;\n} & React.InputHTMLAttributes<HTMLInputElement>;\n\n/**\n * RadioButton Component\n * @param props - Component props\n * @param forwardedRef - Ref forwarded to the underlying HTMLInputElement\n */\nfunction RadioButtonComponent(props: RadioButtonProps, forwardedRef: React.Ref<HTMLInputElement>) {\n const { label, errorText, ...rest } = props;\n const internalRef = useRef<HTMLInputElement>(null);\n const errorId = useId();\n\n useImperativeHandle(forwardedRef, () => internalRef.current as HTMLInputElement);\n\n useEffect(() => {\n if (internalRef.current) {\n internalRef.current.setCustomValidity(errorText || '');\n }\n }, [errorText]);\n\n return (\n <Label>\n <Input\n {...rest}\n type=\"radio\"\n ref={internalRef}\n aria-invalid={!!errorText}\n aria-describedby={errorText ? errorId : undefined}\n />\n <span>{label}</span>\n </Label>\n );\n}\n\nconst RadioButton = React.forwardRef(RadioButtonComponent);\nexport default RadioButton;\n"],"names":["Input","styled","getThemeValue","THEME_NAME","PRIMARY","PRIMARY_LIGHT","TEXT_COLOR_LIGHT","BORDER_LIGHT_COLOR","DISABLED_BORDER","Label","RadioGroup","RadioButtonComponent","props","forwardedRef","label","errorText","rest","internalRef","useRef","errorId","useId","useImperativeHandle","current","useEffect","setCustomValidity","_jsxs","_jsx","type","ref","aria-invalid","aria-describedby","undefined","span","RadioButton","React","forwardRef"],"mappings":";;;;;AAIA,MAAMA,KAAAA,iBAAQC,MAAAA,CAAAA,OAAAA,EAAAA;;;AAMGC,CAAAA,CAAAA,CAAAA,kDAAAA,EAAAA,aAAAA,CAAcC,WAAWC,OAAO,CAAA,EAAA,iDAAA,EAGrBF,cAAcC,UAAAA,CAAWC,OAAO,uGAO5BF,aAAAA,CAAcC,UAAAA,CAAWE,aAAa,CAAA,EAAA,4CAAA,EAI1CH,cAAcC,UAAAA,CAAWE,aAAa,cACjDH,aAAAA,CAAcC,UAAAA,CAAWG,gBAAgB,CAAA,EAAA,8CAAA,EAI9BJ,aAAAA,CAAcC,UAAAA,CAAWC,OAAO,cAC3CF,aAAAA,CAAcC,UAAAA,CAAWG,gBAAgB,CAAA,EAAA,uCAAA,EAI9BJ,aAAAA,CAAcC,WAAWI,kBAAkB,CAAA,EAAA,SAAA,EACtDL,cAAcC,UAAAA,CAAWK,eAAe,oDAI7BN,aAAAA,CAAcC,UAAAA,CAAWK,eAAe,CAAA,EAAA,SAAA,EACnDN,aAAAA,CAAcC,WAAWG,gBAAgB,CAAA,EAAA,IAAA,CAAA;AAI1D,MAAMG,KAAAA,iBAAQR,MAAAA,CAAAA,OAAAA,EAAAA;;;;MAQDS,UAAAA,iBAAaT,MAAAA,CAAAA,KAAAA,EAAAA;;;AAMhBQ,CAAAA,CAAAA,CAAAA,4EAAAA,EAAAA,KAAAA,EAAAA,uDAAAA,EAIAA,KAAAA,EAAAA,kDAAAA;AAYV;;;;AAIC,IACD,SAASE,oBAAAA,CAAqBC,KAAuB,EAAEC,YAAyC,EAAA;AAC5F,IAAA,MAAM,EAAEC,KAAK,EAAEC,SAAS,EAAE,GAAGC,MAAM,GAAGJ,KAAAA;AACtC,IAAA,MAAMK,cAAcC,MAAAA,CAAyB,IAAA,CAAA;AAC7C,IAAA,MAAMC,OAAAA,GAAUC,KAAAA,EAAAA;IAEhBC,mBAAAA,CAAoBR,YAAAA,EAAc,IAAMI,WAAAA,CAAYK,OAAO,CAAA;IAE3DC,SAAAA,CAAU,IAAA;QACN,IAAIN,WAAAA,CAAYK,OAAO,EAAE;AACrBL,YAAAA,WAAAA,CAAYK,OAAO,CAACE,iBAAiB,CAACT,SAAAA,IAAa,EAAA,CAAA;AACvD,QAAA;IACJ,CAAA,EAAG;AAACA,QAAAA;AAAU,KAAA,CAAA;AAEd,IAAA,qBACIU,IAAA,CAAChB,KAAAA,EAAAA;;0BACGiB,GAAA,CAAC1B,KAAAA,EAAAA;AACI,gBAAA,GAAGgB,IAAI;gBACRW,IAAAA,EAAK,OAAA;gBACLC,GAAAA,EAAKX,WAAAA;AACLY,gBAAAA,cAAAA,EAAc,CAAC,CAACd,SAAAA;AAChBe,gBAAAA,kBAAAA,EAAkBf,YAAYI,OAAAA,GAAUY;;0BAE5CL,GAAA,CAACM,MAAAA,EAAAA;AAAMlB,gBAAAA,QAAAA,EAAAA;;;;AAGnB;AAEA,MAAMmB,WAAAA,iBAAcC,KAAAA,CAAMC,UAAU,CAACxB,oBAAAA;;;;"}
@@ -1,15 +1,15 @@
1
1
  import { jsxs, jsx } from '@emotion/react/jsx-runtime';
2
- import React, { useState, useId, useRef, useEffect } from 'react';
2
+ import React, { useState, useId, useRef, useImperativeHandle, useEffect } from 'react';
3
3
  import styled from '@emotion/styled';
4
4
  import ExpandMore from '../../icons/ExpandMore.js';
5
5
  import { getThemeValue, THEME_NAME } from '../../shared/constants.js';
6
6
 
7
7
  const Label$3 = /*#__PURE__*/ styled("label", {
8
- target: "e13b7jm0",
8
+ target: "e1trg58l0",
9
9
  label: "Label"
10
10
  })("display:inline-flex;flex-direction:column;position:relative;margin:10px 5px;pointer-events:none;max-width:268px;& svg{fill:currentColor;}");
11
11
  const SelectField = /*#__PURE__*/ styled("select", {
12
- target: "e13b7jm1",
12
+ target: "e1trg58l1",
13
13
  label: "SelectField"
14
14
  })("border:none;color:inherit;padding:0 8px;line-height:30px;min-height:32px;width:268px;border-radius:3px;border:1px solid ", getThemeValue(THEME_NAME.BORDER_COLOR), ";display:inline-block;background-color:", getThemeValue(THEME_NAME.BACKGROUND), ";pointer-events:auto;appearance:none;&:focus,&:active{border-color:", getThemeValue(THEME_NAME.PRIMARY), ";box-shadow:0 0 0 4px ", getThemeValue(THEME_NAME.PRIMARY_LIGHT), ";}&:focus ~ span,&:active ~ span{color:", getThemeValue(THEME_NAME.PRIMARY), ";}&:disabled{border-color:", getThemeValue(THEME_NAME.DISABLED_BORDER), ";background-color:", getThemeValue(THEME_NAME.DISABLED_BACKGROUND), ";}&:disabled ~ span{color:", getThemeValue(THEME_NAME.DISABLED), ";}&:focus:invalid{border-color:", getThemeValue(THEME_NAME.ERROR), ";box-shadow:0 0 0 4px ", getThemeValue(THEME_NAME.ERROR_LIGHT), ";}", (props)=>props.touched ? `
15
15
  &:invalid {
@@ -33,31 +33,41 @@ const SelectField = /*#__PURE__*/ styled("select", {
33
33
  line-height: 14px;
34
34
  }
35
35
  ` : '', " &:focus + span,&:placeholder-shown + span{top:-8px;background:", getThemeValue(THEME_NAME.BACKGROUND), ";font-size:12px;line-height:14px;}");
36
- const ErrorContainer$1 = /*#__PURE__*/ styled("div", {
37
- target: "e13b7jm2",
36
+ const ErrorContainer$3 = /*#__PURE__*/ styled("div", {
37
+ target: "e1trg58l2",
38
38
  label: "ErrorContainer"
39
39
  })("color:", getThemeValue(THEME_NAME.ERROR), ";padding-top:3px;font-size:12px;line-height:14px;margin-left:3px;");
40
40
  const ArrowContainer$1 = /*#__PURE__*/ styled("span", {
41
- target: "e13b7jm3",
41
+ target: "e1trg58l3",
42
42
  label: "ArrowContainer"
43
43
  })("position:absolute;right:8px;top:8px;");
44
44
  /**
45
45
  * Select Component
46
46
  * @param props - Component props
47
47
  * @param ref - Ref forwarded to the underlying HTMLSelectElement
48
- */ function SelectComponent(props, ref) {
48
+ */ function SelectComponent(props, forwardedRef) {
49
49
  const [touched, setTouched] = useState(false);
50
50
  const [value, setValue] = useState(props.value || '');
51
51
  const errorId = useId();
52
52
  const prevValueRef = useRef(undefined);
53
+ const internalRef = useRef(null);
54
+ useImperativeHandle(forwardedRef, ()=>internalRef.current);
55
+ // Sync prop value with state
53
56
  useEffect(()=>{
54
- if (props.value !== undefined && props.value !== prevValueRef.current) {
55
- setValue(props.value);
57
+ if (props.value !== prevValueRef.current) {
58
+ setValue(props.value || '');
56
59
  prevValueRef.current = props.value;
57
60
  }
58
61
  }, [
59
62
  props.value
60
63
  ]);
64
+ useEffect(()=>{
65
+ if (internalRef.current) {
66
+ internalRef.current.setCustomValidity(props.errorText || '');
67
+ }
68
+ }, [
69
+ props.errorText
70
+ ]);
61
71
  const handleFocus = (e)=>{
62
72
  setTouched(true);
63
73
  if (props.onFocus) {
@@ -76,7 +86,7 @@ const ArrowContainer$1 = /*#__PURE__*/ styled("span", {
76
86
  children: [
77
87
  /*#__PURE__*/ jsxs(SelectField, {
78
88
  ...props,
79
- ref: ref,
89
+ ref: internalRef,
80
90
  multiple: false,
81
91
  value: value,
82
92
  onChange: onChangeHandler,
@@ -97,7 +107,7 @@ const ArrowContainer$1 = /*#__PURE__*/ styled("span", {
97
107
  "aria-hidden": "true",
98
108
  children: /*#__PURE__*/ jsx(ExpandMore, {})
99
109
  }),
100
- props.errorText && /*#__PURE__*/ jsx(ErrorContainer$1, {
110
+ props.errorText && /*#__PURE__*/ jsx(ErrorContainer$3, {
101
111
  id: errorId,
102
112
  children: props.errorText
103
113
  })
@@ -1 +1 @@
1
- {"version":3,"file":"Select.js","sources":["../../../src/components/Input/Select.tsx"],"sourcesContent":["import React, { useState, useEffect, useId, useRef } from 'react';\nimport styled from '@emotion/styled';\nimport ExpandMore from '../../icons/ExpandMore';\nimport { getThemeValue, THEME_NAME } from '../../shared/constants';\n\ntype SelectProps = {\n /** Label for the field */\n label?: string;\n /** Error text to be shown below the field */\n errorText?: string;\n} & React.InputHTMLAttributes<HTMLSelectElement>;\n\ntype SelectInternalProps = SelectProps & {\n touched: boolean;\n};\n\nconst Label = styled.label`\n display: inline-flex;\n flex-direction: column;\n position: relative;\n margin: 10px 5px;\n pointer-events: none;\n max-width: 268px;\n\n & svg {\n fill: currentColor;\n }\n`;\n\nconst SelectField = styled.select<SelectInternalProps>`\n border: none;\n color: inherit;\n padding: 0 8px;\n line-height: 30px;\n min-height: 32px;\n width: 268px;\n border-radius: 3px;\n border: 1px solid ${getThemeValue(THEME_NAME.BORDER_COLOR)};\n display: inline-block;\n background-color: ${getThemeValue(THEME_NAME.BACKGROUND)};\n pointer-events: auto;\n appearance: none;\n\n /** Focused */\n &:focus,\n &:active {\n border-color: ${getThemeValue(THEME_NAME.PRIMARY)};\n box-shadow: 0 0 0 4px ${getThemeValue(THEME_NAME.PRIMARY_LIGHT)};\n }\n\n &:focus ~ span,\n &:active ~ span {\n color: ${getThemeValue(THEME_NAME.PRIMARY)};\n }\n\n /** Disabled */\n &:disabled {\n border-color: ${getThemeValue(THEME_NAME.DISABLED_BORDER)};\n background-color: ${getThemeValue(THEME_NAME.DISABLED_BACKGROUND)};\n }\n\n &:disabled ~ span {\n color: ${getThemeValue(THEME_NAME.DISABLED)};\n }\n\n /** Invalid */\n &:focus:invalid {\n border-color: ${getThemeValue(THEME_NAME.ERROR)};\n box-shadow: 0 0 0 4px ${getThemeValue(THEME_NAME.ERROR_LIGHT)};\n }\n\n ${(props) =>\n props.touched\n ? `\n &:invalid {\n border-color: ${getThemeValue(THEME_NAME.ERROR)};\n }\n\n &:invalid ~ span {\n color: ${getThemeValue(THEME_NAME.ERROR)};\n }\n `\n : ''}\n\n /** Error */\n ${(props) =>\n props.errorText\n ? `\n border-color: ${getThemeValue(THEME_NAME.ERROR)};\n\n & ~ span {\n color: ${getThemeValue(THEME_NAME.ERROR)};\n }\n `\n : ''}\n\n /** Required */\n &:required + span:after {\n content: '*';\n margin-left: 2px;\n color: ${getThemeValue(THEME_NAME.ERROR)};\n }\n\n /** Label Animation */\n & + span {\n position: absolute;\n padding: 0 5px;\n top: 0px;\n left: 4px;\n font-size: 14px;\n line-height: 32px;\n transition: all 300ms ease;\n }\n\n ${(props) =>\n props.value !== ''\n ? `\n & + span {\n top: -8px;\n background: ${getThemeValue(THEME_NAME.BACKGROUND)};\n font-size: 12px;\n line-height: 14px;\n }\n `\n : ''}\n\n &:focus + span, &:placeholder-shown + span {\n top: -8px;\n background: ${getThemeValue(THEME_NAME.BACKGROUND)};\n font-size: 12px;\n line-height: 14px;\n }\n`;\n\nconst ErrorContainer = styled.div`\n color: ${getThemeValue(THEME_NAME.ERROR)};\n padding-top: 3px;\n font-size: 12px;\n line-height: 14px;\n margin-left: 3px;\n`;\n\nconst ArrowContainer = styled.span`\n position: absolute;\n right: 8px;\n top: 8px;\n`;\n\n/**\n * Select Component\n * @param props - Component props\n * @param ref - Ref forwarded to the underlying HTMLSelectElement\n */\nfunction SelectComponent(props: SelectProps, ref: React.Ref<HTMLSelectElement>) {\n const [touched, setTouched] = useState(false);\n const [value, setValue] = useState(props.value || '');\n const errorId = useId();\n const prevValueRef = useRef<string>(undefined);\n\n useEffect(() => {\n if (props.value !== undefined && props.value !== prevValueRef.current) {\n setValue(props.value);\n prevValueRef.current = props.value as string;\n }\n }, [props.value]);\n\n const handleFocus = (e: React.FocusEvent<HTMLSelectElement>) => {\n setTouched(true);\n if (props.onFocus) {\n props.onFocus(e);\n }\n };\n\n const onChangeHandler = (e: React.ChangeEvent<HTMLSelectElement>) => {\n if (props.onChange) {\n setValue(e.target.value);\n props.onChange(e);\n } else {\n setValue(e.target.value);\n }\n };\n\n return (\n <Label>\n <SelectField\n {...props}\n ref={ref}\n multiple={false}\n value={value}\n onChange={onChangeHandler}\n onFocus={handleFocus}\n touched={touched}\n aria-invalid={!!props.errorText}\n aria-required={props.required}\n aria-describedby={props.errorText ? errorId : undefined}\n >\n <option />\n {props.children}\n </SelectField>\n <span>{props.label}</span>\n <ArrowContainer aria-hidden=\"true\">\n <ExpandMore />\n </ArrowContainer>\n {props.errorText && <ErrorContainer id={errorId}>{props.errorText}</ErrorContainer>}\n </Label>\n );\n}\n\nconst Select = React.forwardRef(SelectComponent);\nexport default Select;\n"],"names":["Label","styled","SelectField","getThemeValue","THEME_NAME","BORDER_COLOR","BACKGROUND","PRIMARY","PRIMARY_LIGHT","DISABLED_BORDER","DISABLED_BACKGROUND","DISABLED","ERROR","ERROR_LIGHT","props","touched","errorText","value","ErrorContainer","ArrowContainer","SelectComponent","ref","setTouched","useState","setValue","errorId","useId","prevValueRef","useRef","undefined","useEffect","current","handleFocus","e","onFocus","onChangeHandler","onChange","target","_jsxs","multiple","aria-invalid","aria-required","required","aria-describedby","_jsx","option","children","span","label","aria-hidden","ExpandMore","id","Select","React","forwardRef"],"mappings":"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"}
1
+ {"version":3,"file":"Select.js","sources":["../../../src/components/Input/Select.tsx"],"sourcesContent":["import React, { useState, useEffect, useId, useRef, useImperativeHandle } from 'react';\nimport styled from '@emotion/styled';\nimport ExpandMore from '../../icons/ExpandMore';\nimport { getThemeValue, THEME_NAME } from '../../shared/constants';\n\ntype SelectProps = {\n /** Label for the field */\n label?: string;\n /** Error text to be shown below the field */\n errorText?: string;\n} & React.InputHTMLAttributes<HTMLSelectElement>;\n\ntype SelectInternalProps = SelectProps & {\n touched: boolean;\n};\n\nconst Label = styled.label`\n display: inline-flex;\n flex-direction: column;\n position: relative;\n margin: 10px 5px;\n pointer-events: none;\n max-width: 268px;\n\n & svg {\n fill: currentColor;\n }\n`;\n\nconst SelectField = styled.select<SelectInternalProps>`\n border: none;\n color: inherit;\n padding: 0 8px;\n line-height: 30px;\n min-height: 32px;\n width: 268px;\n border-radius: 3px;\n border: 1px solid ${getThemeValue(THEME_NAME.BORDER_COLOR)};\n display: inline-block;\n background-color: ${getThemeValue(THEME_NAME.BACKGROUND)};\n pointer-events: auto;\n appearance: none;\n\n /** Focused */\n &:focus,\n &:active {\n border-color: ${getThemeValue(THEME_NAME.PRIMARY)};\n box-shadow: 0 0 0 4px ${getThemeValue(THEME_NAME.PRIMARY_LIGHT)};\n }\n\n &:focus ~ span,\n &:active ~ span {\n color: ${getThemeValue(THEME_NAME.PRIMARY)};\n }\n\n /** Disabled */\n &:disabled {\n border-color: ${getThemeValue(THEME_NAME.DISABLED_BORDER)};\n background-color: ${getThemeValue(THEME_NAME.DISABLED_BACKGROUND)};\n }\n\n &:disabled ~ span {\n color: ${getThemeValue(THEME_NAME.DISABLED)};\n }\n\n /** Invalid */\n &:focus:invalid {\n border-color: ${getThemeValue(THEME_NAME.ERROR)};\n box-shadow: 0 0 0 4px ${getThemeValue(THEME_NAME.ERROR_LIGHT)};\n }\n\n ${(props) =>\n props.touched\n ? `\n &:invalid {\n border-color: ${getThemeValue(THEME_NAME.ERROR)};\n }\n\n &:invalid ~ span {\n color: ${getThemeValue(THEME_NAME.ERROR)};\n }\n `\n : ''}\n\n /** Error */\n ${(props) =>\n props.errorText\n ? `\n border-color: ${getThemeValue(THEME_NAME.ERROR)};\n\n & ~ span {\n color: ${getThemeValue(THEME_NAME.ERROR)};\n }\n `\n : ''}\n\n /** Required */\n &:required + span:after {\n content: '*';\n margin-left: 2px;\n color: ${getThemeValue(THEME_NAME.ERROR)};\n }\n\n /** Label Animation */\n & + span {\n position: absolute;\n padding: 0 5px;\n top: 0px;\n left: 4px;\n font-size: 14px;\n line-height: 32px;\n transition: all 300ms ease;\n }\n\n ${(props) =>\n props.value !== ''\n ? `\n & + span {\n top: -8px;\n background: ${getThemeValue(THEME_NAME.BACKGROUND)};\n font-size: 12px;\n line-height: 14px;\n }\n `\n : ''}\n\n &:focus + span, &:placeholder-shown + span {\n top: -8px;\n background: ${getThemeValue(THEME_NAME.BACKGROUND)};\n font-size: 12px;\n line-height: 14px;\n }\n`;\n\nconst ErrorContainer = styled.div`\n color: ${getThemeValue(THEME_NAME.ERROR)};\n padding-top: 3px;\n font-size: 12px;\n line-height: 14px;\n margin-left: 3px;\n`;\n\nconst ArrowContainer = styled.span`\n position: absolute;\n right: 8px;\n top: 8px;\n`;\n\n/**\n * Select Component\n * @param props - Component props\n * @param ref - Ref forwarded to the underlying HTMLSelectElement\n */\nfunction SelectComponent(props: SelectProps, forwardedRef: React.Ref<HTMLSelectElement>) {\n const [touched, setTouched] = useState(false);\n const [value, setValue] = useState(props.value || '');\n const errorId = useId();\n const prevValueRef = useRef<string>(undefined);\n const internalRef = useRef<HTMLSelectElement>(null);\n\n useImperativeHandle(forwardedRef, () => internalRef.current as HTMLSelectElement);\n\n // Sync prop value with state\n useEffect(() => {\n if (props.value !== prevValueRef.current) {\n setValue(props.value || '');\n prevValueRef.current = props.value as string;\n }\n }, [props.value]);\n\n useEffect(() => {\n if (internalRef.current) {\n internalRef.current.setCustomValidity(props.errorText || '');\n }\n }, [props.errorText]);\n\n const handleFocus = (e: React.FocusEvent<HTMLSelectElement>) => {\n setTouched(true);\n if (props.onFocus) {\n props.onFocus(e);\n }\n };\n\n const onChangeHandler = (e: React.ChangeEvent<HTMLSelectElement>) => {\n if (props.onChange) {\n setValue(e.target.value);\n props.onChange(e);\n } else {\n setValue(e.target.value);\n }\n };\n\n return (\n <Label>\n <SelectField\n {...props}\n ref={internalRef}\n multiple={false}\n value={value}\n onChange={onChangeHandler}\n onFocus={handleFocus}\n touched={touched}\n aria-invalid={!!props.errorText}\n aria-required={props.required}\n aria-describedby={props.errorText ? errorId : undefined}\n >\n <option />\n {props.children}\n </SelectField>\n <span>{props.label}</span>\n <ArrowContainer aria-hidden=\"true\">\n <ExpandMore />\n </ArrowContainer>\n {props.errorText && <ErrorContainer id={errorId}>{props.errorText}</ErrorContainer>}\n </Label>\n );\n}\n\nconst Select = React.forwardRef(SelectComponent);\nexport default Select;\n"],"names":["Label","styled","SelectField","getThemeValue","THEME_NAME","BORDER_COLOR","BACKGROUND","PRIMARY","PRIMARY_LIGHT","DISABLED_BORDER","DISABLED_BACKGROUND","DISABLED","ERROR","ERROR_LIGHT","props","touched","errorText","value","ErrorContainer","ArrowContainer","SelectComponent","forwardedRef","setTouched","useState","setValue","errorId","useId","prevValueRef","useRef","undefined","internalRef","useImperativeHandle","current","useEffect","setCustomValidity","handleFocus","e","onFocus","onChangeHandler","onChange","target","_jsxs","ref","multiple","aria-invalid","aria-required","required","aria-describedby","_jsx","option","children","span","label","aria-hidden","ExpandMore","id","Select","React","forwardRef"],"mappings":";;;;;;AAgBA,MAAMA,OAAAA,iBAAQC,MAAAA,CAAAA,OAAAA,EAAAA;;;;AAad,MAAMC,WAAAA,iBAAcD,MAAAA,CAAAA,QAAAA,EAAAA;;;+HAQIE,aAAAA,CAAcC,UAAAA,CAAWC,YAAY,CAAA,EAAA,yCAAA,EAErCF,aAAAA,CAAcC,WAAWE,UAAU,CAAA,EAAA,qEAAA,EAOnCH,cAAcC,UAAAA,CAAWG,OAAO,6BACxBJ,aAAAA,CAAcC,UAAAA,CAAWI,aAAa,CAAA,EAAA,yCAAA,EAKrDL,aAAAA,CAAcC,WAAWG,OAAO,CAAA,EAAA,4BAAA,EAKzBJ,cAAcC,UAAAA,CAAWK,eAAe,yBACpCN,aAAAA,CAAcC,UAAAA,CAAWM,mBAAmB,CAAA,EAAA,4BAAA,EAIvDP,aAAAA,CAAcC,WAAWO,QAAQ,CAAA,EAAA,iCAAA,EAK1BR,cAAcC,UAAAA,CAAWQ,KAAK,6BACtBT,aAAAA,CAAcC,UAAAA,CAAWS,WAAW,CAAA,EAAA,IAAA,EAG9D,CAACC,QACCA,KAAAA,CAAMC,OAAO,GACP;;sBAEQ,EAAEZ,aAAAA,CAAcC,UAAAA,CAAWQ,KAAK,CAAA,CAAE;;;;eAIzC,EAAET,aAAAA,CAAcC,UAAAA,CAAWQ,KAAK,CAAA,CAAE;;AAE7C,IAAA,CAAC,GACS,EAAA,EAAA,YAAA,EAGR,CAACE,QACCA,KAAAA,CAAME,SAAS,GACT;kBACI,EAAEb,aAAAA,CAAcC,UAAAA,CAAWQ,KAAK,CAAA,CAAE;;;eAGrC,EAAET,aAAAA,CAAcC,UAAAA,CAAWQ,KAAK,CAAA,CAAE;;AAE7C,IAAA,CAAC,GACS,EAAA,EAAA,sEAAA,EAMGT,aAAAA,CAAcC,UAAAA,CAAWQ,KAAK,CAAA,EAAA,yHAAA,EAczC,CAACE,KAAAA,GACCA,KAAAA,CAAMG,KAAK,KAAK,EAAA,GACV;;;oBAGM,EAAEd,aAAAA,CAAcC,UAAAA,CAAWE,UAAU,CAAA,CAAE;;;;AAIvD,IAAA,CAAC,GACS,EAAA,EAAA,oEAAA,EAIQH,aAAAA,CAAcC,UAAAA,CAAWE,UAAU,CAAA,EAAA,oCAAA,CAAA;AAMzD,MAAMY,gBAAAA,iBAAiBjB,MAAAA,CAAAA,KAAAA,EAAAA;;;AACVE,CAAAA,CAAAA,CAAAA,QAAAA,EAAAA,aAAAA,CAAcC,WAAWQ,KAAK,CAAA,EAAA,mEAAA,CAAA;AAO3C,MAAMO,gBAAAA,iBAAiBlB,MAAAA,CAAAA,MAAAA,EAAAA;;;;AAMvB;;;;AAIC,IACD,SAASmB,eAAAA,CAAgBN,KAAkB,EAAEO,YAA0C,EAAA;AACnF,IAAA,MAAM,CAACN,OAAAA,EAASO,UAAAA,CAAW,GAAGC,QAAAA,CAAS,KAAA,CAAA;AACvC,IAAA,MAAM,CAACN,KAAAA,EAAOO,QAAAA,CAAS,GAAGD,QAAAA,CAAST,KAAAA,CAAMG,KAAK,IAAI,EAAA,CAAA;AAClD,IAAA,MAAMQ,OAAAA,GAAUC,KAAAA,EAAAA;AAChB,IAAA,MAAMC,eAAeC,MAAAA,CAAeC,SAAAA,CAAAA;AACpC,IAAA,MAAMC,cAAcF,MAAAA,CAA0B,IAAA,CAAA;IAE9CG,mBAAAA,CAAoBV,YAAAA,EAAc,IAAMS,WAAAA,CAAYE,OAAO,CAAA;;IAG3DC,SAAAA,CAAU,IAAA;AACN,QAAA,IAAInB,KAAAA,CAAMG,KAAK,KAAKU,YAAAA,CAAaK,OAAO,EAAE;YACtCR,QAAAA,CAASV,KAAAA,CAAMG,KAAK,IAAI,EAAA,CAAA;YACxBU,YAAAA,CAAaK,OAAO,GAAGlB,KAAAA,CAAMG,KAAK;AACtC,QAAA;IACJ,CAAA,EAAG;AAACH,QAAAA,KAAAA,CAAMG;AAAM,KAAA,CAAA;IAEhBgB,SAAAA,CAAU,IAAA;QACN,IAAIH,WAAAA,CAAYE,OAAO,EAAE;AACrBF,YAAAA,WAAAA,CAAYE,OAAO,CAACE,iBAAiB,CAACpB,KAAAA,CAAME,SAAS,IAAI,EAAA,CAAA;AAC7D,QAAA;IACJ,CAAA,EAAG;AAACF,QAAAA,KAAAA,CAAME;AAAU,KAAA,CAAA;AAEpB,IAAA,MAAMmB,cAAc,CAACC,CAAAA,GAAAA;QACjBd,UAAAA,CAAW,IAAA,CAAA;QACX,IAAIR,KAAAA,CAAMuB,OAAO,EAAE;AACfvB,YAAAA,KAAAA,CAAMuB,OAAO,CAACD,CAAAA,CAAAA;AAClB,QAAA;AACJ,IAAA,CAAA;AAEA,IAAA,MAAME,kBAAkB,CAACF,CAAAA,GAAAA;QACrB,IAAItB,KAAAA,CAAMyB,QAAQ,EAAE;YAChBf,QAAAA,CAASY,CAAAA,CAAEI,MAAM,CAACvB,KAAK,CAAA;AACvBH,YAAAA,KAAAA,CAAMyB,QAAQ,CAACH,CAAAA,CAAAA;QACnB,CAAA,MAAO;YACHZ,QAAAA,CAASY,CAAAA,CAAEI,MAAM,CAACvB,KAAK,CAAA;AAC3B,QAAA;AACJ,IAAA,CAAA;AAEA,IAAA,qBACIwB,IAAA,CAACzC,OAAAA,EAAAA;;0BACGyC,IAAA,CAACvC,WAAAA,EAAAA;AACI,gBAAA,GAAGY,KAAK;gBACT4B,GAAAA,EAAKZ,WAAAA;gBACLa,QAAAA,EAAU,KAAA;gBACV1B,KAAAA,EAAOA,KAAAA;gBACPsB,QAAAA,EAAUD,eAAAA;gBACVD,OAAAA,EAASF,WAAAA;gBACTpB,OAAAA,EAASA,OAAAA;gBACT6B,cAAAA,EAAc,CAAC,CAAC9B,KAAAA,CAAME,SAAS;AAC/B6B,gBAAAA,eAAAA,EAAe/B,MAAMgC,QAAQ;gBAC7BC,kBAAAA,EAAkBjC,KAAAA,CAAME,SAAS,GAAGS,OAAAA,GAAUI,SAAAA;;kCAE9CmB,GAAA,CAACC,QAAAA,EAAAA,EAAAA,CAAAA;AACAnC,oBAAAA,KAAAA,CAAMoC;;;0BAEXF,GAAA,CAACG,MAAAA,EAAAA;AAAMrC,gBAAAA,QAAAA,EAAAA,KAAAA,CAAMsC;;0BACbJ,GAAA,CAAC7B,gBAAAA,EAAAA;gBAAekC,aAAAA,EAAY,MAAA;AACxB,gBAAA,QAAA,gBAAAL,GAAA,CAACM,UAAAA,EAAAA,EAAAA;;YAEJxC,KAAAA,CAAME,SAAS,kBAAIgC,GAAA,CAAC9B,gBAAAA,EAAAA;gBAAeqC,EAAAA,EAAI9B,OAAAA;AAAUX,gBAAAA,QAAAA,EAAAA,KAAAA,CAAME;;;;AAGpE;AAEA,MAAMwC,MAAAA,iBAASC,KAAAA,CAAMC,UAAU,CAACtC,eAAAA;;;;"}
@@ -1,14 +1,14 @@
1
1
  import { jsxs, jsx } from '@emotion/react/jsx-runtime';
2
- import React, { useState, useId, useRef, useEffect } from 'react';
2
+ import React, { useState, useId, useRef, useImperativeHandle, useEffect } from 'react';
3
3
  import styled from '@emotion/styled';
4
4
  import { getThemeValue, THEME_NAME } from '../../shared/constants.js';
5
5
 
6
6
  const Label$4 = /*#__PURE__*/ styled("label", {
7
- target: "e1j32tnv0",
7
+ target: "e1towgf50",
8
8
  label: "Label"
9
9
  })("display:inline-flex;flex-direction:column;position:relative;margin:10px 5px;");
10
10
  const TextField = /*#__PURE__*/ styled("textarea", {
11
- target: "e1j32tnv1",
11
+ target: "e1towgf51",
12
12
  label: "TextField"
13
13
  })("border:none;color:inherit;padding:8px;min-height:150px;min-width:250px;border-radius:3px;border:1px solid ", getThemeValue(THEME_NAME.BORDER_COLOR), ";display:inline-block;background-color:", getThemeValue(THEME_NAME.BACKGROUND), ";&:focus,&:active{border-color:", getThemeValue(THEME_NAME.PRIMARY), ";box-shadow:0 0 0 4px ", getThemeValue(THEME_NAME.PRIMARY_LIGHT), ";}&:focus + span,&:active + span{color:", getThemeValue(THEME_NAME.PRIMARY), ";}&:disabled{border-color:", getThemeValue(THEME_NAME.DISABLED_BORDER), ";background-color:", getThemeValue(THEME_NAME.DISABLED_BACKGROUND), ";}&:disabled + span{color:", getThemeValue(THEME_NAME.DISABLED), ";}&:focus:invalid{border-color:", getThemeValue(THEME_NAME.ERROR), ";box-shadow:0 0 0 4px ", getThemeValue(THEME_NAME.ERROR_LIGHT), ";}", (props)=>props.touched ? `
14
14
  &:invalid {
@@ -32,20 +32,22 @@ const TextField = /*#__PURE__*/ styled("textarea", {
32
32
  line-height: 14px;
33
33
  }
34
34
  ` : '', " &:focus + span,&:placeholder-shown + span{top:-8px;background:", getThemeValue(THEME_NAME.BACKGROUND), ";font-size:12px;line-height:14px;}");
35
- const ErrorContainer$2 = /*#__PURE__*/ styled("div", {
36
- target: "e1j32tnv2",
35
+ const ErrorContainer$4 = /*#__PURE__*/ styled("div", {
36
+ target: "e1towgf52",
37
37
  label: "ErrorContainer"
38
38
  })("color:", getThemeValue(THEME_NAME.ERROR), ";padding-top:3px;font-size:12px;line-height:14px;margin-left:3px;");
39
39
  /**
40
40
  * TextArea Component
41
41
  * @param props - Component props
42
42
  * @param ref - Ref forwarded to the underlying HTMLTextAreaElement
43
- */ function TextAreaComponent(props, ref) {
43
+ */ function TextAreaComponent(props, forwardedRef) {
44
44
  const { label, errorText, value: propsValue, required, ...rest } = props;
45
45
  const [touched, setTouched] = useState(false);
46
46
  const [value, setValue] = useState(propsValue || '');
47
47
  const errorId = useId();
48
48
  const prevValueRef = useRef(undefined);
49
+ const internalRef = useRef(null);
50
+ useImperativeHandle(forwardedRef, ()=>internalRef.current);
49
51
  useEffect(()=>{
50
52
  if (propsValue !== undefined && propsValue !== prevValueRef.current) {
51
53
  setValue(propsValue);
@@ -54,6 +56,13 @@ const ErrorContainer$2 = /*#__PURE__*/ styled("div", {
54
56
  }, [
55
57
  propsValue
56
58
  ]);
59
+ useEffect(()=>{
60
+ if (internalRef.current) {
61
+ internalRef.current.setCustomValidity(errorText || '');
62
+ }
63
+ }, [
64
+ errorText
65
+ ]);
57
66
  const handleFocus = (e)=>{
58
67
  setTouched(true);
59
68
  if (props.onFocus) {
@@ -72,7 +81,7 @@ const ErrorContainer$2 = /*#__PURE__*/ styled("div", {
72
81
  children: [
73
82
  /*#__PURE__*/ jsx(TextField, {
74
83
  ...rest,
75
- ref: ref,
84
+ ref: internalRef,
76
85
  value: value,
77
86
  onChange: onChangeHandler,
78
87
  onFocus: handleFocus,
@@ -85,7 +94,7 @@ const ErrorContainer$2 = /*#__PURE__*/ styled("div", {
85
94
  /*#__PURE__*/ jsx("span", {
86
95
  children: label
87
96
  }),
88
- errorText && /*#__PURE__*/ jsx(ErrorContainer$2, {
97
+ errorText && /*#__PURE__*/ jsx(ErrorContainer$4, {
89
98
  id: errorId,
90
99
  children: errorText
91
100
  })