@remember-web/primitive 0.5.4 → 0.5.5

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 (47) hide show
  1. package/dist/src/Inputs/Select/DesignedSelect/index.cjs.js +4 -1
  2. package/dist/src/Inputs/Select/DesignedSelect/index.cjs.js.map +1 -1
  3. package/dist/src/Inputs/Select/DesignedSelect/index.d.ts +1 -0
  4. package/dist/src/Inputs/Select/DesignedSelect/index.d.ts.map +1 -1
  5. package/dist/src/Inputs/Select/DesignedSelect/index.esm.js +4 -1
  6. package/dist/src/Inputs/Select/DesignedSelect/index.esm.js.map +1 -1
  7. package/dist/src/Inputs/Select/DesignedSelect/styles.cjs.js +4 -4
  8. package/dist/src/Inputs/Select/DesignedSelect/styles.cjs.js.map +1 -1
  9. package/dist/src/Inputs/Select/DesignedSelect/styles.d.ts.map +1 -1
  10. package/dist/src/Inputs/Select/DesignedSelect/styles.esm.js +5 -5
  11. package/dist/src/Inputs/Select/DesignedSelect/styles.esm.js.map +1 -1
  12. package/dist/src/Inputs/Select/DesignedSelect/types.d.ts +1 -0
  13. package/dist/src/Inputs/Select/DesignedSelect/types.d.ts.map +1 -1
  14. package/dist/src/Inputs/Select/NativeSelect/index.cjs.js +4 -1
  15. package/dist/src/Inputs/Select/NativeSelect/index.cjs.js.map +1 -1
  16. package/dist/src/Inputs/Select/NativeSelect/index.d.ts +1 -0
  17. package/dist/src/Inputs/Select/NativeSelect/index.d.ts.map +1 -1
  18. package/dist/src/Inputs/Select/NativeSelect/index.esm.js +4 -1
  19. package/dist/src/Inputs/Select/NativeSelect/index.esm.js.map +1 -1
  20. package/dist/src/Inputs/Select/NativeSelect/styles.cjs.js +2 -2
  21. package/dist/src/Inputs/Select/NativeSelect/styles.cjs.js.map +1 -1
  22. package/dist/src/Inputs/Select/NativeSelect/styles.d.ts.map +1 -1
  23. package/dist/src/Inputs/Select/NativeSelect/styles.esm.js +3 -3
  24. package/dist/src/Inputs/Select/NativeSelect/styles.esm.js.map +1 -1
  25. package/dist/src/Inputs/Select/NativeSelect/types.d.ts +1 -0
  26. package/dist/src/Inputs/Select/NativeSelect/types.d.ts.map +1 -1
  27. package/dist/src/Inputs/Select/index.cjs.js +4 -1
  28. package/dist/src/Inputs/Select/index.cjs.js.map +1 -1
  29. package/dist/src/Inputs/Select/index.d.ts.map +1 -1
  30. package/dist/src/Inputs/Select/index.esm.js +4 -1
  31. package/dist/src/Inputs/Select/index.esm.js.map +1 -1
  32. package/dist/src/Inputs/Select/styles.cjs.js +12 -3
  33. package/dist/src/Inputs/Select/styles.cjs.js.map +1 -1
  34. package/dist/src/Inputs/Select/styles.d.ts +1 -0
  35. package/dist/src/Inputs/Select/styles.d.ts.map +1 -1
  36. package/dist/src/Inputs/Select/styles.esm.js +14 -5
  37. package/dist/src/Inputs/Select/styles.esm.js.map +1 -1
  38. package/package.json +1 -1
  39. package/src/Inputs/Select/DesignedSelect/index.tsx +2 -0
  40. package/src/Inputs/Select/DesignedSelect/styles.ts +12 -4
  41. package/src/Inputs/Select/DesignedSelect/types.ts +1 -0
  42. package/src/Inputs/Select/NativeSelect/index.tsx +2 -0
  43. package/src/Inputs/Select/NativeSelect/styles.ts +6 -7
  44. package/src/Inputs/Select/NativeSelect/types.ts +1 -0
  45. package/src/Inputs/Select/Select.stories.tsx +2 -3
  46. package/src/Inputs/Select/index.tsx +3 -0
  47. package/src/Inputs/Select/styles.ts +28 -5
@@ -20,7 +20,7 @@ var _defineProperty__default = /*#__PURE__*/_interopDefault(_defineProperty);
20
20
  var _slicedToArray__default = /*#__PURE__*/_interopDefault(_slicedToArray);
21
21
  var _objectWithoutProperties__default = /*#__PURE__*/_interopDefault(_objectWithoutProperties);
22
22
 
23
- var _excluded = ["children", "value", "maxHeight", "placeholder", "onChange", "width", "extendDirection", "disabled", "onClick"];
23
+ var _excluded = ["children", "value", "maxHeight", "placeholder", "onChange", "width", "extendDirection", "error", "disabled", "onClick"];
24
24
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
25
25
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), true).forEach(function (r) { _defineProperty__default.default(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
26
26
  var DesignedSelect = function DesignedSelect(_ref, ref) {
@@ -32,6 +32,8 @@ var DesignedSelect = function DesignedSelect(_ref, ref) {
32
32
  onChange = _ref.onChange,
33
33
  width = _ref.width,
34
34
  extendDirection = _ref.extendDirection,
35
+ _ref$error = _ref.error,
36
+ error = _ref$error === void 0 ? false : _ref$error,
35
37
  disabled = _ref.disabled,
36
38
  onClick = _ref.onClick,
37
39
  props = _objectWithoutProperties__default.default(_ref, _excluded);
@@ -178,6 +180,7 @@ var DesignedSelect = function DesignedSelect(_ref, ref) {
178
180
  "aria-expanded": isExpanded,
179
181
  "aria-haspopup": "listbox",
180
182
  "aria-disabled": disabled,
183
+ $error: error,
181
184
  onKeyDown: keyDownHandler
182
185
  }, props), {}, {
183
186
  children: [/*#__PURE__*/jsxRuntime.jsx(styles$1.StyledSelect, {
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs.js","sources":["../../../../../src/Inputs/Select/DesignedSelect/index.tsx"],"sourcesContent":["'use client';\n\nimport { IconArrow2Down, IconArrow2Up } from '@remember-web/icon';\nimport type { KeyboardEvent, ReactNode, Ref, RefCallback } from 'react';\nimport {\n Children,\n forwardRef,\n isValidElement,\n useCallback,\n useId,\n useRef,\n useState,\n} from 'react';\n\nimport useMouseEventAway from '@/hooks/useMouseEventAway';\n\nimport { OptionHolder } from '../Option';\nimport { SelectContainer } from '../styles';\nimport type { OptionElementType, SelectValue } from '../types';\nimport { focusSibling } from '../utils';\nimport { DEFAULT_MAX_HEIGHT_PX, OPTION_ITEM_HEIGHT_PX } from './const';\nimport {\n SelectDownIcon,\n SelectOption,\n SelectOptionWrapper,\n StyledSelect,\n} from './styles';\nimport type { DesignedSelectInternalProps, ExpandedType } from './types';\n\nconst DesignedSelect = <Value extends SelectValue>(\n {\n children,\n value,\n maxHeight = DEFAULT_MAX_HEIGHT_PX,\n placeholder,\n onChange,\n width,\n extendDirection,\n disabled,\n onClick,\n ...props\n }: DesignedSelectInternalProps<Value>,\n ref?: Ref<HTMLDivElement>\n) => {\n const id = useId();\n const [expandedDirection, _setExpandedDirection] =\n useState<ExpandedType>('none');\n const selectContainerRef = useRef<HTMLDivElement | null>(null);\n const selectListRef = useRef<HTMLUListElement | null>(null);\n const clickAwayRef = useMouseEventAway<HTMLDivElement, 'pointerdown'>(\n 'pointerdown',\n () => {\n setExpandedDirection('none');\n }\n );\n\n const setExpandedDirection = useCallback(\n (...args: Parameters<typeof _setExpandedDirection>) => {\n if (disabled) {\n return;\n }\n _setExpandedDirection(...args);\n },\n [disabled]\n );\n\n const options = Children.toArray(children)\n .filter(\n (child): child is OptionElementType<Value> =>\n isValidElement(child) && child.type === OptionHolder\n )\n .map(\n ({\n props: { children: _children, value: _value, disabled: _disabled },\n }) => ({\n label: _children,\n value: _value,\n disabled: _disabled,\n })\n );\n\n const selectedOption = options.find((option) => value === option.value);\n\n const isExpanded = expandedDirection !== 'none';\n\n const onSelectOption = (_value: Value, _label: ReactNode) => {\n onChange?.(_value, _label);\n setExpandedDirection('none');\n selectContainerRef.current?.focus();\n };\n\n // 리스트가 하단으로 나와야하는지 상단으로 나와야하는지 계산하는 함수\n // 현재 Viewport기준으로 Select컴포넌트가 아래로 확장되었을 때 뷰포트 내에 리스트박스가 노출될 수 있다면 하단으로 확장, 아니라면 상단으로 확장\n // direction이 props로 전달되었다면 해당 방향으로 확장\n const expandSelectListAtComputedPosition = () => {\n if (extendDirection) {\n setExpandedDirection(extendDirection);\n return;\n }\n\n const selectContainerRect =\n selectContainerRef.current?.getBoundingClientRect();\n\n if (!selectContainerRect) {\n setExpandedDirection('below');\n return;\n }\n\n // SelectOptionWrapper가 마운트되기 전에 계산해야 하기 때문에 clientHeight를 사용하지 못하고 직접 계산\n const currentSelectHeight = Math.min(\n maxHeight,\n options.length * OPTION_ITEM_HEIGHT_PX\n );\n const bottomGap = document.body.clientHeight - selectContainerRect.bottom;\n\n setExpandedDirection(currentSelectHeight > bottomGap ? 'above' : 'below');\n };\n\n const optionItemRef = useCallback<RefCallback<HTMLLIElement>>(\n (ele) => {\n if (!ele) {\n return;\n }\n\n // 선택한 요소가 없을때는 첫번째 요소에 focus\n if (!value && !ele.previousSibling) {\n setTimeout(() => ele.focus());\n return;\n }\n\n // 선택한 요소가 있다면 해당 요소에 focus\n const optionValue = ele.dataset.optionValue || null;\n if (optionValue === value) {\n setTimeout(() => ele.focus());\n }\n },\n [value]\n );\n\n const keyDownHandler = (e: KeyboardEvent) => {\n const focusedElement = document.activeElement;\n\n if (!focusedElement || !(focusedElement instanceof HTMLElement)) {\n return;\n }\n\n switch (e.key) {\n case 'Tab':\n if (isExpanded) {\n e.preventDefault();\n }\n break;\n case 'ArrowUp':\n e.preventDefault();\n if (!isExpanded) {\n expandSelectListAtComputedPosition();\n break;\n }\n focusSibling(focusedElement, 'previous');\n break;\n case 'ArrowDown':\n e.preventDefault();\n if (!isExpanded) {\n expandSelectListAtComputedPosition();\n break;\n }\n focusSibling(focusedElement, 'next');\n break;\n case 'Escape':\n e.preventDefault();\n setExpandedDirection('none');\n selectContainerRef.current?.focus();\n break;\n case 'Enter':\n case ' ':\n e.preventDefault();\n\n if (e.target === e.currentTarget) {\n if (isExpanded) {\n setExpandedDirection('none');\n return;\n }\n expandSelectListAtComputedPosition();\n }\n\n if (\n focusedElement?.matches('[data-option-value]') &&\n focusedElement instanceof HTMLLIElement &&\n focusedElement.dataset.optionValue\n ) {\n onSelectOption(\n focusedElement.dataset.optionValue as Value,\n focusedElement.innerText\n );\n }\n break;\n default:\n break;\n }\n };\n\n return (\n <SelectContainer\n ref={(el) => {\n if (!el) {\n return;\n }\n selectContainerRef.current = el;\n clickAwayRef.current = el;\n }}\n $width={width}\n tabIndex={disabled ? undefined : 0}\n aria-expanded={isExpanded}\n aria-haspopup=\"listbox\"\n aria-disabled={disabled}\n onKeyDown={keyDownHandler}\n {...props}\n >\n <StyledSelect\n ref={ref}\n onClick={onClick}\n expandedDirection={expandedDirection}\n isPlaceholder={!selectedOption && !!placeholder}\n onPointerDown={(e) => {\n if (isExpanded) {\n setExpandedDirection('none');\n return;\n }\n\n e.stopPropagation();\n\n expandSelectListAtComputedPosition();\n }}\n >\n {selectedOption?.label || placeholder || 'ㅤ'}\n </StyledSelect>\n <SelectDownIcon>\n {isExpanded ? (\n <IconArrow2Up size=\"small\" />\n ) : (\n <IconArrow2Down size=\"small\" />\n )}\n </SelectDownIcon>\n {isExpanded && (\n <SelectOptionWrapper\n role=\"listbox\"\n aria-activedescendant={\n value != null ? `${id}-select-option-${value}` : undefined\n }\n ref={selectListRef}\n expandedDirection={expandedDirection}\n maxHeight={maxHeight}\n >\n {options.map(({ value: optionValue, label, disabled: _disabled }) => (\n <SelectOption\n id={`${id}-select-option-${optionValue}`}\n role=\"option\"\n key={optionValue}\n tabIndex={_disabled ? undefined : 0}\n aria-selected={optionValue === value}\n aria-disabled={_disabled}\n ref={optionItemRef}\n isSelected={optionValue === value}\n data-option-value={optionValue}\n // onMouseEnter를 사용하게 되면 키보드로 스크롤 할 때도 focus가 이동하게 되기 때문에 onMouseMove를 사용\n onMouseMove={(e) => {\n if (e.currentTarget === document.activeElement) {\n return;\n }\n e.currentTarget.focus({\n preventScroll: true,\n });\n }}\n onFocus={() => {\n selectListRef.current?.setAttribute(\n 'aria-activedescendant',\n `${id}-select-option-${optionValue}`\n );\n }}\n onClick={() => {\n if (_disabled) {\n return;\n }\n\n onSelectOption(optionValue, label);\n }}\n >\n {label}\n </SelectOption>\n ))}\n </SelectOptionWrapper>\n )}\n </SelectContainer>\n );\n};\n\nexport default forwardRef(DesignedSelect);\n"],"names":["maxHeight","props","expandedDirection","_setExpandedDirection","label","value","disabled","setTimeout","expandSelectListAtComputedPosition","focusSibling","ref","$width","tabIndex","onKeyDown","onClick","isPlaceholder","onPointerDown","children","size","role","onMouseMove","e","preventScroll","onSelectOption"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAAa;AAAA;AAAA;AA6Bb;AAcK;;;AAVDA;;;;;;;AAOGC;AAIL;AACA;;AAAOC;AAAmBC;AAE1B;AACA;AACA;;AAIE;AAGF;AAEI;AACE;AACF;AACAA;AACF;AAIF;;AAG0D;AAGtD;;;;;AAGEC;AACAC;AACAC;;AACD;AAGL;AAA2C;;AAE3C;;AAE6D;;;AAG3D;;;AAGF;AACA;AACA;AACA;AAAiD;AAC/C;;AAEE;AACF;AAEA;;;AAKE;AACF;;AAEA;AACA;;;;AASF;;AAGM;AACF;;AAEA;AACA;AACEC;AAAW;;AACX;AACF;;AAEA;;;AAGEA;AAAW;;AACb;AACF;AAIF;AAA6C;AAC3C;;AAGE;AACF;;AAGE;AACE;;AAEA;AACA;AACF;;;AAGIC;AACA;AACF;AACAC;AACA;AACF;;;AAGID;AACA;AACF;AACAC;AACA;AACF;;;AAGE;AACA;AACF;AACA;;AAGE;AACE;;AAEE;AACF;AACAD;AACF;;;AAWA;AACA;AAGJ;;AAGF;AAEIE;;AAEI;AACF;;;;AAIFC;AACAC;AACA;AACA;AACA;AACAC;AAA0B;;AAIxBH;AACAI;AACAZ;AACAa;AACAC;AACE;;AAEE;AACF;;AAIAR;;;AAG0C;AAE/BS;AAEGC;AAAY;AAEVA;;AACjB;AAICC;AACA;AAGAT;AACAR;AACAF;AAAqBiB;AAER;;;;;AAGTE;AAEAP;;AAEA;AACAF;;;AAGA;AAAA;AACAU;AACE;AACE;AACF;AACAC;AACEC;AACF;;;AAEa;;;;AAOb;AACE;AACF;AAEAC;;AACAN;AAEI;;AAER;AAEL;AAGP;AAEA;;"}
1
+ {"version":3,"file":"index.cjs.js","sources":["../../../../../src/Inputs/Select/DesignedSelect/index.tsx"],"sourcesContent":["'use client';\n\nimport { IconArrow2Down, IconArrow2Up } from '@remember-web/icon';\nimport type { KeyboardEvent, ReactNode, Ref, RefCallback } from 'react';\nimport {\n Children,\n forwardRef,\n isValidElement,\n useCallback,\n useId,\n useRef,\n useState,\n} from 'react';\n\nimport useMouseEventAway from '@/hooks/useMouseEventAway';\n\nimport { OptionHolder } from '../Option';\nimport { SelectContainer } from '../styles';\nimport type { OptionElementType, SelectValue } from '../types';\nimport { focusSibling } from '../utils';\nimport { DEFAULT_MAX_HEIGHT_PX, OPTION_ITEM_HEIGHT_PX } from './const';\nimport {\n SelectDownIcon,\n SelectOption,\n SelectOptionWrapper,\n StyledSelect,\n} from './styles';\nimport type { DesignedSelectInternalProps, ExpandedType } from './types';\n\nconst DesignedSelect = <Value extends SelectValue>(\n {\n children,\n value,\n maxHeight = DEFAULT_MAX_HEIGHT_PX,\n placeholder,\n onChange,\n width,\n extendDirection,\n error = false,\n disabled,\n onClick,\n ...props\n }: DesignedSelectInternalProps<Value>,\n ref?: Ref<HTMLDivElement>\n) => {\n const id = useId();\n const [expandedDirection, _setExpandedDirection] =\n useState<ExpandedType>('none');\n const selectContainerRef = useRef<HTMLDivElement | null>(null);\n const selectListRef = useRef<HTMLUListElement | null>(null);\n const clickAwayRef = useMouseEventAway<HTMLDivElement, 'pointerdown'>(\n 'pointerdown',\n () => {\n setExpandedDirection('none');\n }\n );\n\n const setExpandedDirection = useCallback(\n (...args: Parameters<typeof _setExpandedDirection>) => {\n if (disabled) {\n return;\n }\n _setExpandedDirection(...args);\n },\n [disabled]\n );\n\n const options = Children.toArray(children)\n .filter(\n (child): child is OptionElementType<Value> =>\n isValidElement(child) && child.type === OptionHolder\n )\n .map(\n ({\n props: { children: _children, value: _value, disabled: _disabled },\n }) => ({\n label: _children,\n value: _value,\n disabled: _disabled,\n })\n );\n\n const selectedOption = options.find((option) => value === option.value);\n\n const isExpanded = expandedDirection !== 'none';\n\n const onSelectOption = (_value: Value, _label: ReactNode) => {\n onChange?.(_value, _label);\n setExpandedDirection('none');\n selectContainerRef.current?.focus();\n };\n\n // 리스트가 하단으로 나와야하는지 상단으로 나와야하는지 계산하는 함수\n // 현재 Viewport기준으로 Select컴포넌트가 아래로 확장되었을 때 뷰포트 내에 리스트박스가 노출될 수 있다면 하단으로 확장, 아니라면 상단으로 확장\n // direction이 props로 전달되었다면 해당 방향으로 확장\n const expandSelectListAtComputedPosition = () => {\n if (extendDirection) {\n setExpandedDirection(extendDirection);\n return;\n }\n\n const selectContainerRect =\n selectContainerRef.current?.getBoundingClientRect();\n\n if (!selectContainerRect) {\n setExpandedDirection('below');\n return;\n }\n\n // SelectOptionWrapper가 마운트되기 전에 계산해야 하기 때문에 clientHeight를 사용하지 못하고 직접 계산\n const currentSelectHeight = Math.min(\n maxHeight,\n options.length * OPTION_ITEM_HEIGHT_PX\n );\n const bottomGap = document.body.clientHeight - selectContainerRect.bottom;\n\n setExpandedDirection(currentSelectHeight > bottomGap ? 'above' : 'below');\n };\n\n const optionItemRef = useCallback<RefCallback<HTMLLIElement>>(\n (ele) => {\n if (!ele) {\n return;\n }\n\n // 선택한 요소가 없을때는 첫번째 요소에 focus\n if (!value && !ele.previousSibling) {\n setTimeout(() => ele.focus());\n return;\n }\n\n // 선택한 요소가 있다면 해당 요소에 focus\n const optionValue = ele.dataset.optionValue || null;\n if (optionValue === value) {\n setTimeout(() => ele.focus());\n }\n },\n [value]\n );\n\n const keyDownHandler = (e: KeyboardEvent) => {\n const focusedElement = document.activeElement;\n\n if (!focusedElement || !(focusedElement instanceof HTMLElement)) {\n return;\n }\n\n switch (e.key) {\n case 'Tab':\n if (isExpanded) {\n e.preventDefault();\n }\n break;\n case 'ArrowUp':\n e.preventDefault();\n if (!isExpanded) {\n expandSelectListAtComputedPosition();\n break;\n }\n focusSibling(focusedElement, 'previous');\n break;\n case 'ArrowDown':\n e.preventDefault();\n if (!isExpanded) {\n expandSelectListAtComputedPosition();\n break;\n }\n focusSibling(focusedElement, 'next');\n break;\n case 'Escape':\n e.preventDefault();\n setExpandedDirection('none');\n selectContainerRef.current?.focus();\n break;\n case 'Enter':\n case ' ':\n e.preventDefault();\n\n if (e.target === e.currentTarget) {\n if (isExpanded) {\n setExpandedDirection('none');\n return;\n }\n expandSelectListAtComputedPosition();\n }\n\n if (\n focusedElement?.matches('[data-option-value]') &&\n focusedElement instanceof HTMLLIElement &&\n focusedElement.dataset.optionValue\n ) {\n onSelectOption(\n focusedElement.dataset.optionValue as Value,\n focusedElement.innerText\n );\n }\n break;\n default:\n break;\n }\n };\n\n return (\n <SelectContainer\n ref={(el) => {\n if (!el) {\n return;\n }\n selectContainerRef.current = el;\n clickAwayRef.current = el;\n }}\n $width={width}\n tabIndex={disabled ? undefined : 0}\n aria-expanded={isExpanded}\n aria-haspopup=\"listbox\"\n aria-disabled={disabled}\n $error={error}\n onKeyDown={keyDownHandler}\n {...props}\n >\n <StyledSelect\n ref={ref}\n onClick={onClick}\n expandedDirection={expandedDirection}\n isPlaceholder={!selectedOption && !!placeholder}\n onPointerDown={(e) => {\n if (isExpanded) {\n setExpandedDirection('none');\n return;\n }\n\n e.stopPropagation();\n\n expandSelectListAtComputedPosition();\n }}\n >\n {selectedOption?.label || placeholder || 'ㅤ'}\n </StyledSelect>\n <SelectDownIcon>\n {isExpanded ? (\n <IconArrow2Up size=\"small\" />\n ) : (\n <IconArrow2Down size=\"small\" />\n )}\n </SelectDownIcon>\n {isExpanded && (\n <SelectOptionWrapper\n role=\"listbox\"\n aria-activedescendant={\n value != null ? `${id}-select-option-${value}` : undefined\n }\n ref={selectListRef}\n expandedDirection={expandedDirection}\n maxHeight={maxHeight}\n >\n {options.map(({ value: optionValue, label, disabled: _disabled }) => (\n <SelectOption\n id={`${id}-select-option-${optionValue}`}\n role=\"option\"\n key={optionValue}\n tabIndex={_disabled ? undefined : 0}\n aria-selected={optionValue === value}\n aria-disabled={_disabled}\n ref={optionItemRef}\n isSelected={optionValue === value}\n data-option-value={optionValue}\n // onMouseEnter를 사용하게 되면 키보드로 스크롤 할 때도 focus가 이동하게 되기 때문에 onMouseMove를 사용\n onMouseMove={(e) => {\n if (e.currentTarget === document.activeElement) {\n return;\n }\n e.currentTarget.focus({\n preventScroll: true,\n });\n }}\n onFocus={() => {\n selectListRef.current?.setAttribute(\n 'aria-activedescendant',\n `${id}-select-option-${optionValue}`\n );\n }}\n onClick={() => {\n if (_disabled) {\n return;\n }\n\n onSelectOption(optionValue, label);\n }}\n >\n {label}\n </SelectOption>\n ))}\n </SelectOptionWrapper>\n )}\n </SelectContainer>\n );\n};\n\nexport default forwardRef(DesignedSelect);\n"],"names":["maxHeight","error","props","expandedDirection","_setExpandedDirection","label","value","disabled","setTimeout","expandSelectListAtComputedPosition","focusSibling","ref","$width","tabIndex","$error","onKeyDown","onClick","isPlaceholder","onPointerDown","children","size","role","onMouseMove","e","preventScroll","onSelectOption"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAAa;AAAA;AAAA;AA6Bb;AAeK;;;AAXDA;;;;;;AAKAC;;;AAGGC;AAIL;AACA;;AAAOC;AAAmBC;AAE1B;AACA;AACA;;AAIE;AAGF;AAEI;AACE;AACF;AACAA;AACF;AAIF;;AAG0D;AAGtD;;;;;AAGEC;AACAC;AACAC;;AACD;AAGL;AAA2C;;AAE3C;;AAE6D;;;AAG3D;;;AAGF;AACA;AACA;AACA;AAAiD;AAC/C;;AAEE;AACF;AAEA;;;AAKE;AACF;;AAEA;AACA;;;;AASF;;AAGM;AACF;;AAEA;AACA;AACEC;AAAW;;AACX;AACF;;AAEA;;;AAGEA;AAAW;;AACb;AACF;AAIF;AAA6C;AAC3C;;AAGE;AACF;;AAGE;AACE;;AAEA;AACA;AACF;;;AAGIC;AACA;AACF;AACAC;AACA;AACF;;;AAGID;AACA;AACF;AACAC;AACA;AACF;;;AAGE;AACA;AACF;AACA;;AAGE;AACE;;AAEE;AACF;AACAD;AACF;;;AAWA;AACA;AAGJ;;AAGF;AAEIE;;AAEI;AACF;;;;AAIFC;AACAC;AACA;AACA;AACA;AACAC;AACAC;AAA0B;;AAIxBJ;AACAK;AACAb;AACAc;AACAC;AACE;;AAEE;AACF;;AAIAT;;;AAG0C;AAE/BU;AAEGC;AAAY;AAEVA;;AACjB;AAICC;AACA;AAGAV;AACAR;AACAH;AAAqBmB;AAER;;;;;AAGTE;AAEAR;;AAEA;AACAF;;;AAGA;AAAA;AACAW;AACE;AACE;AACF;AACAC;AACEC;AACF;;;AAEa;;;;AAOb;AACE;AACF;AAEAC;;AACAN;AAEI;;AAER;AAEL;AAGP;AAEA;;"}
@@ -7,6 +7,7 @@ declare const _default: import("react").ForwardRefExoticComponent<Omit<import("r
7
7
  width?: string | number | undefined;
8
8
  placeholder?: string | undefined;
9
9
  extendDirection?: "above" | "below" | undefined;
10
+ error?: boolean | undefined;
10
11
  } & import("react").RefAttributes<HTMLDivElement>>;
11
12
  export default _default;
12
13
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/Inputs/Select/DesignedSelect/index.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAiB,SAAS,EAAoB,MAAM,OAAO,CAAC;AAexE,OAAO,KAAK,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;;;;;;;;;AAsR/D,wBAA0C"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/Inputs/Select/DesignedSelect/index.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAiB,SAAS,EAAoB,MAAM,OAAO,CAAC;AAexE,OAAO,KAAK,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;;;;;;;;;;AAwR/D,wBAA0C"}
@@ -12,7 +12,7 @@ import { DEFAULT_MAX_HEIGHT_PX, OPTION_ITEM_HEIGHT_PX } from './const.esm.js';
12
12
  import { StyledSelect, SelectDownIcon, SelectOptionWrapper, SelectOption } from './styles.esm.js';
13
13
  import { jsxs, jsx } from 'react/jsx-runtime';
14
14
 
15
- var _excluded = ["children", "value", "maxHeight", "placeholder", "onChange", "width", "extendDirection", "disabled", "onClick"];
15
+ var _excluded = ["children", "value", "maxHeight", "placeholder", "onChange", "width", "extendDirection", "error", "disabled", "onClick"];
16
16
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
17
17
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), true).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
18
18
  var DesignedSelect = function DesignedSelect(_ref, ref) {
@@ -24,6 +24,8 @@ var DesignedSelect = function DesignedSelect(_ref, ref) {
24
24
  onChange = _ref.onChange,
25
25
  width = _ref.width,
26
26
  extendDirection = _ref.extendDirection,
27
+ _ref$error = _ref.error,
28
+ error = _ref$error === void 0 ? false : _ref$error,
27
29
  disabled = _ref.disabled,
28
30
  onClick = _ref.onClick,
29
31
  props = _objectWithoutProperties(_ref, _excluded);
@@ -170,6 +172,7 @@ var DesignedSelect = function DesignedSelect(_ref, ref) {
170
172
  "aria-expanded": isExpanded,
171
173
  "aria-haspopup": "listbox",
172
174
  "aria-disabled": disabled,
175
+ $error: error,
173
176
  onKeyDown: keyDownHandler
174
177
  }, props), {}, {
175
178
  children: [/*#__PURE__*/jsx(StyledSelect, {
@@ -1 +1 @@
1
- {"version":3,"file":"index.esm.js","sources":["../../../../../src/Inputs/Select/DesignedSelect/index.tsx"],"sourcesContent":["'use client';\n\nimport { IconArrow2Down, IconArrow2Up } from '@remember-web/icon';\nimport type { KeyboardEvent, ReactNode, Ref, RefCallback } from 'react';\nimport {\n Children,\n forwardRef,\n isValidElement,\n useCallback,\n useId,\n useRef,\n useState,\n} from 'react';\n\nimport useMouseEventAway from '@/hooks/useMouseEventAway';\n\nimport { OptionHolder } from '../Option';\nimport { SelectContainer } from '../styles';\nimport type { OptionElementType, SelectValue } from '../types';\nimport { focusSibling } from '../utils';\nimport { DEFAULT_MAX_HEIGHT_PX, OPTION_ITEM_HEIGHT_PX } from './const';\nimport {\n SelectDownIcon,\n SelectOption,\n SelectOptionWrapper,\n StyledSelect,\n} from './styles';\nimport type { DesignedSelectInternalProps, ExpandedType } from './types';\n\nconst DesignedSelect = <Value extends SelectValue>(\n {\n children,\n value,\n maxHeight = DEFAULT_MAX_HEIGHT_PX,\n placeholder,\n onChange,\n width,\n extendDirection,\n disabled,\n onClick,\n ...props\n }: DesignedSelectInternalProps<Value>,\n ref?: Ref<HTMLDivElement>\n) => {\n const id = useId();\n const [expandedDirection, _setExpandedDirection] =\n useState<ExpandedType>('none');\n const selectContainerRef = useRef<HTMLDivElement | null>(null);\n const selectListRef = useRef<HTMLUListElement | null>(null);\n const clickAwayRef = useMouseEventAway<HTMLDivElement, 'pointerdown'>(\n 'pointerdown',\n () => {\n setExpandedDirection('none');\n }\n );\n\n const setExpandedDirection = useCallback(\n (...args: Parameters<typeof _setExpandedDirection>) => {\n if (disabled) {\n return;\n }\n _setExpandedDirection(...args);\n },\n [disabled]\n );\n\n const options = Children.toArray(children)\n .filter(\n (child): child is OptionElementType<Value> =>\n isValidElement(child) && child.type === OptionHolder\n )\n .map(\n ({\n props: { children: _children, value: _value, disabled: _disabled },\n }) => ({\n label: _children,\n value: _value,\n disabled: _disabled,\n })\n );\n\n const selectedOption = options.find((option) => value === option.value);\n\n const isExpanded = expandedDirection !== 'none';\n\n const onSelectOption = (_value: Value, _label: ReactNode) => {\n onChange?.(_value, _label);\n setExpandedDirection('none');\n selectContainerRef.current?.focus();\n };\n\n // 리스트가 하단으로 나와야하는지 상단으로 나와야하는지 계산하는 함수\n // 현재 Viewport기준으로 Select컴포넌트가 아래로 확장되었을 때 뷰포트 내에 리스트박스가 노출될 수 있다면 하단으로 확장, 아니라면 상단으로 확장\n // direction이 props로 전달되었다면 해당 방향으로 확장\n const expandSelectListAtComputedPosition = () => {\n if (extendDirection) {\n setExpandedDirection(extendDirection);\n return;\n }\n\n const selectContainerRect =\n selectContainerRef.current?.getBoundingClientRect();\n\n if (!selectContainerRect) {\n setExpandedDirection('below');\n return;\n }\n\n // SelectOptionWrapper가 마운트되기 전에 계산해야 하기 때문에 clientHeight를 사용하지 못하고 직접 계산\n const currentSelectHeight = Math.min(\n maxHeight,\n options.length * OPTION_ITEM_HEIGHT_PX\n );\n const bottomGap = document.body.clientHeight - selectContainerRect.bottom;\n\n setExpandedDirection(currentSelectHeight > bottomGap ? 'above' : 'below');\n };\n\n const optionItemRef = useCallback<RefCallback<HTMLLIElement>>(\n (ele) => {\n if (!ele) {\n return;\n }\n\n // 선택한 요소가 없을때는 첫번째 요소에 focus\n if (!value && !ele.previousSibling) {\n setTimeout(() => ele.focus());\n return;\n }\n\n // 선택한 요소가 있다면 해당 요소에 focus\n const optionValue = ele.dataset.optionValue || null;\n if (optionValue === value) {\n setTimeout(() => ele.focus());\n }\n },\n [value]\n );\n\n const keyDownHandler = (e: KeyboardEvent) => {\n const focusedElement = document.activeElement;\n\n if (!focusedElement || !(focusedElement instanceof HTMLElement)) {\n return;\n }\n\n switch (e.key) {\n case 'Tab':\n if (isExpanded) {\n e.preventDefault();\n }\n break;\n case 'ArrowUp':\n e.preventDefault();\n if (!isExpanded) {\n expandSelectListAtComputedPosition();\n break;\n }\n focusSibling(focusedElement, 'previous');\n break;\n case 'ArrowDown':\n e.preventDefault();\n if (!isExpanded) {\n expandSelectListAtComputedPosition();\n break;\n }\n focusSibling(focusedElement, 'next');\n break;\n case 'Escape':\n e.preventDefault();\n setExpandedDirection('none');\n selectContainerRef.current?.focus();\n break;\n case 'Enter':\n case ' ':\n e.preventDefault();\n\n if (e.target === e.currentTarget) {\n if (isExpanded) {\n setExpandedDirection('none');\n return;\n }\n expandSelectListAtComputedPosition();\n }\n\n if (\n focusedElement?.matches('[data-option-value]') &&\n focusedElement instanceof HTMLLIElement &&\n focusedElement.dataset.optionValue\n ) {\n onSelectOption(\n focusedElement.dataset.optionValue as Value,\n focusedElement.innerText\n );\n }\n break;\n default:\n break;\n }\n };\n\n return (\n <SelectContainer\n ref={(el) => {\n if (!el) {\n return;\n }\n selectContainerRef.current = el;\n clickAwayRef.current = el;\n }}\n $width={width}\n tabIndex={disabled ? undefined : 0}\n aria-expanded={isExpanded}\n aria-haspopup=\"listbox\"\n aria-disabled={disabled}\n onKeyDown={keyDownHandler}\n {...props}\n >\n <StyledSelect\n ref={ref}\n onClick={onClick}\n expandedDirection={expandedDirection}\n isPlaceholder={!selectedOption && !!placeholder}\n onPointerDown={(e) => {\n if (isExpanded) {\n setExpandedDirection('none');\n return;\n }\n\n e.stopPropagation();\n\n expandSelectListAtComputedPosition();\n }}\n >\n {selectedOption?.label || placeholder || 'ㅤ'}\n </StyledSelect>\n <SelectDownIcon>\n {isExpanded ? (\n <IconArrow2Up size=\"small\" />\n ) : (\n <IconArrow2Down size=\"small\" />\n )}\n </SelectDownIcon>\n {isExpanded && (\n <SelectOptionWrapper\n role=\"listbox\"\n aria-activedescendant={\n value != null ? `${id}-select-option-${value}` : undefined\n }\n ref={selectListRef}\n expandedDirection={expandedDirection}\n maxHeight={maxHeight}\n >\n {options.map(({ value: optionValue, label, disabled: _disabled }) => (\n <SelectOption\n id={`${id}-select-option-${optionValue}`}\n role=\"option\"\n key={optionValue}\n tabIndex={_disabled ? undefined : 0}\n aria-selected={optionValue === value}\n aria-disabled={_disabled}\n ref={optionItemRef}\n isSelected={optionValue === value}\n data-option-value={optionValue}\n // onMouseEnter를 사용하게 되면 키보드로 스크롤 할 때도 focus가 이동하게 되기 때문에 onMouseMove를 사용\n onMouseMove={(e) => {\n if (e.currentTarget === document.activeElement) {\n return;\n }\n e.currentTarget.focus({\n preventScroll: true,\n });\n }}\n onFocus={() => {\n selectListRef.current?.setAttribute(\n 'aria-activedescendant',\n `${id}-select-option-${optionValue}`\n );\n }}\n onClick={() => {\n if (_disabled) {\n return;\n }\n\n onSelectOption(optionValue, label);\n }}\n >\n {label}\n </SelectOption>\n ))}\n </SelectOptionWrapper>\n )}\n </SelectContainer>\n );\n};\n\nexport default forwardRef(DesignedSelect);\n"],"names":["maxHeight","props","expandedDirection","_setExpandedDirection","label","value","disabled","setTimeout","expandSelectListAtComputedPosition","focusSibling","ref","$width","tabIndex","onKeyDown","onClick","isPlaceholder","onPointerDown","children","size","role","onMouseMove","e","preventScroll","onSelectOption"],"mappings":";;;;;;;;;;;;;;AAAa;AAAA;AAAA;AA6Bb;AAcK;;;AAVDA;;;;;;;AAOGC;AAIL;AACA;;AAAOC;AAAmBC;AAE1B;AACA;AACA;;AAIE;AAGF;AAEI;AACE;AACF;AACAA;AACF;AAIF;;AAG0D;AAGtD;;;;;AAGEC;AACAC;AACAC;;AACD;AAGL;AAA2C;;AAE3C;;AAE6D;;;AAG3D;;;AAGF;AACA;AACA;AACA;AAAiD;AAC/C;;AAEE;AACF;AAEA;;;AAKE;AACF;;AAEA;AACA;;;;AASF;;AAGM;AACF;;AAEA;AACA;AACEC;AAAW;;AACX;AACF;;AAEA;;;AAGEA;AAAW;;AACb;AACF;AAIF;AAA6C;AAC3C;;AAGE;AACF;;AAGE;AACE;;AAEA;AACA;AACF;;;AAGIC;AACA;AACF;AACAC;AACA;AACF;;;AAGID;AACA;AACF;AACAC;AACA;AACF;;;AAGE;AACA;AACF;AACA;;AAGE;AACE;;AAEE;AACF;AACAD;AACF;;;AAWA;AACA;AAGJ;;AAGF;AAEIE;;AAEI;AACF;;;;AAIFC;AACAC;AACA;AACA;AACA;AACAC;AAA0B;;AAIxBH;AACAI;AACAZ;AACAa;AACAC;AACE;;AAEE;AACF;;AAIAR;;;AAG0C;AAE/BS;AAEGC;AAAY;AAEVA;;AACjB;AAICC;AACA;AAGAT;AACAR;AACAF;AAAqBiB;AAER;;;;;AAGTE;AAEAP;;AAEA;AACAF;;;AAGA;AAAA;AACAU;AACE;AACE;AACF;AACAC;AACEC;AACF;;;AAEa;;;;AAOb;AACE;AACF;AAEAC;;AACAN;AAEI;;AAER;AAEL;AAGP;AAEA;;"}
1
+ {"version":3,"file":"index.esm.js","sources":["../../../../../src/Inputs/Select/DesignedSelect/index.tsx"],"sourcesContent":["'use client';\n\nimport { IconArrow2Down, IconArrow2Up } from '@remember-web/icon';\nimport type { KeyboardEvent, ReactNode, Ref, RefCallback } from 'react';\nimport {\n Children,\n forwardRef,\n isValidElement,\n useCallback,\n useId,\n useRef,\n useState,\n} from 'react';\n\nimport useMouseEventAway from '@/hooks/useMouseEventAway';\n\nimport { OptionHolder } from '../Option';\nimport { SelectContainer } from '../styles';\nimport type { OptionElementType, SelectValue } from '../types';\nimport { focusSibling } from '../utils';\nimport { DEFAULT_MAX_HEIGHT_PX, OPTION_ITEM_HEIGHT_PX } from './const';\nimport {\n SelectDownIcon,\n SelectOption,\n SelectOptionWrapper,\n StyledSelect,\n} from './styles';\nimport type { DesignedSelectInternalProps, ExpandedType } from './types';\n\nconst DesignedSelect = <Value extends SelectValue>(\n {\n children,\n value,\n maxHeight = DEFAULT_MAX_HEIGHT_PX,\n placeholder,\n onChange,\n width,\n extendDirection,\n error = false,\n disabled,\n onClick,\n ...props\n }: DesignedSelectInternalProps<Value>,\n ref?: Ref<HTMLDivElement>\n) => {\n const id = useId();\n const [expandedDirection, _setExpandedDirection] =\n useState<ExpandedType>('none');\n const selectContainerRef = useRef<HTMLDivElement | null>(null);\n const selectListRef = useRef<HTMLUListElement | null>(null);\n const clickAwayRef = useMouseEventAway<HTMLDivElement, 'pointerdown'>(\n 'pointerdown',\n () => {\n setExpandedDirection('none');\n }\n );\n\n const setExpandedDirection = useCallback(\n (...args: Parameters<typeof _setExpandedDirection>) => {\n if (disabled) {\n return;\n }\n _setExpandedDirection(...args);\n },\n [disabled]\n );\n\n const options = Children.toArray(children)\n .filter(\n (child): child is OptionElementType<Value> =>\n isValidElement(child) && child.type === OptionHolder\n )\n .map(\n ({\n props: { children: _children, value: _value, disabled: _disabled },\n }) => ({\n label: _children,\n value: _value,\n disabled: _disabled,\n })\n );\n\n const selectedOption = options.find((option) => value === option.value);\n\n const isExpanded = expandedDirection !== 'none';\n\n const onSelectOption = (_value: Value, _label: ReactNode) => {\n onChange?.(_value, _label);\n setExpandedDirection('none');\n selectContainerRef.current?.focus();\n };\n\n // 리스트가 하단으로 나와야하는지 상단으로 나와야하는지 계산하는 함수\n // 현재 Viewport기준으로 Select컴포넌트가 아래로 확장되었을 때 뷰포트 내에 리스트박스가 노출될 수 있다면 하단으로 확장, 아니라면 상단으로 확장\n // direction이 props로 전달되었다면 해당 방향으로 확장\n const expandSelectListAtComputedPosition = () => {\n if (extendDirection) {\n setExpandedDirection(extendDirection);\n return;\n }\n\n const selectContainerRect =\n selectContainerRef.current?.getBoundingClientRect();\n\n if (!selectContainerRect) {\n setExpandedDirection('below');\n return;\n }\n\n // SelectOptionWrapper가 마운트되기 전에 계산해야 하기 때문에 clientHeight를 사용하지 못하고 직접 계산\n const currentSelectHeight = Math.min(\n maxHeight,\n options.length * OPTION_ITEM_HEIGHT_PX\n );\n const bottomGap = document.body.clientHeight - selectContainerRect.bottom;\n\n setExpandedDirection(currentSelectHeight > bottomGap ? 'above' : 'below');\n };\n\n const optionItemRef = useCallback<RefCallback<HTMLLIElement>>(\n (ele) => {\n if (!ele) {\n return;\n }\n\n // 선택한 요소가 없을때는 첫번째 요소에 focus\n if (!value && !ele.previousSibling) {\n setTimeout(() => ele.focus());\n return;\n }\n\n // 선택한 요소가 있다면 해당 요소에 focus\n const optionValue = ele.dataset.optionValue || null;\n if (optionValue === value) {\n setTimeout(() => ele.focus());\n }\n },\n [value]\n );\n\n const keyDownHandler = (e: KeyboardEvent) => {\n const focusedElement = document.activeElement;\n\n if (!focusedElement || !(focusedElement instanceof HTMLElement)) {\n return;\n }\n\n switch (e.key) {\n case 'Tab':\n if (isExpanded) {\n e.preventDefault();\n }\n break;\n case 'ArrowUp':\n e.preventDefault();\n if (!isExpanded) {\n expandSelectListAtComputedPosition();\n break;\n }\n focusSibling(focusedElement, 'previous');\n break;\n case 'ArrowDown':\n e.preventDefault();\n if (!isExpanded) {\n expandSelectListAtComputedPosition();\n break;\n }\n focusSibling(focusedElement, 'next');\n break;\n case 'Escape':\n e.preventDefault();\n setExpandedDirection('none');\n selectContainerRef.current?.focus();\n break;\n case 'Enter':\n case ' ':\n e.preventDefault();\n\n if (e.target === e.currentTarget) {\n if (isExpanded) {\n setExpandedDirection('none');\n return;\n }\n expandSelectListAtComputedPosition();\n }\n\n if (\n focusedElement?.matches('[data-option-value]') &&\n focusedElement instanceof HTMLLIElement &&\n focusedElement.dataset.optionValue\n ) {\n onSelectOption(\n focusedElement.dataset.optionValue as Value,\n focusedElement.innerText\n );\n }\n break;\n default:\n break;\n }\n };\n\n return (\n <SelectContainer\n ref={(el) => {\n if (!el) {\n return;\n }\n selectContainerRef.current = el;\n clickAwayRef.current = el;\n }}\n $width={width}\n tabIndex={disabled ? undefined : 0}\n aria-expanded={isExpanded}\n aria-haspopup=\"listbox\"\n aria-disabled={disabled}\n $error={error}\n onKeyDown={keyDownHandler}\n {...props}\n >\n <StyledSelect\n ref={ref}\n onClick={onClick}\n expandedDirection={expandedDirection}\n isPlaceholder={!selectedOption && !!placeholder}\n onPointerDown={(e) => {\n if (isExpanded) {\n setExpandedDirection('none');\n return;\n }\n\n e.stopPropagation();\n\n expandSelectListAtComputedPosition();\n }}\n >\n {selectedOption?.label || placeholder || 'ㅤ'}\n </StyledSelect>\n <SelectDownIcon>\n {isExpanded ? (\n <IconArrow2Up size=\"small\" />\n ) : (\n <IconArrow2Down size=\"small\" />\n )}\n </SelectDownIcon>\n {isExpanded && (\n <SelectOptionWrapper\n role=\"listbox\"\n aria-activedescendant={\n value != null ? `${id}-select-option-${value}` : undefined\n }\n ref={selectListRef}\n expandedDirection={expandedDirection}\n maxHeight={maxHeight}\n >\n {options.map(({ value: optionValue, label, disabled: _disabled }) => (\n <SelectOption\n id={`${id}-select-option-${optionValue}`}\n role=\"option\"\n key={optionValue}\n tabIndex={_disabled ? undefined : 0}\n aria-selected={optionValue === value}\n aria-disabled={_disabled}\n ref={optionItemRef}\n isSelected={optionValue === value}\n data-option-value={optionValue}\n // onMouseEnter를 사용하게 되면 키보드로 스크롤 할 때도 focus가 이동하게 되기 때문에 onMouseMove를 사용\n onMouseMove={(e) => {\n if (e.currentTarget === document.activeElement) {\n return;\n }\n e.currentTarget.focus({\n preventScroll: true,\n });\n }}\n onFocus={() => {\n selectListRef.current?.setAttribute(\n 'aria-activedescendant',\n `${id}-select-option-${optionValue}`\n );\n }}\n onClick={() => {\n if (_disabled) {\n return;\n }\n\n onSelectOption(optionValue, label);\n }}\n >\n {label}\n </SelectOption>\n ))}\n </SelectOptionWrapper>\n )}\n </SelectContainer>\n );\n};\n\nexport default forwardRef(DesignedSelect);\n"],"names":["maxHeight","error","props","expandedDirection","_setExpandedDirection","label","value","disabled","setTimeout","expandSelectListAtComputedPosition","focusSibling","ref","$width","tabIndex","$error","onKeyDown","onClick","isPlaceholder","onPointerDown","children","size","role","onMouseMove","e","preventScroll","onSelectOption"],"mappings":";;;;;;;;;;;;;;AAAa;AAAA;AAAA;AA6Bb;AAeK;;;AAXDA;;;;;;AAKAC;;;AAGGC;AAIL;AACA;;AAAOC;AAAmBC;AAE1B;AACA;AACA;;AAIE;AAGF;AAEI;AACE;AACF;AACAA;AACF;AAIF;;AAG0D;AAGtD;;;;;AAGEC;AACAC;AACAC;;AACD;AAGL;AAA2C;;AAE3C;;AAE6D;;;AAG3D;;;AAGF;AACA;AACA;AACA;AAAiD;AAC/C;;AAEE;AACF;AAEA;;;AAKE;AACF;;AAEA;AACA;;;;AASF;;AAGM;AACF;;AAEA;AACA;AACEC;AAAW;;AACX;AACF;;AAEA;;;AAGEA;AAAW;;AACb;AACF;AAIF;AAA6C;AAC3C;;AAGE;AACF;;AAGE;AACE;;AAEA;AACA;AACF;;;AAGIC;AACA;AACF;AACAC;AACA;AACF;;;AAGID;AACA;AACF;AACAC;AACA;AACF;;;AAGE;AACA;AACF;AACA;;AAGE;AACE;;AAEE;AACF;AACAD;AACF;;;AAWA;AACA;AAGJ;;AAGF;AAEIE;;AAEI;AACF;;;;AAIFC;AACAC;AACA;AACA;AACA;AACAC;AACAC;AAA0B;;AAIxBJ;AACAK;AACAb;AACAc;AACAC;AACE;;AAEE;AACF;;AAIAT;;;AAG0C;AAE/BU;AAEGC;AAAY;AAEVA;;AACjB;AAICC;AACA;AAGAV;AACAR;AACAH;AAAqBmB;AAER;;;;;AAGTE;AAEAR;;AAEA;AACAF;;;AAGA;AAAA;AACAW;AACE;AACE;AACF;AACAC;AACEC;AACF;;;AAEa;;;;AAOb;AACE;AACF;AAEAC;;AACAN;AAEI;;AAER;AAEL;AAGP;AAEA;;"}
@@ -12,7 +12,7 @@ var _taggedTemplateLiteral__default = /*#__PURE__*/_interopDefault(_taggedTempla
12
12
  var styled__default = /*#__PURE__*/_interopDefault(styled);
13
13
 
14
14
  var _templateObject, _templateObject2, _templateObject3, _templateObject4, _templateObject5, _templateObject6, _templateObject7, _templateObject8, _templateObject9, _templateObject10, _templateObject11, _templateObject12, _templateObject13;
15
- var StyledSelect = styled__default.default.div(_templateObject || (_templateObject = _taggedTemplateLiteral__default.default(["\n ", "\n border: 1px solid ", ";\n ", ";\n\n padding: 10px 36px 10px 12px;\n transition: border-color 0.2s, background-color 0.2s;\n\n ", "\n\n ", ":focus-within & {\n outline: none;\n border-color: ", ";\n }\n ", ":not([aria-disabled='true']) & {\n @media (hover: hover) {\n &:hover {\n background-color: ", ";\n }\n }\n\n &:active {\n background-color: ", ";\n }\n }\n"])), mixin.ellipsis(), mixin.contents300, function (_ref) {
15
+ var StyledSelect = styled__default.default.div(_templateObject || (_templateObject = _taggedTemplateLiteral__default.default(["\n ", "\n border-width: 1px;\n border-style: solid;;\n\n ", ";\n\n padding: 10px 36px 10px 12px;\n transition: border-color 0.2s, background-color 0.2s;\n\n ", "\n\n ", ":focus-within & {\n outline: none;\n }\n\n ", ":not([aria-disabled='true']) & {\n @media (hover: hover) {\n &:hover {\n background-color: ", ";\n }\n }\n\n &:active {\n background-color: ", ";\n }\n }\n\n border-color: var(--border-color);\n"])), mixin.ellipsis(), function (_ref) {
16
16
  var expandedDirection = _ref.expandedDirection;
17
17
  return {
18
18
  none: styled.css(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral__default.default(["\n border-radius: 4px;\n "]))),
@@ -22,9 +22,9 @@ var StyledSelect = styled__default.default.div(_templateObject || (_templateObje
22
22
  }, function (_ref2) {
23
23
  var isPlaceholder = _ref2.isPlaceholder;
24
24
  return isPlaceholder && styled.css(_templateObject5 || (_templateObject5 = _taggedTemplateLiteral__default.default(["\n color: ", ";\n "])), mixin.contents200);
25
- }, styles.SelectContainer, mixin.contents000, styles.SelectContainer, mixin.bg200, mixin.bg300);
25
+ }, styles.SelectContainer, styles.SelectContainer, mixin.bg200, mixin.bg300);
26
26
  var SelectDownIcon = styled__default.default.div(_templateObject6 || (_templateObject6 = _taggedTemplateLiteral__default.default(["\n position: absolute;\n right: 12px;\n top: 50%;\n transform: translateY(-50%);\n\n & > svg {\n display: block;\n }\n\n pointer-events: none;\n"])));
27
- var SelectOptionWrapper = styled__default.default.ul(_templateObject7 || (_templateObject7 = _taggedTemplateLiteral__default.default(["\n all: unset;\n position: absolute;\n left: 0;\n right: 0;\n z-index: 1;\n border: 1px solid ", ";\n background-color: ", ";\n overflow-y: auto;\n overscroll-behavior: contain;\n transition: border-color 0.2s, background-color 0.2s;\n\n ", ";\n\n ", "\n\n ", ":focus &, ", ":focus-within & {\n outline: none;\n border-color: ", ";\n }\n"])), mixin.contents300, mixin.bg100, function (_ref3) {
27
+ var SelectOptionWrapper = styled__default.default.ul(_templateObject7 || (_templateObject7 = _taggedTemplateLiteral__default.default(["\n all: unset;\n position: absolute;\n left: 0;\n right: 0;\n z-index: 1;\n \n border-width: 1px;\n border-style: solid;;\n\n background-color: ", ";\n overflow-y: auto;\n overscroll-behavior: contain;\n transition: border-color 0.2s, background-color 0.2s;\n\n ", ";\n\n ", "\n\n ", ":focus &, ", ":focus-within & {\n outline: none;\n }\n\n border-color: var(--border-color);\n"])), mixin.bg100, function (_ref3) {
28
28
  var maxHeight = _ref3.maxHeight;
29
29
  if (!maxHeight) {
30
30
  return null;
@@ -36,7 +36,7 @@ var SelectOptionWrapper = styled__default.default.ul(_templateObject7 || (_templ
36
36
  }, function (_ref4) {
37
37
  var expandedDirection = _ref4.expandedDirection;
38
38
  return expandedDirection === 'below' ? styled.css(_templateObject10 || (_templateObject10 = _taggedTemplateLiteral__default.default(["\n top: calc(100% - 1px);\n border-top: none;\n border-radius: 0 0 4px 4px;\n "]))) : styled.css(_templateObject11 || (_templateObject11 = _taggedTemplateLiteral__default.default(["\n bottom: calc(100% - 1px);\n border-bottom: none;\n border-radius: 4px 4px 0 0;\n "])));
39
- }, styles.SelectContainer, styles.SelectContainer, mixin.contents000);
39
+ }, styles.SelectContainer, styles.SelectContainer);
40
40
  var SelectOption = styled__default.default.li(_templateObject12 || (_templateObject12 = _taggedTemplateLiteral__default.default(["\n ", "\n padding: 10px 12px;\n color: ", ";\n\n &[aria-disabled='true'] {\n color: ", ";\n }\n\n &:focus {\n background-color: ", ";\n outline: none;\n }\n\n ", "\n"])), mixin.ellipsis(), mixin.contents000, mixin.contents300, mixin.bg200, function (_ref5) {
41
41
  var isSelected = _ref5.isSelected;
42
42
  return isSelected && styled.css(_templateObject13 || (_templateObject13 = _taggedTemplateLiteral__default.default(["\n background-color: ", ";\n "])), mixin.bg200);
@@ -1 +1 @@
1
- {"version":3,"file":"styles.cjs.js","sources":["../../../../../src/Inputs/Select/DesignedSelect/styles.ts"],"sourcesContent":["'use client';\n\nimport {\n bg100,\n bg200,\n bg300,\n contents000,\n contents200,\n contents300,\n ellipsis,\n} from '@remember-web/mixin';\nimport styled, { css } from 'styled-components';\n\nimport { SelectContainer } from '../styles';\nimport type { ExpandedType } from './types';\n\nexport const StyledSelect = styled.div<{\n expandedDirection?: ExpandedType;\n isPlaceholder?: boolean;\n}>`\n ${ellipsis()}\n border: 1px solid ${contents300};\n ${({ expandedDirection }) =>\n ({\n none: css`\n border-radius: 4px;\n `,\n above: css`\n border-radius: 0 0 4px 4px;\n border-top-color: transparent;\n `,\n below: css`\n border-radius: 4px 4px 0 0;\n border-bottom-color: transparent;\n `,\n })[expandedDirection ?? 'none']};\n\n padding: 10px 36px 10px 12px;\n transition: border-color 0.2s, background-color 0.2s;\n\n ${({ isPlaceholder }) =>\n isPlaceholder &&\n css`\n color: ${contents200};\n `}\n\n ${SelectContainer}:focus-within & {\n outline: none;\n border-color: ${contents000};\n }\n ${SelectContainer}:not([aria-disabled='true']) & {\n @media (hover: hover) {\n &:hover {\n background-color: ${bg200};\n }\n }\n\n &:active {\n background-color: ${bg300};\n }\n }\n`;\n\nexport const SelectDownIcon = styled.div`\n position: absolute;\n right: 12px;\n top: 50%;\n transform: translateY(-50%);\n\n & > svg {\n display: block;\n }\n\n pointer-events: none;\n`;\n\nexport const SelectOptionWrapper = styled.ul<{\n expandedDirection?: ExpandedType;\n maxHeight?: number | string;\n}>`\n all: unset;\n position: absolute;\n left: 0;\n right: 0;\n z-index: 1;\n border: 1px solid ${contents300};\n background-color: ${bg100};\n overflow-y: auto;\n overscroll-behavior: contain;\n transition: border-color 0.2s, background-color 0.2s;\n\n ${({ maxHeight }) => {\n if (!maxHeight) {\n return null;\n }\n\n if (typeof maxHeight === 'number') {\n return css`\n max-height: ${maxHeight}px;\n `;\n }\n\n return css`\n max-height: ${maxHeight};\n `;\n }};\n\n ${({ expandedDirection }) =>\n expandedDirection === 'below'\n ? css`\n top: calc(100% - 1px);\n border-top: none;\n border-radius: 0 0 4px 4px;\n `\n : css`\n bottom: calc(100% - 1px);\n border-bottom: none;\n border-radius: 4px 4px 0 0;\n `}\n\n ${SelectContainer}:focus &, ${SelectContainer}:focus-within & {\n outline: none;\n border-color: ${contents000};\n }\n`;\n\nexport const SelectOption = styled.li<{ isSelected?: boolean }>`\n ${ellipsis()}\n padding: 10px 12px;\n color: ${contents000};\n\n &[aria-disabled='true'] {\n color: ${contents300};\n }\n\n &:focus {\n background-color: ${bg200};\n outline: none;\n }\n\n ${({ isSelected }) =>\n isSelected &&\n css`\n background-color: ${bg200};\n `}\n`;\n"],"names":["below"],"mappings":";;;;;;;;;;;;;AAAa;AAgBN;AAMH;;;;AASEA;;AAI6B;AAK/B;;AAIC;AAmBE;;AA4BgB;;AAEjB;AACF;AAEA;;AAIA;;AAKF;AAEE;AAAoB;AAWf;AAQF;AAcH;;AAIC;;;;;"}
1
+ {"version":3,"file":"styles.cjs.js","sources":["../../../../../src/Inputs/Select/DesignedSelect/styles.ts"],"sourcesContent":["'use client';\n\nimport {\n bg100,\n bg200,\n bg300,\n contents000,\n contents200,\n contents300,\n ellipsis,\n} from '@remember-web/mixin';\nimport styled, { css } from 'styled-components';\n\nimport { SelectContainer } from '../styles';\nimport type { ExpandedType } from './types';\n\nexport const StyledSelect = styled.div<{\n expandedDirection?: ExpandedType;\n isPlaceholder?: boolean;\n}>`\n ${ellipsis()}\n border-width: 1px;\n border-style: solid;;\n\n ${({ expandedDirection }) =>\n ({\n none: css`\n border-radius: 4px;\n `,\n above: css`\n border-radius: 0 0 4px 4px;\n border-top-color: transparent;\n `,\n below: css`\n border-radius: 4px 4px 0 0;\n border-bottom-color: transparent;\n `,\n })[expandedDirection ?? 'none']};\n\n padding: 10px 36px 10px 12px;\n transition: border-color 0.2s, background-color 0.2s;\n\n ${({ isPlaceholder }) =>\n isPlaceholder &&\n css`\n color: ${contents200};\n `}\n\n ${SelectContainer}:focus-within & {\n outline: none;\n }\n\n ${SelectContainer}:not([aria-disabled='true']) & {\n @media (hover: hover) {\n &:hover {\n background-color: ${bg200};\n }\n }\n\n &:active {\n background-color: ${bg300};\n }\n }\n\n border-color: var(--border-color);\n`;\n\nexport const SelectDownIcon = styled.div`\n position: absolute;\n right: 12px;\n top: 50%;\n transform: translateY(-50%);\n\n & > svg {\n display: block;\n }\n\n pointer-events: none;\n`;\n\nexport const SelectOptionWrapper = styled.ul<{\n expandedDirection?: ExpandedType;\n maxHeight?: number | string;\n}>`\n all: unset;\n position: absolute;\n left: 0;\n right: 0;\n z-index: 1;\n \n border-width: 1px;\n border-style: solid;;\n\n background-color: ${bg100};\n overflow-y: auto;\n overscroll-behavior: contain;\n transition: border-color 0.2s, background-color 0.2s;\n\n ${({ maxHeight }) => {\n if (!maxHeight) {\n return null;\n }\n\n if (typeof maxHeight === 'number') {\n return css`\n max-height: ${maxHeight}px;\n `;\n }\n\n return css`\n max-height: ${maxHeight};\n `;\n }};\n\n ${({ expandedDirection }) =>\n expandedDirection === 'below'\n ? css`\n top: calc(100% - 1px);\n border-top: none;\n border-radius: 0 0 4px 4px;\n `\n : css`\n bottom: calc(100% - 1px);\n border-bottom: none;\n border-radius: 4px 4px 0 0;\n `}\n\n ${SelectContainer}:focus &, ${SelectContainer}:focus-within & {\n outline: none;\n }\n\n border-color: var(--border-color);\n`;\n\nexport const SelectOption = styled.li<{ isSelected?: boolean }>`\n ${ellipsis()}\n padding: 10px 12px;\n color: ${contents000};\n\n &[aria-disabled='true'] {\n color: ${contents300};\n }\n\n &:focus {\n background-color: ${bg200};\n outline: none;\n }\n\n ${({ isSelected }) =>\n isSelected &&\n css`\n background-color: ${bg200};\n `}\n`;\n"],"names":["below"],"mappings":";;;;;;;;;;;;;AAAa;;AAwBT;;;;AASEA;;AAI6B;AAK/B;;AAIC;AAqBE;;AA+BgB;;AAEjB;AACF;AAEA;;AAIA;;AAKF;AAEE;AAAoB;AAWf;AASF;AAcH;;AAIC;;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../../../../../src/Inputs/Select/DesignedSelect/styles.ts"],"names":[],"mappings":";AAcA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE5C,eAAO,MAAM,YAAY;;;GA6CxB,CAAC;AAEF,eAAO,MAAM,cAAc,gNAW1B,CAAC;AAEF,eAAO,MAAM,mBAAmB;;;GAgD/B,CAAC;AAEF,eAAO,MAAM,YAAY;;GAmBxB,CAAC"}
1
+ {"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../../../../../src/Inputs/Select/DesignedSelect/styles.ts"],"names":[],"mappings":";AAcA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE5C,eAAO,MAAM,YAAY;;;GAiDxB,CAAC;AAEF,eAAO,MAAM,cAAc,gNAW1B,CAAC;AAEF,eAAO,MAAM,mBAAmB;;;GAoD/B,CAAC;AAEF,eAAO,MAAM,YAAY;;GAmBxB,CAAC"}
@@ -1,11 +1,11 @@
1
1
  "use client";
2
2
  import _taggedTemplateLiteral from '@babel/runtime/helpers/taggedTemplateLiteral';
3
- import { ellipsis, contents300, contents200, contents000, bg200, bg300, bg100 } from '@remember-web/mixin';
3
+ import { ellipsis, contents200, bg200, bg300, bg100, contents000, contents300 } from '@remember-web/mixin';
4
4
  import styled, { css } from 'styled-components';
5
5
  import { SelectContainer } from '../styles.esm.js';
6
6
 
7
7
  var _templateObject, _templateObject2, _templateObject3, _templateObject4, _templateObject5, _templateObject6, _templateObject7, _templateObject8, _templateObject9, _templateObject10, _templateObject11, _templateObject12, _templateObject13;
8
- var StyledSelect = styled.div(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n ", "\n border: 1px solid ", ";\n ", ";\n\n padding: 10px 36px 10px 12px;\n transition: border-color 0.2s, background-color 0.2s;\n\n ", "\n\n ", ":focus-within & {\n outline: none;\n border-color: ", ";\n }\n ", ":not([aria-disabled='true']) & {\n @media (hover: hover) {\n &:hover {\n background-color: ", ";\n }\n }\n\n &:active {\n background-color: ", ";\n }\n }\n"])), ellipsis(), contents300, function (_ref) {
8
+ var StyledSelect = styled.div(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n ", "\n border-width: 1px;\n border-style: solid;;\n\n ", ";\n\n padding: 10px 36px 10px 12px;\n transition: border-color 0.2s, background-color 0.2s;\n\n ", "\n\n ", ":focus-within & {\n outline: none;\n }\n\n ", ":not([aria-disabled='true']) & {\n @media (hover: hover) {\n &:hover {\n background-color: ", ";\n }\n }\n\n &:active {\n background-color: ", ";\n }\n }\n\n border-color: var(--border-color);\n"])), ellipsis(), function (_ref) {
9
9
  var expandedDirection = _ref.expandedDirection;
10
10
  return {
11
11
  none: css(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\n border-radius: 4px;\n "]))),
@@ -15,9 +15,9 @@ var StyledSelect = styled.div(_templateObject || (_templateObject = _taggedTempl
15
15
  }, function (_ref2) {
16
16
  var isPlaceholder = _ref2.isPlaceholder;
17
17
  return isPlaceholder && css(_templateObject5 || (_templateObject5 = _taggedTemplateLiteral(["\n color: ", ";\n "])), contents200);
18
- }, SelectContainer, contents000, SelectContainer, bg200, bg300);
18
+ }, SelectContainer, SelectContainer, bg200, bg300);
19
19
  var SelectDownIcon = styled.div(_templateObject6 || (_templateObject6 = _taggedTemplateLiteral(["\n position: absolute;\n right: 12px;\n top: 50%;\n transform: translateY(-50%);\n\n & > svg {\n display: block;\n }\n\n pointer-events: none;\n"])));
20
- var SelectOptionWrapper = styled.ul(_templateObject7 || (_templateObject7 = _taggedTemplateLiteral(["\n all: unset;\n position: absolute;\n left: 0;\n right: 0;\n z-index: 1;\n border: 1px solid ", ";\n background-color: ", ";\n overflow-y: auto;\n overscroll-behavior: contain;\n transition: border-color 0.2s, background-color 0.2s;\n\n ", ";\n\n ", "\n\n ", ":focus &, ", ":focus-within & {\n outline: none;\n border-color: ", ";\n }\n"])), contents300, bg100, function (_ref3) {
20
+ var SelectOptionWrapper = styled.ul(_templateObject7 || (_templateObject7 = _taggedTemplateLiteral(["\n all: unset;\n position: absolute;\n left: 0;\n right: 0;\n z-index: 1;\n \n border-width: 1px;\n border-style: solid;;\n\n background-color: ", ";\n overflow-y: auto;\n overscroll-behavior: contain;\n transition: border-color 0.2s, background-color 0.2s;\n\n ", ";\n\n ", "\n\n ", ":focus &, ", ":focus-within & {\n outline: none;\n }\n\n border-color: var(--border-color);\n"])), bg100, function (_ref3) {
21
21
  var maxHeight = _ref3.maxHeight;
22
22
  if (!maxHeight) {
23
23
  return null;
@@ -29,7 +29,7 @@ var SelectOptionWrapper = styled.ul(_templateObject7 || (_templateObject7 = _tag
29
29
  }, function (_ref4) {
30
30
  var expandedDirection = _ref4.expandedDirection;
31
31
  return expandedDirection === 'below' ? css(_templateObject10 || (_templateObject10 = _taggedTemplateLiteral(["\n top: calc(100% - 1px);\n border-top: none;\n border-radius: 0 0 4px 4px;\n "]))) : css(_templateObject11 || (_templateObject11 = _taggedTemplateLiteral(["\n bottom: calc(100% - 1px);\n border-bottom: none;\n border-radius: 4px 4px 0 0;\n "])));
32
- }, SelectContainer, SelectContainer, contents000);
32
+ }, SelectContainer, SelectContainer);
33
33
  var SelectOption = styled.li(_templateObject12 || (_templateObject12 = _taggedTemplateLiteral(["\n ", "\n padding: 10px 12px;\n color: ", ";\n\n &[aria-disabled='true'] {\n color: ", ";\n }\n\n &:focus {\n background-color: ", ";\n outline: none;\n }\n\n ", "\n"])), ellipsis(), contents000, contents300, bg200, function (_ref5) {
34
34
  var isSelected = _ref5.isSelected;
35
35
  return isSelected && css(_templateObject13 || (_templateObject13 = _taggedTemplateLiteral(["\n background-color: ", ";\n "])), bg200);
@@ -1 +1 @@
1
- {"version":3,"file":"styles.esm.js","sources":["../../../../../src/Inputs/Select/DesignedSelect/styles.ts"],"sourcesContent":["'use client';\n\nimport {\n bg100,\n bg200,\n bg300,\n contents000,\n contents200,\n contents300,\n ellipsis,\n} from '@remember-web/mixin';\nimport styled, { css } from 'styled-components';\n\nimport { SelectContainer } from '../styles';\nimport type { ExpandedType } from './types';\n\nexport const StyledSelect = styled.div<{\n expandedDirection?: ExpandedType;\n isPlaceholder?: boolean;\n}>`\n ${ellipsis()}\n border: 1px solid ${contents300};\n ${({ expandedDirection }) =>\n ({\n none: css`\n border-radius: 4px;\n `,\n above: css`\n border-radius: 0 0 4px 4px;\n border-top-color: transparent;\n `,\n below: css`\n border-radius: 4px 4px 0 0;\n border-bottom-color: transparent;\n `,\n })[expandedDirection ?? 'none']};\n\n padding: 10px 36px 10px 12px;\n transition: border-color 0.2s, background-color 0.2s;\n\n ${({ isPlaceholder }) =>\n isPlaceholder &&\n css`\n color: ${contents200};\n `}\n\n ${SelectContainer}:focus-within & {\n outline: none;\n border-color: ${contents000};\n }\n ${SelectContainer}:not([aria-disabled='true']) & {\n @media (hover: hover) {\n &:hover {\n background-color: ${bg200};\n }\n }\n\n &:active {\n background-color: ${bg300};\n }\n }\n`;\n\nexport const SelectDownIcon = styled.div`\n position: absolute;\n right: 12px;\n top: 50%;\n transform: translateY(-50%);\n\n & > svg {\n display: block;\n }\n\n pointer-events: none;\n`;\n\nexport const SelectOptionWrapper = styled.ul<{\n expandedDirection?: ExpandedType;\n maxHeight?: number | string;\n}>`\n all: unset;\n position: absolute;\n left: 0;\n right: 0;\n z-index: 1;\n border: 1px solid ${contents300};\n background-color: ${bg100};\n overflow-y: auto;\n overscroll-behavior: contain;\n transition: border-color 0.2s, background-color 0.2s;\n\n ${({ maxHeight }) => {\n if (!maxHeight) {\n return null;\n }\n\n if (typeof maxHeight === 'number') {\n return css`\n max-height: ${maxHeight}px;\n `;\n }\n\n return css`\n max-height: ${maxHeight};\n `;\n }};\n\n ${({ expandedDirection }) =>\n expandedDirection === 'below'\n ? css`\n top: calc(100% - 1px);\n border-top: none;\n border-radius: 0 0 4px 4px;\n `\n : css`\n bottom: calc(100% - 1px);\n border-bottom: none;\n border-radius: 4px 4px 0 0;\n `}\n\n ${SelectContainer}:focus &, ${SelectContainer}:focus-within & {\n outline: none;\n border-color: ${contents000};\n }\n`;\n\nexport const SelectOption = styled.li<{ isSelected?: boolean }>`\n ${ellipsis()}\n padding: 10px 12px;\n color: ${contents000};\n\n &[aria-disabled='true'] {\n color: ${contents300};\n }\n\n &:focus {\n background-color: ${bg200};\n outline: none;\n }\n\n ${({ isSelected }) =>\n isSelected &&\n css`\n background-color: ${bg200};\n `}\n`;\n"],"names":["below"],"mappings":";;;;;;AAAa;AAgBN;AAMH;;;;AASEA;;AAI6B;AAK/B;;AAIC;AAmBE;;AA4BgB;;AAEjB;AACF;AAEA;;AAIA;;AAKF;AAEE;AAAoB;AAWf;AAQF;AAcH;;AAIC;;"}
1
+ {"version":3,"file":"styles.esm.js","sources":["../../../../../src/Inputs/Select/DesignedSelect/styles.ts"],"sourcesContent":["'use client';\n\nimport {\n bg100,\n bg200,\n bg300,\n contents000,\n contents200,\n contents300,\n ellipsis,\n} from '@remember-web/mixin';\nimport styled, { css } from 'styled-components';\n\nimport { SelectContainer } from '../styles';\nimport type { ExpandedType } from './types';\n\nexport const StyledSelect = styled.div<{\n expandedDirection?: ExpandedType;\n isPlaceholder?: boolean;\n}>`\n ${ellipsis()}\n border-width: 1px;\n border-style: solid;;\n\n ${({ expandedDirection }) =>\n ({\n none: css`\n border-radius: 4px;\n `,\n above: css`\n border-radius: 0 0 4px 4px;\n border-top-color: transparent;\n `,\n below: css`\n border-radius: 4px 4px 0 0;\n border-bottom-color: transparent;\n `,\n })[expandedDirection ?? 'none']};\n\n padding: 10px 36px 10px 12px;\n transition: border-color 0.2s, background-color 0.2s;\n\n ${({ isPlaceholder }) =>\n isPlaceholder &&\n css`\n color: ${contents200};\n `}\n\n ${SelectContainer}:focus-within & {\n outline: none;\n }\n\n ${SelectContainer}:not([aria-disabled='true']) & {\n @media (hover: hover) {\n &:hover {\n background-color: ${bg200};\n }\n }\n\n &:active {\n background-color: ${bg300};\n }\n }\n\n border-color: var(--border-color);\n`;\n\nexport const SelectDownIcon = styled.div`\n position: absolute;\n right: 12px;\n top: 50%;\n transform: translateY(-50%);\n\n & > svg {\n display: block;\n }\n\n pointer-events: none;\n`;\n\nexport const SelectOptionWrapper = styled.ul<{\n expandedDirection?: ExpandedType;\n maxHeight?: number | string;\n}>`\n all: unset;\n position: absolute;\n left: 0;\n right: 0;\n z-index: 1;\n \n border-width: 1px;\n border-style: solid;;\n\n background-color: ${bg100};\n overflow-y: auto;\n overscroll-behavior: contain;\n transition: border-color 0.2s, background-color 0.2s;\n\n ${({ maxHeight }) => {\n if (!maxHeight) {\n return null;\n }\n\n if (typeof maxHeight === 'number') {\n return css`\n max-height: ${maxHeight}px;\n `;\n }\n\n return css`\n max-height: ${maxHeight};\n `;\n }};\n\n ${({ expandedDirection }) =>\n expandedDirection === 'below'\n ? css`\n top: calc(100% - 1px);\n border-top: none;\n border-radius: 0 0 4px 4px;\n `\n : css`\n bottom: calc(100% - 1px);\n border-bottom: none;\n border-radius: 4px 4px 0 0;\n `}\n\n ${SelectContainer}:focus &, ${SelectContainer}:focus-within & {\n outline: none;\n }\n\n border-color: var(--border-color);\n`;\n\nexport const SelectOption = styled.li<{ isSelected?: boolean }>`\n ${ellipsis()}\n padding: 10px 12px;\n color: ${contents000};\n\n &[aria-disabled='true'] {\n color: ${contents300};\n }\n\n &:focus {\n background-color: ${bg200};\n outline: none;\n }\n\n ${({ isSelected }) =>\n isSelected &&\n css`\n background-color: ${bg200};\n `}\n`;\n"],"names":["below"],"mappings":";;;;;;AAAa;;AAwBT;;;;AASEA;;AAI6B;AAK/B;;AAIC;AAqBE;;AA+BgB;;AAEjB;AACF;AAEA;;AAIA;;AAKF;AAEE;AAAoB;AAWf;AASF;AAcH;;AAIC;;"}
@@ -7,6 +7,7 @@ export type DesignedSelectInternalProps<Value extends SelectValue> = Omit<Select
7
7
  width?: number | string;
8
8
  placeholder?: string;
9
9
  extendDirection?: Exclude<ExpandedType, 'none'>;
10
+ error?: boolean;
10
11
  };
11
12
  export type ExpandedType = 'none' | 'above' | 'below';
12
13
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../src/Inputs/Select/DesignedSelect/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,oBAAoB,EAAE,MAAM,OAAO,CAAC;AAE7D,OAAO,KAAK,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAE/D,MAAM,MAAM,2BAA2B,CAAC,KAAK,SAAS,WAAW,IAAI,IAAI,CACvE,oBAAoB,CAAC,cAAc,CAAC,EACpC,QAAQ,MAAM,EAAE,GAAG,UAAU,GAAG,UAAU,CAC3C,GAAG;IACF,QAAQ,EAAE,iBAAiB,CAAC,KAAK,CAAC,GAAG,iBAAiB,CAAC,KAAK,CAAC,EAAE,CAAC;IAChE,QAAQ,CAAC,EAAE,CACT,WAAW,EAAE,KAAK,EAClB,WAAW,EAAE,SAAS,KACnB,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,OAAO,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;CACjD,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../src/Inputs/Select/DesignedSelect/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,oBAAoB,EAAE,MAAM,OAAO,CAAC;AAE7D,OAAO,KAAK,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAE/D,MAAM,MAAM,2BAA2B,CAAC,KAAK,SAAS,WAAW,IAAI,IAAI,CACvE,oBAAoB,CAAC,cAAc,CAAC,EACpC,QAAQ,MAAM,EAAE,GAAG,UAAU,GAAG,UAAU,CAC3C,GAAG;IACF,QAAQ,EAAE,iBAAiB,CAAC,KAAK,CAAC,GAAG,iBAAiB,CAAC,KAAK,CAAC,EAAE,CAAC;IAChE,QAAQ,CAAC,EAAE,CACT,WAAW,EAAE,KAAK,EAClB,WAAW,EAAE,SAAS,KACnB,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,OAAO,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;IAChD,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC"}
@@ -14,7 +14,7 @@ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
14
14
  var _defineProperty__default = /*#__PURE__*/_interopDefault(_defineProperty);
15
15
  var _objectWithoutProperties__default = /*#__PURE__*/_interopDefault(_objectWithoutProperties);
16
16
 
17
- var _excluded = ["children", "className", "width", "placeholder", "value", "disabled", "onClick"];
17
+ var _excluded = ["children", "className", "width", "placeholder", "value", "disabled", "onClick", "error"];
18
18
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
19
19
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), true).forEach(function (r) { _defineProperty__default.default(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
20
20
  var NativeSelect = function NativeSelect(_ref, ref) {
@@ -25,12 +25,15 @@ var NativeSelect = function NativeSelect(_ref, ref) {
25
25
  value = _ref.value,
26
26
  disabled = _ref.disabled,
27
27
  onClick = _ref.onClick,
28
+ _ref$error = _ref.error,
29
+ error = _ref$error === void 0 ? false : _ref$error,
28
30
  props = _objectWithoutProperties__default.default(_ref, _excluded);
29
31
  var showPlaceholder = !value && !!placeholder;
30
32
  return /*#__PURE__*/jsxRuntime.jsxs(styles.SelectContainer, {
31
33
  "aria-disabled": disabled,
32
34
  className: className,
33
35
  $width: width,
36
+ $error: error,
34
37
  children: [/*#__PURE__*/jsxRuntime.jsxs(styles$1.StyledSelect, _objectSpread(_objectSpread({}, props), {}, {
35
38
  value: value,
36
39
  $width: width,
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs.js","sources":["../../../../../src/Inputs/Select/NativeSelect/index.tsx"],"sourcesContent":["'use client';\n\nimport { IconArrow2Down } from '@remember-web/icon';\nimport type { ForwardRefRenderFunction } from 'react';\nimport { forwardRef } from 'react';\n\nimport { SelectContainer } from '../styles';\nimport { SelectDownIcon, StyledSelect } from './styles';\nimport type { NativeSelectInternalProps } from './types';\n\nconst NativeSelect: ForwardRefRenderFunction<\n HTMLSelectElement,\n NativeSelectInternalProps\n> = (\n {\n children,\n className,\n width,\n placeholder,\n value,\n disabled,\n onClick,\n ...props\n },\n ref\n) => {\n const showPlaceholder = !value && !!placeholder;\n\n return (\n <SelectContainer\n aria-disabled={disabled}\n className={className}\n $width={width}\n >\n <StyledSelect\n {...props}\n value={value}\n $width={width}\n ref={ref}\n isPlaceholder={showPlaceholder}\n disabled={disabled}\n onClick={onClick}\n >\n {!value && (\n <option value=\"\" selected>\n {placeholder || 'ㅤ'}\n </option>\n )}\n {children}\n </StyledSelect>\n <SelectDownIcon>\n <IconArrow2Down size=\"small\" />\n </SelectDownIcon>\n </SelectContainer>\n );\n};\n\nexport default forwardRef(NativeSelect);\n"],"names":["props","className","$width","value","ref","isPlaceholder","disabled","onClick","children","size"],"mappings":";;;;;;;;;;;;;;;;AAAa;AAAA;AAAA;AAUb;AAeK;;;;;;;AAHEA;AAIL;;AAII;AACAC;AACAC;;AAIEC;AACAD;AACAE;AACAC;AACAC;AACAC;AAAiBC;AAGPL;;;;AAID;;AAGOM;;AAAe;AAChB;AAGvB;AAEA;;"}
1
+ {"version":3,"file":"index.cjs.js","sources":["../../../../../src/Inputs/Select/NativeSelect/index.tsx"],"sourcesContent":["'use client';\n\nimport { IconArrow2Down } from '@remember-web/icon';\nimport type { ForwardRefRenderFunction } from 'react';\nimport { forwardRef } from 'react';\n\nimport { SelectContainer } from '../styles';\nimport { SelectDownIcon, StyledSelect } from './styles';\nimport type { NativeSelectInternalProps } from './types';\n\nconst NativeSelect: ForwardRefRenderFunction<\n HTMLSelectElement,\n NativeSelectInternalProps\n> = (\n {\n children,\n className,\n width,\n placeholder,\n value,\n disabled,\n onClick,\n error = false,\n ...props\n },\n ref\n) => {\n const showPlaceholder = !value && !!placeholder;\n\n return (\n <SelectContainer\n aria-disabled={disabled}\n className={className}\n $width={width}\n $error={error}\n >\n <StyledSelect\n {...props}\n value={value}\n $width={width}\n ref={ref}\n isPlaceholder={showPlaceholder}\n disabled={disabled}\n onClick={onClick}\n >\n {!value && (\n <option value=\"\" selected>\n {placeholder || 'ㅤ'}\n </option>\n )}\n {children}\n </StyledSelect>\n <SelectDownIcon>\n <IconArrow2Down size=\"small\" />\n </SelectDownIcon>\n </SelectContainer>\n );\n};\n\nexport default forwardRef(NativeSelect);\n"],"names":["error","props","className","$width","$error","value","ref","isPlaceholder","disabled","onClick","children","size"],"mappings":";;;;;;;;;;;;;;;;AAAa;AAAA;AAAA;AAUb;AAgBK;;;;;;;;AAJDA;AACGC;AAIL;;AAII;AACAC;AACAC;AACAC;;AAIEC;AACAF;AACAG;AACAC;AACAC;AACAC;AAAiBC;AAGPL;;;;AAID;;AAGOM;;AAAe;AAChB;AAGvB;AAEA;;"}
@@ -3,6 +3,7 @@ declare const _default: import("react").ForwardRefExoticComponent<Omit<import("r
3
3
  children: import("react").ReactElement<import("../types").OptionProps<string>, <Value extends import("../types").SelectValue = string>({ children, disabled, value, }: import("../types").OptionProps<Value>) => import("react/jsx-runtime").JSX.Element> | import("react").ReactElement<import("../types").OptionProps<string>, <Value extends import("../types").SelectValue = string>({ children, disabled, value, }: import("../types").OptionProps<Value>) => import("react/jsx-runtime").JSX.Element>[];
4
4
  width?: string | number | undefined;
5
5
  placeholder?: string | undefined;
6
+ error?: boolean | undefined;
6
7
  } & import("react").RefAttributes<HTMLSelectElement>>;
7
8
  export default _default;
8
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/Inputs/Select/NativeSelect/index.tsx"],"names":[],"mappings":";;;;;;AAyDA,wBAAwC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/Inputs/Select/NativeSelect/index.tsx"],"names":[],"mappings":";;;;;;;AA2DA,wBAAwC"}
@@ -7,7 +7,7 @@ import { SelectContainer } from '../styles.esm.js';
7
7
  import { StyledSelect, SelectDownIcon } from './styles.esm.js';
8
8
  import { jsxs, jsx } from 'react/jsx-runtime';
9
9
 
10
- var _excluded = ["children", "className", "width", "placeholder", "value", "disabled", "onClick"];
10
+ var _excluded = ["children", "className", "width", "placeholder", "value", "disabled", "onClick", "error"];
11
11
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
12
12
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), true).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
13
13
  var NativeSelect = function NativeSelect(_ref, ref) {
@@ -18,12 +18,15 @@ var NativeSelect = function NativeSelect(_ref, ref) {
18
18
  value = _ref.value,
19
19
  disabled = _ref.disabled,
20
20
  onClick = _ref.onClick,
21
+ _ref$error = _ref.error,
22
+ error = _ref$error === void 0 ? false : _ref$error,
21
23
  props = _objectWithoutProperties(_ref, _excluded);
22
24
  var showPlaceholder = !value && !!placeholder;
23
25
  return /*#__PURE__*/jsxs(SelectContainer, {
24
26
  "aria-disabled": disabled,
25
27
  className: className,
26
28
  $width: width,
29
+ $error: error,
27
30
  children: [/*#__PURE__*/jsxs(StyledSelect, _objectSpread(_objectSpread({}, props), {}, {
28
31
  value: value,
29
32
  $width: width,
@@ -1 +1 @@
1
- {"version":3,"file":"index.esm.js","sources":["../../../../../src/Inputs/Select/NativeSelect/index.tsx"],"sourcesContent":["'use client';\n\nimport { IconArrow2Down } from '@remember-web/icon';\nimport type { ForwardRefRenderFunction } from 'react';\nimport { forwardRef } from 'react';\n\nimport { SelectContainer } from '../styles';\nimport { SelectDownIcon, StyledSelect } from './styles';\nimport type { NativeSelectInternalProps } from './types';\n\nconst NativeSelect: ForwardRefRenderFunction<\n HTMLSelectElement,\n NativeSelectInternalProps\n> = (\n {\n children,\n className,\n width,\n placeholder,\n value,\n disabled,\n onClick,\n ...props\n },\n ref\n) => {\n const showPlaceholder = !value && !!placeholder;\n\n return (\n <SelectContainer\n aria-disabled={disabled}\n className={className}\n $width={width}\n >\n <StyledSelect\n {...props}\n value={value}\n $width={width}\n ref={ref}\n isPlaceholder={showPlaceholder}\n disabled={disabled}\n onClick={onClick}\n >\n {!value && (\n <option value=\"\" selected>\n {placeholder || 'ㅤ'}\n </option>\n )}\n {children}\n </StyledSelect>\n <SelectDownIcon>\n <IconArrow2Down size=\"small\" />\n </SelectDownIcon>\n </SelectContainer>\n );\n};\n\nexport default forwardRef(NativeSelect);\n"],"names":["props","className","$width","value","ref","isPlaceholder","disabled","onClick","children","size"],"mappings":";;;;;;;;;AAAa;AAAA;AAAA;AAUb;AAeK;;;;;;;AAHEA;AAIL;;AAII;AACAC;AACAC;;AAIEC;AACAD;AACAE;AACAC;AACAC;AACAC;AAAiBC;AAGPL;;;;AAID;;AAGOM;;AAAe;AAChB;AAGvB;AAEA;;"}
1
+ {"version":3,"file":"index.esm.js","sources":["../../../../../src/Inputs/Select/NativeSelect/index.tsx"],"sourcesContent":["'use client';\n\nimport { IconArrow2Down } from '@remember-web/icon';\nimport type { ForwardRefRenderFunction } from 'react';\nimport { forwardRef } from 'react';\n\nimport { SelectContainer } from '../styles';\nimport { SelectDownIcon, StyledSelect } from './styles';\nimport type { NativeSelectInternalProps } from './types';\n\nconst NativeSelect: ForwardRefRenderFunction<\n HTMLSelectElement,\n NativeSelectInternalProps\n> = (\n {\n children,\n className,\n width,\n placeholder,\n value,\n disabled,\n onClick,\n error = false,\n ...props\n },\n ref\n) => {\n const showPlaceholder = !value && !!placeholder;\n\n return (\n <SelectContainer\n aria-disabled={disabled}\n className={className}\n $width={width}\n $error={error}\n >\n <StyledSelect\n {...props}\n value={value}\n $width={width}\n ref={ref}\n isPlaceholder={showPlaceholder}\n disabled={disabled}\n onClick={onClick}\n >\n {!value && (\n <option value=\"\" selected>\n {placeholder || 'ㅤ'}\n </option>\n )}\n {children}\n </StyledSelect>\n <SelectDownIcon>\n <IconArrow2Down size=\"small\" />\n </SelectDownIcon>\n </SelectContainer>\n );\n};\n\nexport default forwardRef(NativeSelect);\n"],"names":["error","props","className","$width","$error","value","ref","isPlaceholder","disabled","onClick","children","size"],"mappings":";;;;;;;;;AAAa;AAAA;AAAA;AAUb;AAgBK;;;;;;;;AAJDA;AACGC;AAIL;;AAII;AACAC;AACAC;AACAC;;AAIEC;AACAF;AACAG;AACAC;AACAC;AACAC;AAAiBC;AAGPL;;;;AAID;;AAGOM;;AAAe;AAChB;AAGvB;AAEA;;"}
@@ -11,7 +11,7 @@ var _taggedTemplateLiteral__default = /*#__PURE__*/_interopDefault(_taggedTempla
11
11
  var styled__default = /*#__PURE__*/_interopDefault(styled);
12
12
 
13
13
  var _templateObject, _templateObject2, _templateObject3;
14
- var StyledSelect = styled__default.default.select(_templateObject || (_templateObject = _taggedTemplateLiteral__default.default(["\n all: unset;\n\n ", "\n border: 1px solid ", ";\n border-radius: 4px;\n padding: 10px 36px 10px 12px;\n box-sizing: border-box;\n\n ", "\n\n width: ", ";\n\n transition: border-color 0.2s, background-color 0.2s;\n\n &:focus {\n border-color: ", ";\n }\n\n &:not(:disabled) {\n @media (hover: hover) {\n &:hover {\n background-color: ", ";\n }\n }\n\n &:active {\n background-color: ", ";\n }\n }\n"])), mixin.getTypographyStyles('UIBody2'), mixin.contents300, function (_ref) {
14
+ var StyledSelect = styled__default.default.select(_templateObject || (_templateObject = _taggedTemplateLiteral__default.default(["\n all: unset;\n\n ", ";\n border-width: 1px;\n border-style: solid;\n \n border-radius: 4px;\n padding: 10px 36px 10px 12px;\n box-sizing: border-box;\n\n ", "\n\n width: ", ";\n\n transition: border-color 0.2s, background-color 0.2s;\n\n\n &:not(:disabled) {\n @media (hover: hover) {\n &:hover {\n background-color: ", ";\n }\n }\n\n &:active {\n background-color: ", ";\n }\n }\n\n border-color: var(--border-color);\n"])), mixin.getTypographyStyles('UIBody2'), function (_ref) {
15
15
  var isPlaceholder = _ref.isPlaceholder;
16
16
  return isPlaceholder && styled.css(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral__default.default(["\n color: ", ";\n "])), mixin.contents200);
17
17
  }, function (_ref2) {
@@ -23,7 +23,7 @@ var StyledSelect = styled__default.default.select(_templateObject || (_templateO
23
23
  return "".concat($width, "px");
24
24
  }
25
25
  return $width;
26
- }, mixin.contents000, mixin.bg200, mixin.bg300);
26
+ }, mixin.bg200, mixin.bg300);
27
27
  var SelectDownIcon = styled__default.default.div(_templateObject3 || (_templateObject3 = _taggedTemplateLiteral__default.default(["\n position: absolute;\n right: 12px;\n top: 50%;\n transform: translateY(-50%);\n\n & > svg {\n display: block;\n }\n\n pointer-events: none;\n"])));
28
28
 
29
29
  exports.SelectDownIcon = SelectDownIcon;
@@ -1 +1 @@
1
- {"version":3,"file":"styles.cjs.js","sources":["../../../../../src/Inputs/Select/NativeSelect/styles.ts"],"sourcesContent":["'use client';\n\nimport {\n bg200,\n bg300,\n contents000,\n contents200,\n contents300,\n getTypographyStyles,\n} from '@remember-web/mixin';\nimport styled, { css } from 'styled-components';\n\nexport const StyledSelect = styled.select<{\n $width?: number | string;\n isPlaceholder?: boolean;\n}>`\n all: unset;\n\n ${getTypographyStyles('UIBody2')}\n border: 1px solid ${contents300};\n border-radius: 4px;\n padding: 10px 36px 10px 12px;\n box-sizing: border-box;\n\n ${({ isPlaceholder }) =>\n isPlaceholder &&\n css`\n color: ${contents200};\n `}\n\n width: ${({ $width }) => {\n if (!$width) {\n return null;\n }\n\n if (typeof $width === 'number') {\n return `${$width}px`;\n }\n\n return $width;\n }};\n\n transition: border-color 0.2s, background-color 0.2s;\n\n &:focus {\n border-color: ${contents000};\n }\n\n &:not(:disabled) {\n @media (hover: hover) {\n &:hover {\n background-color: ${bg200};\n }\n }\n\n &:active {\n background-color: ${bg300};\n }\n }\n`;\nexport const SelectDownIcon = styled.div`\n position: absolute;\n right: 12px;\n top: 50%;\n transform: translateY(-50%);\n\n & > svg {\n display: block;\n }\n\n pointer-events: none;\n`;\n"],"names":[],"mappings":";;;;;;;;;;;;AAAa;AAYN;AAYH;;AAIC;AAEsB;;AAErB;AACF;AAEA;;AAEA;AAEA;AACF;AAoBK;;;"}
1
+ {"version":3,"file":"styles.cjs.js","sources":["../../../../../src/Inputs/Select/NativeSelect/styles.ts"],"sourcesContent":["'use client';\n\nimport {\n bg200,\n bg300,\n contents200,\n getTypographyStyles,\n} from '@remember-web/mixin';\nimport styled, { css } from 'styled-components';\n\nexport const StyledSelect = styled.select<{\n $width?: number | string;\n isPlaceholder?: boolean;\n}>`\n all: unset;\n\n ${getTypographyStyles('UIBody2')};\n border-width: 1px;\n border-style: solid;\n \n border-radius: 4px;\n padding: 10px 36px 10px 12px;\n box-sizing: border-box;\n\n ${({ isPlaceholder }) =>\n isPlaceholder &&\n css`\n color: ${contents200};\n `}\n\n width: ${({ $width }) => {\n if (!$width) {\n return null;\n }\n\n if (typeof $width === 'number') {\n return `${$width}px`;\n }\n\n return $width;\n }};\n\n transition: border-color 0.2s, background-color 0.2s;\n\n\n &:not(:disabled) {\n @media (hover: hover) {\n &:hover {\n background-color: ${bg200};\n }\n }\n\n &:active {\n background-color: ${bg300};\n }\n }\n\n border-color: var(--border-color);\n`;\nexport const SelectDownIcon = styled.div`\n position: absolute;\n right: 12px;\n top: 50%;\n transform: translateY(-50%);\n\n & > svg {\n display: block;\n }\n\n pointer-events: none;\n`;\n"],"names":[],"mappings":";;;;;;;;;;;;AAAa;;AAwBT;;AAIC;AAEsB;;AAErB;AACF;AAEA;;AAEA;AAEA;AACF;AAmBK;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../../../../../src/Inputs/Select/NativeSelect/styles.ts"],"names":[],"mappings":";AAYA,eAAO,MAAM,YAAY;;;GA+CxB,CAAC;AACF,eAAO,MAAM,cAAc,gNAW1B,CAAC"}
1
+ {"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../../../../../src/Inputs/Select/NativeSelect/styles.ts"],"names":[],"mappings":";AAUA,eAAO,MAAM,YAAY;;;GAgDxB,CAAC;AACF,eAAO,MAAM,cAAc,gNAW1B,CAAC"}
@@ -1,10 +1,10 @@
1
1
  "use client";
2
2
  import _taggedTemplateLiteral from '@babel/runtime/helpers/taggedTemplateLiteral';
3
- import { getTypographyStyles, contents300, contents200, contents000, bg200, bg300 } from '@remember-web/mixin';
3
+ import { getTypographyStyles, contents200, bg200, bg300 } from '@remember-web/mixin';
4
4
  import styled, { css } from 'styled-components';
5
5
 
6
6
  var _templateObject, _templateObject2, _templateObject3;
7
- var StyledSelect = styled.select(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n all: unset;\n\n ", "\n border: 1px solid ", ";\n border-radius: 4px;\n padding: 10px 36px 10px 12px;\n box-sizing: border-box;\n\n ", "\n\n width: ", ";\n\n transition: border-color 0.2s, background-color 0.2s;\n\n &:focus {\n border-color: ", ";\n }\n\n &:not(:disabled) {\n @media (hover: hover) {\n &:hover {\n background-color: ", ";\n }\n }\n\n &:active {\n background-color: ", ";\n }\n }\n"])), getTypographyStyles('UIBody2'), contents300, function (_ref) {
7
+ var StyledSelect = styled.select(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n all: unset;\n\n ", ";\n border-width: 1px;\n border-style: solid;\n \n border-radius: 4px;\n padding: 10px 36px 10px 12px;\n box-sizing: border-box;\n\n ", "\n\n width: ", ";\n\n transition: border-color 0.2s, background-color 0.2s;\n\n\n &:not(:disabled) {\n @media (hover: hover) {\n &:hover {\n background-color: ", ";\n }\n }\n\n &:active {\n background-color: ", ";\n }\n }\n\n border-color: var(--border-color);\n"])), getTypographyStyles('UIBody2'), function (_ref) {
8
8
  var isPlaceholder = _ref.isPlaceholder;
9
9
  return isPlaceholder && css(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\n color: ", ";\n "])), contents200);
10
10
  }, function (_ref2) {
@@ -16,7 +16,7 @@ var StyledSelect = styled.select(_templateObject || (_templateObject = _taggedTe
16
16
  return "".concat($width, "px");
17
17
  }
18
18
  return $width;
19
- }, contents000, bg200, bg300);
19
+ }, bg200, bg300);
20
20
  var SelectDownIcon = styled.div(_templateObject3 || (_templateObject3 = _taggedTemplateLiteral(["\n position: absolute;\n right: 12px;\n top: 50%;\n transform: translateY(-50%);\n\n & > svg {\n display: block;\n }\n\n pointer-events: none;\n"])));
21
21
 
22
22
  export { SelectDownIcon, StyledSelect };
@@ -1 +1 @@
1
- {"version":3,"file":"styles.esm.js","sources":["../../../../../src/Inputs/Select/NativeSelect/styles.ts"],"sourcesContent":["'use client';\n\nimport {\n bg200,\n bg300,\n contents000,\n contents200,\n contents300,\n getTypographyStyles,\n} from '@remember-web/mixin';\nimport styled, { css } from 'styled-components';\n\nexport const StyledSelect = styled.select<{\n $width?: number | string;\n isPlaceholder?: boolean;\n}>`\n all: unset;\n\n ${getTypographyStyles('UIBody2')}\n border: 1px solid ${contents300};\n border-radius: 4px;\n padding: 10px 36px 10px 12px;\n box-sizing: border-box;\n\n ${({ isPlaceholder }) =>\n isPlaceholder &&\n css`\n color: ${contents200};\n `}\n\n width: ${({ $width }) => {\n if (!$width) {\n return null;\n }\n\n if (typeof $width === 'number') {\n return `${$width}px`;\n }\n\n return $width;\n }};\n\n transition: border-color 0.2s, background-color 0.2s;\n\n &:focus {\n border-color: ${contents000};\n }\n\n &:not(:disabled) {\n @media (hover: hover) {\n &:hover {\n background-color: ${bg200};\n }\n }\n\n &:active {\n background-color: ${bg300};\n }\n }\n`;\nexport const SelectDownIcon = styled.div`\n position: absolute;\n right: 12px;\n top: 50%;\n transform: translateY(-50%);\n\n & > svg {\n display: block;\n }\n\n pointer-events: none;\n`;\n"],"names":[],"mappings":";;;;;AAAa;AAYN;AAYH;;AAIC;AAEsB;;AAErB;AACF;AAEA;;AAEA;AAEA;AACF;AAoBK;;"}
1
+ {"version":3,"file":"styles.esm.js","sources":["../../../../../src/Inputs/Select/NativeSelect/styles.ts"],"sourcesContent":["'use client';\n\nimport {\n bg200,\n bg300,\n contents200,\n getTypographyStyles,\n} from '@remember-web/mixin';\nimport styled, { css } from 'styled-components';\n\nexport const StyledSelect = styled.select<{\n $width?: number | string;\n isPlaceholder?: boolean;\n}>`\n all: unset;\n\n ${getTypographyStyles('UIBody2')};\n border-width: 1px;\n border-style: solid;\n \n border-radius: 4px;\n padding: 10px 36px 10px 12px;\n box-sizing: border-box;\n\n ${({ isPlaceholder }) =>\n isPlaceholder &&\n css`\n color: ${contents200};\n `}\n\n width: ${({ $width }) => {\n if (!$width) {\n return null;\n }\n\n if (typeof $width === 'number') {\n return `${$width}px`;\n }\n\n return $width;\n }};\n\n transition: border-color 0.2s, background-color 0.2s;\n\n\n &:not(:disabled) {\n @media (hover: hover) {\n &:hover {\n background-color: ${bg200};\n }\n }\n\n &:active {\n background-color: ${bg300};\n }\n }\n\n border-color: var(--border-color);\n`;\nexport const SelectDownIcon = styled.div`\n position: absolute;\n right: 12px;\n top: 50%;\n transform: translateY(-50%);\n\n & > svg {\n display: block;\n }\n\n pointer-events: none;\n`;\n"],"names":[],"mappings":";;;;;AAAa;;AAwBT;;AAIC;AAEsB;;AAErB;AACF;AAEA;;AAEA;AAEA;AACF;AAmBK;;"}
@@ -6,6 +6,7 @@ export type NativeSelectInternalProps = Omit<SelectHTMLAttributes<HTMLSelectElem
6
6
  children: NativeOptionElement | NativeOptionElement[];
7
7
  width?: number | string;
8
8
  placeholder?: string;
9
+ error?: boolean;
9
10
  };
10
11
  export {};
11
12
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../src/Inputs/Select/NativeSelect/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,OAAO,CAAC;AAEhE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAE7C,KAAK,mBAAmB,GAAG,YAAY,CACrC,WAAW,CAAC,MAAM,CAAC,EACnB,OAAO,YAAY,CACpB,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG,IAAI,CAC1C,oBAAoB,CAAC,iBAAiB,CAAC,EACvC,QAAQ,MAAM,EAAE,GAAG,UAAU,CAC9B,GAAG;IACF,QAAQ,EAAE,mBAAmB,GAAG,mBAAmB,EAAE,CAAC;IACtD,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../src/Inputs/Select/NativeSelect/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,OAAO,CAAC;AAEhE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAE7C,KAAK,mBAAmB,GAAG,YAAY,CACrC,WAAW,CAAC,MAAM,CAAC,EACnB,OAAO,YAAY,CACpB,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG,IAAI,CAC1C,oBAAoB,CAAC,iBAAiB,CAAC,EACvC,QAAQ,MAAM,EAAE,GAAG,UAAU,CAC9B,GAAG;IACF,QAAQ,EAAE,mBAAmB,GAAG,mBAAmB,EAAE,CAAC;IACtD,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,CAAC"}
@@ -24,7 +24,8 @@ function Select(props, ref) {
24
24
  placeholder = props.placeholder,
25
25
  width = props.width,
26
26
  required = props.required,
27
- onClick = props.onClick;
27
+ onClick = props.onClick,
28
+ error = props.error;
28
29
  if (props["native"]) {
29
30
  return /*#__PURE__*/jsxRuntime.jsx(index$2, {
30
31
  disabled: disabled,
@@ -37,6 +38,7 @@ function Select(props, ref) {
37
38
  required: required,
38
39
  placeholder: placeholder,
39
40
  width: width,
41
+ error: error,
40
42
  ref: ref,
41
43
  children: react.Children.map(children, function (child) {
42
44
  return /*#__PURE__*/jsxRuntime.jsx(index$3.NativeOption, _objectSpread({}, child.props));
@@ -55,6 +57,7 @@ function Select(props, ref) {
55
57
  width: width,
56
58
  maxHeight: props.maxHeight,
57
59
  extendDirection: props.extendDirection,
60
+ error: error,
58
61
  ref: ref,
59
62
  children: children
60
63
  });
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs.js","sources":["../../../../src/Inputs/Select/index.tsx"],"sourcesContent":["'use client';\n\nimport type { Ref, RefAttributes } from 'react';\nimport { Children, forwardRef } from 'react';\n\nimport DesignedSelect from './DesignedSelect';\nimport NativeSelect from './NativeSelect';\nimport { NativeOption } from './NativeSelect/Option';\nimport { OptionHolder } from './Option';\nimport type {\n DesignedSelectProps,\n NativeSelectProps,\n SelectProps,\n SelectValue,\n} from './types';\n\nfunction Select<Value extends SelectValue>(\n props: SelectProps<Value>,\n ref: Ref<HTMLDivElement | HTMLSelectElement>\n) {\n const {\n children,\n value,\n className,\n disabled,\n onChange,\n placeholder,\n width,\n required,\n onClick,\n } = props;\n\n if (props.native) {\n return (\n <NativeSelect\n disabled={disabled}\n className={className}\n onClick={onClick}\n onChange={(e) => {\n onChange?.(e.target.value as Value, e.target.innerText);\n }}\n value={value}\n required={required}\n placeholder={placeholder}\n width={width}\n ref={ref as Ref<HTMLSelectElement>}\n >\n {Children.map(children, (child) => (\n <NativeOption {...child.props} />\n ))}\n </NativeSelect>\n );\n }\n\n return (\n <DesignedSelect\n className={className}\n value={value}\n disabled={disabled}\n onClick={onClick}\n onChange={(_value, _label) => onChange?.(_value as Value, _label)}\n placeholder={placeholder}\n width={width}\n maxHeight={props.maxHeight}\n extendDirection={props.extendDirection}\n ref={ref as Ref<HTMLDivElement>}\n >\n {children}\n </DesignedSelect>\n );\n}\n\nexport default Object.assign(\n forwardRef(Select) as <Value extends SelectValue>(\n props:\n | (DesignedSelectProps<Value> & RefAttributes<HTMLDivElement>)\n | (NativeSelectProps<Value> & RefAttributes<HTMLSelectElement>)\n ) => JSX.Element,\n { Option: OptionHolder }\n);\n"],"names":["disabled","className","onClick","onChange","value","required","placeholder","width","ref","children","Option"],"mappings":";;;;;;;;;;;;;;;AAAa;AAAA;AAgBb;AAIE;;;;;;;;;;;AAeMA;AACAC;AACAC;AACAC;AACEA;;AAEFC;AACAC;AACAC;AACAC;AACAC;;;;AAIE;AAGR;;AAIIP;AACAG;AACAJ;AACAE;AACAC;;;AACAG;AACAC;;;AAGAC;AAAgCC;AAEvB;AAGf;AAEA;AAMIC;AAAqB;;"}
1
+ {"version":3,"file":"index.cjs.js","sources":["../../../../src/Inputs/Select/index.tsx"],"sourcesContent":["'use client';\n\nimport type { Ref, RefAttributes } from 'react';\nimport { Children, forwardRef } from 'react';\n\nimport DesignedSelect from './DesignedSelect';\nimport NativeSelect from './NativeSelect';\nimport { NativeOption } from './NativeSelect/Option';\nimport { OptionHolder } from './Option';\nimport type {\n DesignedSelectProps,\n NativeSelectProps,\n SelectProps,\n SelectValue,\n} from './types';\n\nfunction Select<Value extends SelectValue>(\n props: SelectProps<Value>,\n ref: Ref<HTMLDivElement | HTMLSelectElement>\n) {\n const {\n children,\n value,\n className,\n disabled,\n onChange,\n placeholder,\n width,\n required,\n onClick,\n error,\n } = props;\n\n if (props.native) {\n return (\n <NativeSelect\n disabled={disabled}\n className={className}\n onClick={onClick}\n onChange={(e) => {\n onChange?.(e.target.value as Value, e.target.innerText);\n }}\n value={value}\n required={required}\n placeholder={placeholder}\n width={width}\n error={error}\n ref={ref as Ref<HTMLSelectElement>}\n >\n {Children.map(children, (child) => (\n <NativeOption {...child.props} />\n ))}\n </NativeSelect>\n );\n }\n\n return (\n <DesignedSelect\n className={className}\n value={value}\n disabled={disabled}\n onClick={onClick}\n onChange={(_value, _label) => onChange?.(_value as Value, _label)}\n placeholder={placeholder}\n width={width}\n maxHeight={props.maxHeight}\n extendDirection={props.extendDirection}\n error={error}\n ref={ref as Ref<HTMLDivElement>}\n >\n {children}\n </DesignedSelect>\n );\n}\n\nexport default Object.assign(\n forwardRef(Select) as <Value extends SelectValue>(\n props:\n | (DesignedSelectProps<Value> & RefAttributes<HTMLDivElement>)\n | (NativeSelectProps<Value> & RefAttributes<HTMLSelectElement>)\n ) => JSX.Element,\n { Option: OptionHolder }\n);\n"],"names":["disabled","className","onClick","onChange","value","required","placeholder","width","error","ref","children","Option"],"mappings":";;;;;;;;;;;;;;;AAAa;AAAA;AAgBb;AAIE;;;;;;;;;;;;AAgBMA;AACAC;AACAC;AACAC;AACEA;;AAEFC;AACAC;AACAC;AACAC;AACAC;AACAC;;;;AAIE;AAGR;;AAIIR;AACAG;AACAJ;AACAE;AACAC;;;AACAG;AACAC;;;AAGAC;AACAC;AAAgCC;AAEvB;AAGf;AAEA;AAMIC;AAAqB;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/Inputs/Select/index.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAO,aAAa,EAAE,MAAM,OAAO,CAAC;AAOhD,OAAO,KAAK,EACV,mBAAmB,EACnB,iBAAiB,EAEjB,WAAW,EACZ,MAAM,SAAS,CAAC;4DA6DT,CAAC,oBAAoB,KAAK,CAAC,GAAG,cAAc,cAAc,CAAC,CAAC,GAC5D,CAAC,kBAAkB,KAAK,CAAC,GAAG,cAAc,iBAAiB,CAAC,CAAC,KAC9D,WAAW;;;;;;AALlB,wBAOE"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/Inputs/Select/index.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAO,aAAa,EAAE,MAAM,OAAO,CAAC;AAOhD,OAAO,KAAK,EACV,mBAAmB,EACnB,iBAAiB,EAEjB,WAAW,EACZ,MAAM,SAAS,CAAC;4DAgET,CAAC,oBAAoB,KAAK,CAAC,GAAG,cAAc,cAAc,CAAC,CAAC,GAC5D,CAAC,kBAAkB,KAAK,CAAC,GAAG,cAAc,iBAAiB,CAAC,CAAC,KAC9D,WAAW;;;;;;AALlB,wBAOE"}
@@ -18,7 +18,8 @@ function Select(props, ref) {
18
18
  placeholder = props.placeholder,
19
19
  width = props.width,
20
20
  required = props.required,
21
- onClick = props.onClick;
21
+ onClick = props.onClick,
22
+ error = props.error;
22
23
  if (props["native"]) {
23
24
  return /*#__PURE__*/jsx(NativeSelect, {
24
25
  disabled: disabled,
@@ -31,6 +32,7 @@ function Select(props, ref) {
31
32
  required: required,
32
33
  placeholder: placeholder,
33
34
  width: width,
35
+ error: error,
34
36
  ref: ref,
35
37
  children: Children.map(children, function (child) {
36
38
  return /*#__PURE__*/jsx(NativeOption, _objectSpread({}, child.props));
@@ -49,6 +51,7 @@ function Select(props, ref) {
49
51
  width: width,
50
52
  maxHeight: props.maxHeight,
51
53
  extendDirection: props.extendDirection,
54
+ error: error,
52
55
  ref: ref,
53
56
  children: children
54
57
  });
@@ -1 +1 @@
1
- {"version":3,"file":"index.esm.js","sources":["../../../../src/Inputs/Select/index.tsx"],"sourcesContent":["'use client';\n\nimport type { Ref, RefAttributes } from 'react';\nimport { Children, forwardRef } from 'react';\n\nimport DesignedSelect from './DesignedSelect';\nimport NativeSelect from './NativeSelect';\nimport { NativeOption } from './NativeSelect/Option';\nimport { OptionHolder } from './Option';\nimport type {\n DesignedSelectProps,\n NativeSelectProps,\n SelectProps,\n SelectValue,\n} from './types';\n\nfunction Select<Value extends SelectValue>(\n props: SelectProps<Value>,\n ref: Ref<HTMLDivElement | HTMLSelectElement>\n) {\n const {\n children,\n value,\n className,\n disabled,\n onChange,\n placeholder,\n width,\n required,\n onClick,\n } = props;\n\n if (props.native) {\n return (\n <NativeSelect\n disabled={disabled}\n className={className}\n onClick={onClick}\n onChange={(e) => {\n onChange?.(e.target.value as Value, e.target.innerText);\n }}\n value={value}\n required={required}\n placeholder={placeholder}\n width={width}\n ref={ref as Ref<HTMLSelectElement>}\n >\n {Children.map(children, (child) => (\n <NativeOption {...child.props} />\n ))}\n </NativeSelect>\n );\n }\n\n return (\n <DesignedSelect\n className={className}\n value={value}\n disabled={disabled}\n onClick={onClick}\n onChange={(_value, _label) => onChange?.(_value as Value, _label)}\n placeholder={placeholder}\n width={width}\n maxHeight={props.maxHeight}\n extendDirection={props.extendDirection}\n ref={ref as Ref<HTMLDivElement>}\n >\n {children}\n </DesignedSelect>\n );\n}\n\nexport default Object.assign(\n forwardRef(Select) as <Value extends SelectValue>(\n props:\n | (DesignedSelectProps<Value> & RefAttributes<HTMLDivElement>)\n | (NativeSelectProps<Value> & RefAttributes<HTMLSelectElement>)\n ) => JSX.Element,\n { Option: OptionHolder }\n);\n"],"names":["disabled","className","onClick","onChange","value","required","placeholder","width","ref","children","Option"],"mappings":";;;;;;;;;AAAa;AAAA;AAgBb;AAIE;;;;;;;;;;;AAeMA;AACAC;AACAC;AACAC;AACEA;;AAEFC;AACAC;AACAC;AACAC;AACAC;;;;AAIE;AAGR;;AAIIP;AACAG;AACAJ;AACAE;AACAC;;;AACAG;AACAC;;;AAGAC;AAAgCC;AAEvB;AAGf;AAEA;AAMIC;AAAqB;;"}
1
+ {"version":3,"file":"index.esm.js","sources":["../../../../src/Inputs/Select/index.tsx"],"sourcesContent":["'use client';\n\nimport type { Ref, RefAttributes } from 'react';\nimport { Children, forwardRef } from 'react';\n\nimport DesignedSelect from './DesignedSelect';\nimport NativeSelect from './NativeSelect';\nimport { NativeOption } from './NativeSelect/Option';\nimport { OptionHolder } from './Option';\nimport type {\n DesignedSelectProps,\n NativeSelectProps,\n SelectProps,\n SelectValue,\n} from './types';\n\nfunction Select<Value extends SelectValue>(\n props: SelectProps<Value>,\n ref: Ref<HTMLDivElement | HTMLSelectElement>\n) {\n const {\n children,\n value,\n className,\n disabled,\n onChange,\n placeholder,\n width,\n required,\n onClick,\n error,\n } = props;\n\n if (props.native) {\n return (\n <NativeSelect\n disabled={disabled}\n className={className}\n onClick={onClick}\n onChange={(e) => {\n onChange?.(e.target.value as Value, e.target.innerText);\n }}\n value={value}\n required={required}\n placeholder={placeholder}\n width={width}\n error={error}\n ref={ref as Ref<HTMLSelectElement>}\n >\n {Children.map(children, (child) => (\n <NativeOption {...child.props} />\n ))}\n </NativeSelect>\n );\n }\n\n return (\n <DesignedSelect\n className={className}\n value={value}\n disabled={disabled}\n onClick={onClick}\n onChange={(_value, _label) => onChange?.(_value as Value, _label)}\n placeholder={placeholder}\n width={width}\n maxHeight={props.maxHeight}\n extendDirection={props.extendDirection}\n error={error}\n ref={ref as Ref<HTMLDivElement>}\n >\n {children}\n </DesignedSelect>\n );\n}\n\nexport default Object.assign(\n forwardRef(Select) as <Value extends SelectValue>(\n props:\n | (DesignedSelectProps<Value> & RefAttributes<HTMLDivElement>)\n | (NativeSelectProps<Value> & RefAttributes<HTMLSelectElement>)\n ) => JSX.Element,\n { Option: OptionHolder }\n);\n"],"names":["disabled","className","onClick","onChange","value","required","placeholder","width","error","ref","children","Option"],"mappings":";;;;;;;;;AAAa;AAAA;AAgBb;AAIE;;;;;;;;;;;;AAgBMA;AACAC;AACAC;AACAC;AACEA;;AAEFC;AACAC;AACAC;AACAC;AACAC;AACAC;;;;AAIE;AAGR;;AAIIR;AACAG;AACAJ;AACAE;AACAC;;;AACAG;AACAC;;;AAGAC;AACAC;AAAgCC;AAEvB;AAGf;AAEA;AAMIC;AAAqB;;"}
@@ -10,8 +10,14 @@ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
10
10
  var _taggedTemplateLiteral__default = /*#__PURE__*/_interopDefault(_taggedTemplateLiteral);
11
11
  var styled__default = /*#__PURE__*/_interopDefault(styled);
12
12
 
13
- var _templateObject;
14
- var SelectContainer = styled__default.default.div(_templateObject || (_templateObject = _taggedTemplateLiteral__default.default(["\n ", "\n color: ", ";\n width: ", ";\n position: relative;\n user-select: none;\n\n &:focus {\n outline: none;\n border-color: ", ";\n }\n &[aria-disabled='true'] {\n color: ", ";\n border-color: ", ";\n background-color: ", ";\n }\n"])), mixin.getTypographyStyles('UIBody2'), mixin.contents000, function (_ref) {
13
+ var _templateObject, _templateObject2;
14
+ var BORDER_COLOR = {
15
+ FOCUS: mixin.contents000,
16
+ DEFAULT: mixin.contents300,
17
+ ERROR: mixin.roleRed,
18
+ DISABLED: mixin.contents300
19
+ };
20
+ var SelectContainer = styled__default.default.div(_templateObject || (_templateObject = _taggedTemplateLiteral__default.default(["\n --border-color: ", ";\n\n ", "\n color: ", ";\n width: ", ";\n position: relative;\n user-select: none;\n\n &:focus, &:focus-within {\n --border-color: ", ";\n outline: none;\n }\n\n ", "\n\n &[aria-disabled='true'] {\n --border-color: ", ";\n color: ", ";\n background-color: ", ";\n }\n\n"])), BORDER_COLOR.DEFAULT, mixin.getTypographyStyles('UIBody2'), mixin.contents000, function (_ref) {
15
21
  var $width = _ref.$width;
16
22
  if (!$width) {
17
23
  return 'fit-content';
@@ -20,7 +26,10 @@ var SelectContainer = styled__default.default.div(_templateObject || (_templateO
20
26
  return "".concat($width, "px");
21
27
  }
22
28
  return $width;
23
- }, mixin.contents000, mixin.contents200, mixin.contents300, mixin.bg200);
29
+ }, BORDER_COLOR.FOCUS, function (_ref2) {
30
+ var $error = _ref2.$error;
31
+ return $error && styled.css(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral__default.default(["\n &, &:focus, &:focus-within {\n --border-color: ", ";\n }\n "])), BORDER_COLOR.ERROR);
32
+ }, BORDER_COLOR.DISABLED, mixin.contents200, mixin.bg200);
24
33
 
25
34
  exports.SelectContainer = SelectContainer;
26
35
  //# sourceMappingURL=styles.cjs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"styles.cjs.js","sources":["../../../../src/Inputs/Select/styles.ts"],"sourcesContent":["'use client';\n\nimport {\n bg200,\n contents000,\n contents200,\n contents300,\n getTypographyStyles,\n} from '@remember-web/mixin';\nimport styled from 'styled-components';\n\nexport const SelectContainer = styled.div<{ $width?: number | string }>`\n ${getTypographyStyles('UIBody2')}\n color: ${contents000};\n width: ${({ $width }) => {\n if (!$width) {\n return 'fit-content';\n }\n\n if (typeof $width === 'number') {\n return `${$width}px`;\n }\n\n return $width;\n }};\n position: relative;\n user-select: none;\n\n &:focus {\n outline: none;\n border-color: ${contents000};\n }\n &[aria-disabled='true'] {\n color: ${contents200};\n border-color: ${contents300};\n background-color: ${bg200};\n }\n`;\n"],"names":[],"mappings":";;;;;;;;;;;;AAAa;AAWN;AAGoB;;AAErB;AACF;AAEA;;AAEA;AAEA;AACF;;"}
1
+ {"version":3,"file":"styles.cjs.js","sources":["../../../../src/Inputs/Select/styles.ts"],"sourcesContent":["'use client';\n\nimport {\n bg200,\n contents000,\n contents200,\n contents300,\n getTypographyStyles,\n roleRed,\n} from '@remember-web/mixin';\nimport styled, { css } from 'styled-components';\n\nconst BORDER_COLOR = {\n FOCUS: contents000,\n DEFAULT: contents300,\n ERROR: roleRed,\n DISABLED: contents300,\n};\n\nexport const SelectContainer = styled.div<{\n $width?: number | string;\n $error: boolean;\n}>`\n --border-color: ${BORDER_COLOR.DEFAULT};\n\n ${getTypographyStyles('UIBody2')}\n color: ${contents000};\n width: ${({ $width }) => {\n if (!$width) {\n return 'fit-content';\n }\n\n if (typeof $width === 'number') {\n return `${$width}px`;\n }\n\n return $width;\n }};\n position: relative;\n user-select: none;\n\n &:focus, &:focus-within {\n --border-color: ${BORDER_COLOR.FOCUS};\n outline: none;\n }\n\n ${({ $error }) =>\n $error &&\n css`\n &, &:focus, &:focus-within {\n --border-color: ${BORDER_COLOR.ERROR};\n }\n `}\n\n &[aria-disabled='true'] {\n --border-color: ${BORDER_COLOR.DISABLED};\n color: ${contents200};\n background-color: ${bg200};\n }\n\n`;\n"],"names":["FOCUS","DEFAULT","ERROR","DISABLED"],"mappings":";;;;;;;;;;;;AAAa;AAYb;AACEA;AACAC;AACAC;AACAC;AACF;AAEO;AAQoB;;AAErB;AACF;AAEA;;AAEA;AAEA;AACF;AASE;AAAS;AAMR;;"}
@@ -1,5 +1,6 @@
1
1
  /// <reference types="react" />
2
2
  export declare const SelectContainer: import("styled-components").IStyledComponent<"web", import("styled-components/dist/types").Substitute<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {
3
3
  $width?: string | number | undefined;
4
+ $error: boolean;
4
5
  }>>;
5
6
  //# sourceMappingURL=styles.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../../../../src/Inputs/Select/styles.ts"],"names":[],"mappings":";AAWA,eAAO,MAAM,eAAe;;GA0B3B,CAAC"}
1
+ {"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../../../../src/Inputs/Select/styles.ts"],"names":[],"mappings":";AAmBA,eAAO,MAAM,eAAe;;YAElB,OAAO;GAuChB,CAAC"}
@@ -1,10 +1,16 @@
1
1
  "use client";
2
2
  import _taggedTemplateLiteral from '@babel/runtime/helpers/taggedTemplateLiteral';
3
- import { getTypographyStyles, contents000, contents200, contents300, bg200 } from '@remember-web/mixin';
4
- import styled from 'styled-components';
3
+ import { contents300, getTypographyStyles, contents000, roleRed, contents200, bg200 } from '@remember-web/mixin';
4
+ import styled, { css } from 'styled-components';
5
5
 
6
- var _templateObject;
7
- var SelectContainer = styled.div(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n ", "\n color: ", ";\n width: ", ";\n position: relative;\n user-select: none;\n\n &:focus {\n outline: none;\n border-color: ", ";\n }\n &[aria-disabled='true'] {\n color: ", ";\n border-color: ", ";\n background-color: ", ";\n }\n"])), getTypographyStyles('UIBody2'), contents000, function (_ref) {
6
+ var _templateObject, _templateObject2;
7
+ var BORDER_COLOR = {
8
+ FOCUS: contents000,
9
+ DEFAULT: contents300,
10
+ ERROR: roleRed,
11
+ DISABLED: contents300
12
+ };
13
+ var SelectContainer = styled.div(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n --border-color: ", ";\n\n ", "\n color: ", ";\n width: ", ";\n position: relative;\n user-select: none;\n\n &:focus, &:focus-within {\n --border-color: ", ";\n outline: none;\n }\n\n ", "\n\n &[aria-disabled='true'] {\n --border-color: ", ";\n color: ", ";\n background-color: ", ";\n }\n\n"])), BORDER_COLOR.DEFAULT, getTypographyStyles('UIBody2'), contents000, function (_ref) {
8
14
  var $width = _ref.$width;
9
15
  if (!$width) {
10
16
  return 'fit-content';
@@ -13,7 +19,10 @@ var SelectContainer = styled.div(_templateObject || (_templateObject = _taggedTe
13
19
  return "".concat($width, "px");
14
20
  }
15
21
  return $width;
16
- }, contents000, contents200, contents300, bg200);
22
+ }, BORDER_COLOR.FOCUS, function (_ref2) {
23
+ var $error = _ref2.$error;
24
+ return $error && css(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\n &, &:focus, &:focus-within {\n --border-color: ", ";\n }\n "])), BORDER_COLOR.ERROR);
25
+ }, BORDER_COLOR.DISABLED, contents200, bg200);
17
26
 
18
27
  export { SelectContainer };
19
28
  //# sourceMappingURL=styles.esm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"styles.esm.js","sources":["../../../../src/Inputs/Select/styles.ts"],"sourcesContent":["'use client';\n\nimport {\n bg200,\n contents000,\n contents200,\n contents300,\n getTypographyStyles,\n} from '@remember-web/mixin';\nimport styled from 'styled-components';\n\nexport const SelectContainer = styled.div<{ $width?: number | string }>`\n ${getTypographyStyles('UIBody2')}\n color: ${contents000};\n width: ${({ $width }) => {\n if (!$width) {\n return 'fit-content';\n }\n\n if (typeof $width === 'number') {\n return `${$width}px`;\n }\n\n return $width;\n }};\n position: relative;\n user-select: none;\n\n &:focus {\n outline: none;\n border-color: ${contents000};\n }\n &[aria-disabled='true'] {\n color: ${contents200};\n border-color: ${contents300};\n background-color: ${bg200};\n }\n`;\n"],"names":[],"mappings":";;;;;AAAa;AAWN;AAGoB;;AAErB;AACF;AAEA;;AAEA;AAEA;AACF;;"}
1
+ {"version":3,"file":"styles.esm.js","sources":["../../../../src/Inputs/Select/styles.ts"],"sourcesContent":["'use client';\n\nimport {\n bg200,\n contents000,\n contents200,\n contents300,\n getTypographyStyles,\n roleRed,\n} from '@remember-web/mixin';\nimport styled, { css } from 'styled-components';\n\nconst BORDER_COLOR = {\n FOCUS: contents000,\n DEFAULT: contents300,\n ERROR: roleRed,\n DISABLED: contents300,\n};\n\nexport const SelectContainer = styled.div<{\n $width?: number | string;\n $error: boolean;\n}>`\n --border-color: ${BORDER_COLOR.DEFAULT};\n\n ${getTypographyStyles('UIBody2')}\n color: ${contents000};\n width: ${({ $width }) => {\n if (!$width) {\n return 'fit-content';\n }\n\n if (typeof $width === 'number') {\n return `${$width}px`;\n }\n\n return $width;\n }};\n position: relative;\n user-select: none;\n\n &:focus, &:focus-within {\n --border-color: ${BORDER_COLOR.FOCUS};\n outline: none;\n }\n\n ${({ $error }) =>\n $error &&\n css`\n &, &:focus, &:focus-within {\n --border-color: ${BORDER_COLOR.ERROR};\n }\n `}\n\n &[aria-disabled='true'] {\n --border-color: ${BORDER_COLOR.DISABLED};\n color: ${contents200};\n background-color: ${bg200};\n }\n\n`;\n"],"names":["FOCUS","DEFAULT","ERROR","DISABLED"],"mappings":";;;;;AAAa;AAYb;AACEA;AACAC;AACAC;AACAC;AACF;AAEO;AAQoB;;AAErB;AACF;AAEA;;AAEA;AAEA;AACF;AASE;AAAS;AAMR;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remember-web/primitive",
3
- "version": "0.5.4",
3
+ "version": "0.5.5",
4
4
  "description": "Remember Web Primitive Components",
5
5
  "homepage": "https://dramancompany.github.io/remember-web-packages/",
6
6
  "author": "Remember",
@@ -36,6 +36,7 @@ const DesignedSelect = <Value extends SelectValue>(
36
36
  onChange,
37
37
  width,
38
38
  extendDirection,
39
+ error = false,
39
40
  disabled,
40
41
  onClick,
41
42
  ...props
@@ -213,6 +214,7 @@ const DesignedSelect = <Value extends SelectValue>(
213
214
  aria-expanded={isExpanded}
214
215
  aria-haspopup="listbox"
215
216
  aria-disabled={disabled}
217
+ $error={error}
216
218
  onKeyDown={keyDownHandler}
217
219
  {...props}
218
220
  >
@@ -19,7 +19,9 @@ export const StyledSelect = styled.div<{
19
19
  isPlaceholder?: boolean;
20
20
  }>`
21
21
  ${ellipsis()}
22
- border: 1px solid ${contents300};
22
+ border-width: 1px;
23
+ border-style: solid;;
24
+
23
25
  ${({ expandedDirection }) =>
24
26
  ({
25
27
  none: css`
@@ -46,8 +48,8 @@ export const StyledSelect = styled.div<{
46
48
 
47
49
  ${SelectContainer}:focus-within & {
48
50
  outline: none;
49
- border-color: ${contents000};
50
51
  }
52
+
51
53
  ${SelectContainer}:not([aria-disabled='true']) & {
52
54
  @media (hover: hover) {
53
55
  &:hover {
@@ -59,6 +61,8 @@ export const StyledSelect = styled.div<{
59
61
  background-color: ${bg300};
60
62
  }
61
63
  }
64
+
65
+ border-color: var(--border-color);
62
66
  `;
63
67
 
64
68
  export const SelectDownIcon = styled.div`
@@ -83,7 +87,10 @@ export const SelectOptionWrapper = styled.ul<{
83
87
  left: 0;
84
88
  right: 0;
85
89
  z-index: 1;
86
- border: 1px solid ${contents300};
90
+
91
+ border-width: 1px;
92
+ border-style: solid;;
93
+
87
94
  background-color: ${bg100};
88
95
  overflow-y: auto;
89
96
  overscroll-behavior: contain;
@@ -120,8 +127,9 @@ export const SelectOptionWrapper = styled.ul<{
120
127
 
121
128
  ${SelectContainer}:focus &, ${SelectContainer}:focus-within & {
122
129
  outline: none;
123
- border-color: ${contents000};
124
130
  }
131
+
132
+ border-color: var(--border-color);
125
133
  `;
126
134
 
127
135
  export const SelectOption = styled.li<{ isSelected?: boolean }>`
@@ -15,6 +15,7 @@ export type DesignedSelectInternalProps<Value extends SelectValue> = Omit<
15
15
  width?: number | string;
16
16
  placeholder?: string;
17
17
  extendDirection?: Exclude<ExpandedType, 'none'>;
18
+ error?: boolean;
18
19
  };
19
20
 
20
21
  export type ExpandedType = 'none' | 'above' | 'below';
@@ -20,6 +20,7 @@ const NativeSelect: ForwardRefRenderFunction<
20
20
  value,
21
21
  disabled,
22
22
  onClick,
23
+ error = false,
23
24
  ...props
24
25
  },
25
26
  ref
@@ -31,6 +32,7 @@ const NativeSelect: ForwardRefRenderFunction<
31
32
  aria-disabled={disabled}
32
33
  className={className}
33
34
  $width={width}
35
+ $error={error}
34
36
  >
35
37
  <StyledSelect
36
38
  {...props}
@@ -3,9 +3,7 @@
3
3
  import {
4
4
  bg200,
5
5
  bg300,
6
- contents000,
7
6
  contents200,
8
- contents300,
9
7
  getTypographyStyles,
10
8
  } from '@remember-web/mixin';
11
9
  import styled, { css } from 'styled-components';
@@ -16,8 +14,10 @@ export const StyledSelect = styled.select<{
16
14
  }>`
17
15
  all: unset;
18
16
 
19
- ${getTypographyStyles('UIBody2')}
20
- border: 1px solid ${contents300};
17
+ ${getTypographyStyles('UIBody2')};
18
+ border-width: 1px;
19
+ border-style: solid;
20
+
21
21
  border-radius: 4px;
22
22
  padding: 10px 36px 10px 12px;
23
23
  box-sizing: border-box;
@@ -42,9 +42,6 @@ export const StyledSelect = styled.select<{
42
42
 
43
43
  transition: border-color 0.2s, background-color 0.2s;
44
44
 
45
- &:focus {
46
- border-color: ${contents000};
47
- }
48
45
 
49
46
  &:not(:disabled) {
50
47
  @media (hover: hover) {
@@ -57,6 +54,8 @@ export const StyledSelect = styled.select<{
57
54
  background-color: ${bg300};
58
55
  }
59
56
  }
57
+
58
+ border-color: var(--border-color);
60
59
  `;
61
60
  export const SelectDownIcon = styled.div`
62
61
  position: absolute;
@@ -15,4 +15,5 @@ export type NativeSelectInternalProps = Omit<
15
15
  children: NativeOptionElement | NativeOptionElement[];
16
16
  width?: number | string;
17
17
  placeholder?: string;
18
+ error?: boolean;
18
19
  };
@@ -1,9 +1,7 @@
1
1
  import type { Meta, StoryObj } from '@storybook/react-vite';
2
2
  import { useState } from 'react';
3
-
4
- import type { DesignedSelectProps, NativeSelectProps } from './types';
5
-
6
3
  import Select from '.';
4
+ import type { DesignedSelectProps, NativeSelectProps } from './types';
7
5
 
8
6
  type Story = StoryObj<typeof Select>;
9
7
 
@@ -18,6 +16,7 @@ const meta = {
18
16
  maxHeight: { type: 'string' },
19
17
  native: { type: 'boolean' },
20
18
  onClick: { action: 'clicked' },
19
+ error: { type: 'boolean' },
21
20
  },
22
21
  } satisfies Meta<typeof Select>;
23
22
 
@@ -28,6 +28,7 @@ function Select<Value extends SelectValue>(
28
28
  width,
29
29
  required,
30
30
  onClick,
31
+ error,
31
32
  } = props;
32
33
 
33
34
  if (props.native) {
@@ -43,6 +44,7 @@ function Select<Value extends SelectValue>(
43
44
  required={required}
44
45
  placeholder={placeholder}
45
46
  width={width}
47
+ error={error}
46
48
  ref={ref as Ref<HTMLSelectElement>}
47
49
  >
48
50
  {Children.map(children, (child) => (
@@ -63,6 +65,7 @@ function Select<Value extends SelectValue>(
63
65
  width={width}
64
66
  maxHeight={props.maxHeight}
65
67
  extendDirection={props.extendDirection}
68
+ error={error}
66
69
  ref={ref as Ref<HTMLDivElement>}
67
70
  >
68
71
  {children}
@@ -6,10 +6,23 @@ import {
6
6
  contents200,
7
7
  contents300,
8
8
  getTypographyStyles,
9
+ roleRed,
9
10
  } from '@remember-web/mixin';
10
- import styled from 'styled-components';
11
+ import styled, { css } from 'styled-components';
12
+
13
+ const BORDER_COLOR = {
14
+ FOCUS: contents000,
15
+ DEFAULT: contents300,
16
+ ERROR: roleRed,
17
+ DISABLED: contents300,
18
+ };
19
+
20
+ export const SelectContainer = styled.div<{
21
+ $width?: number | string;
22
+ $error: boolean;
23
+ }>`
24
+ --border-color: ${BORDER_COLOR.DEFAULT};
11
25
 
12
- export const SelectContainer = styled.div<{ $width?: number | string }>`
13
26
  ${getTypographyStyles('UIBody2')}
14
27
  color: ${contents000};
15
28
  width: ${({ $width }) => {
@@ -26,13 +39,23 @@ export const SelectContainer = styled.div<{ $width?: number | string }>`
26
39
  position: relative;
27
40
  user-select: none;
28
41
 
29
- &:focus {
42
+ &:focus, &:focus-within {
43
+ --border-color: ${BORDER_COLOR.FOCUS};
30
44
  outline: none;
31
- border-color: ${contents000};
32
45
  }
46
+
47
+ ${({ $error }) =>
48
+ $error &&
49
+ css`
50
+ &, &:focus, &:focus-within {
51
+ --border-color: ${BORDER_COLOR.ERROR};
52
+ }
53
+ `}
54
+
33
55
  &[aria-disabled='true'] {
56
+ --border-color: ${BORDER_COLOR.DISABLED};
34
57
  color: ${contents200};
35
- border-color: ${contents300};
36
58
  background-color: ${bg200};
37
59
  }
60
+
38
61
  `;