@wishket/design-system 3.4.0 → 3.4.1
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.
- package/dist/Components/Inputs/TextFieldDropdown/TextFieldDropdown.js +4 -4
- package/dist/Components/Inputs/TextFieldDropdown/TextFieldDropdown.parts.js +5 -4
- package/dist/cjs/Components/Inputs/TextFieldDropdown/TextFieldDropdown.js +3 -3
- package/dist/cjs/Components/Inputs/TextFieldDropdown/TextFieldDropdown.parts.js +6 -5
- package/dist/cjs/hooks/useDropdown.js +3 -1
- package/dist/hooks/useDropdown.js +3 -1
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use client";import{jsxs as e,jsx as t}from"react/jsx-runtime";import{useState as o,useLayoutEffect as
|
|
1
|
+
"use client";import{jsxs as e,jsx as t}from"react/jsx-runtime";import{useState as o,useLayoutEffect as r}from"react";import{twJoin as i}from"tailwind-merge";import{Box as l}from"../../Base/Layouts/Box/Box.js";import"../../Base/Layouts/FullBleed/FullBleed.js";import{List as n}from"../List/List.js";import{SupportTextContainer as s}from"../SupportTextContainer/SupportTextContainer.js";import{useDropdown as a}from"../../../hooks/useDropdown.js";import{SelectBox as d}from"./TextFieldDropdown.parts.js";
|
|
2
2
|
/**
|
|
3
3
|
* 드롭다운 형태의 텍스트 필드 컴포넌트입니다.
|
|
4
4
|
*
|
|
@@ -44,11 +44,11 @@
|
|
|
44
44
|
* selectedItem={items[0]}
|
|
45
45
|
* />
|
|
46
46
|
* ```
|
|
47
|
-
*/const
|
|
47
|
+
*/const p=({selectedItem:p,items:m,onItemClick:c,placeholder:u,disabled:f,isError:g,errorMessage:v,supportMessage:w,className:x,variant:h="default",label:b,panelWidth:L="trigger",panelGutter:I=20})=>{const{isListOpen:y,focusedIndex:k,ref:C,handleItemClick:j,toggleListOpen:B,handleKeyDown:D}=a({items:m,onItemClick:c,disabled:f}),E=!!w||!!v,F="viewport"===L,[M,N]=o(void 0);
|
|
48
48
|
// viewport 패널은 좁은 컨테이너 바깥, 화면 전체 너비로 펼쳐져야 한다.
|
|
49
49
|
// 단 fixed로 띄우면 out-of-flow라 영역을 차지하지 못해 하단에서 잘리므로,
|
|
50
50
|
// in-flow(relative)로 두고 트리거의 화면상 좌측 위치/뷰포트 너비를 측정해
|
|
51
51
|
// 좌우로 full-bleed시킨다. 높이는 in-flow라 실제 영역을 차지하고,
|
|
52
52
|
// 옵션이 많으면 List 내부(max-height)에서 스크롤된다. (리사이즈/스크롤 시 추적)
|
|
53
|
-
return
|
|
54
|
-
/*#__PURE__*/t(
|
|
53
|
+
return r((()=>{if(!y||!F)return;const e=C.current;if(!e)return;const t=()=>{const{left:t}=e.getBoundingClientRect(),o=document.documentElement.clientWidth;N({marginLeft:I-t,width:o-2*I})};return t(),window.addEventListener("scroll",t,!0),window.addEventListener("resize",t),()=>{window.removeEventListener("scroll",t,!0),window.removeEventListener("resize",t)}}),[y,F,I,C]),/*#__PURE__*/e("div",{"data-testid":"design-system--textFieldDropdown",ref:C,className:"group/dropdown relative flex w-full flex-col gap-2 outline-hidden",onKeyDown:D,tabIndex:f?-1:0,role:"combobox","aria-haspopup":"listbox","aria-expanded":y,"aria-disabled":f,children:[
|
|
54
|
+
/*#__PURE__*/t(d,{placeholder:u,value:null==p?void 0:p.value,leadingIcon:null==p?void 0:p.leadingIcon,disabled:f,isListOpen:y,onClick:B,error:g,className:x,variant:h,label:b}),E&&/*#__PURE__*/t(s,{errorMessage:v,supportMessage:w}),y&&/*#__PURE__*/t(l,{"data-testid":"design-system--textFieldDropdown-panel",className:i("z-40",F?"relative":i("absolute w-full","label"===h?"top-[72px]":"top-[54px]")),style:F?M:void 0,children:/*#__PURE__*/t(n.Root,{children:m.map(((e,o)=>/*#__PURE__*/t(n.Item,{text:e.value,leadingIcon:e.leadingIcon,onClick:()=>j(e),selected:e.key===(null==p?void 0:p.key),isFocused:o===k},e.key)))})})]})};export{p as TextFieldDropdown};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import{jsxs as t,jsx as e}from"react/jsx-runtime";import{
|
|
2
|
-
|
|
1
|
+
import{jsxs as t,jsx as e}from"react/jsx-runtime";import{twMerge as a,twJoin as r}from"tailwind-merge";import"../../DataDisplays/Avatar/Avatar.js";import{Typography as s}from"../../Base/Typography/Typography.js";import{Box as o}from"../../Base/Layouts/Box/Box.js";import"../../Base/Layouts/FullBleed/FullBleed.js";import"react";import{SystemIcon as i}from"../../DataDisplays/SystemIcon/SystemIcon.js";import"../../DataDisplays/SystemIcon/SystemIcon.constants.js";import"../../DataDisplays/Accordion/Accordion.js";import{TextFieldContainer as l}from"../TextFieldContainer/TextFieldContainer.js";const d=({placeholder:o="",value:d="",isListOpen:c,disabled:m=!1,error:p,onClick:y,className:x,variant:g="default",label:u})=>/*#__PURE__*/t(l,{isDisabled:m,isFocused:c,isError:p,testId:"design-system--selectBox",onClick:y,className:a(// 래퍼(group/dropdown)가 키보드 포커스를 받으면 트리거에 포커스링을 표시한다.
|
|
2
|
+
!m&&"group-focus-visible/dropdown:border-primary group-focus-visible/dropdown:ring-primary-100 group-focus-visible/dropdown:ring-2",x),children:["label"===g?/*#__PURE__*/e(n,{label:u,value:d,placeholder:o,isFocused:c,isError:p,disabled:m}):/*#__PURE__*/e(s,{"data-testid":"design-system--selectBox-text",variant:"body16",className:r(m&&d?"text-w-gray-300":m&&!d?"text-w-gray-200":d?"text-w-gray-600":"text-w-gray-300","w-full"),children:d||o}),
|
|
3
|
+
/*#__PURE__*/e("div",{className:r("transition-transform duration-300",c&&"rotate-180"),children:/*#__PURE__*/e(i,{name:"medium_arrow_down",className:m?"text-w-gray-300":"text-w-gray-600",testId:"design-system--selectBox-icon"})})]}),n=({label:i,value:l,placeholder:d,isFocused:n,isError:c,disabled:m})=>{const p=!!d;/*#__PURE__*/
|
|
3
4
|
return t(o,{className:"relative flex h-[42px] w-full flex-col gap-0.5 py-px","data-testid":"design-system--selectBox-label",children:[
|
|
4
|
-
/*#__PURE__*/e("div",{className:
|
|
5
|
-
/*#__PURE__*/e(
|
|
5
|
+
/*#__PURE__*/e("div",{className:a("tracking-default absolute",m?"text-w-gray-400":c?"text-w-red-500":n?"text-primary-500":"text-w-gray-400 group-hover:text-primary-500",p?"typo-caption11":n||l?"scale-[0.6875] -translate-y-0.5 origin-top-left transition-transform duration-300":"typo-body16 transition-transform duration-300 translate-y-2 origin-top-left"),"data-testid":"design-system--label-text",children:i}),
|
|
6
|
+
/*#__PURE__*/e(s,{"data-testid":"design-system--selectBox-text",variant:"body16",className:r(m?"text-w-gray-300":l?"text-w-gray-600":"text-w-gray-300","w-full pt-[14px]"),children:l||(p?d:"")})]})};export{d as SelectBox};
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
"use client";"use strict";var e=require("react/jsx-runtime"),t=require("react"),r=require("tailwind-merge"),i=require("../../Base/Layouts/Box/Box.js");require("../../Base/Layouts/FullBleed/FullBleed.js");var s=require("../List/List.js"),
|
|
1
|
+
"use client";"use strict";var e=require("react/jsx-runtime"),t=require("react"),r=require("tailwind-merge"),i=require("../../Base/Layouts/Box/Box.js");require("../../Base/Layouts/FullBleed/FullBleed.js");var s=require("../List/List.js"),o=require("../SupportTextContainer/SupportTextContainer.js"),n=require("../../../hooks/useDropdown.js"),l=require("./TextFieldDropdown.parts.js");exports.TextFieldDropdown=({selectedItem:a,items:d,onItemClick:u,placeholder:c,disabled:p,isError:x,errorMessage:w,supportMessage:m,className:v,variant:g="default",label:L,panelWidth:f="trigger",panelGutter:h=20})=>{const{isListOpen:j,focusedIndex:b,ref:y,handleItemClick:I,toggleListOpen:k,handleKeyDown:q}=n.useDropdown({items:d,onItemClick:u,disabled:p}),B=!!m||!!w,C="viewport"===f,[D,E]=t.useState(void 0);
|
|
2
2
|
// viewport 패널은 좁은 컨테이너 바깥, 화면 전체 너비로 펼쳐져야 한다.
|
|
3
3
|
// 단 fixed로 띄우면 out-of-flow라 영역을 차지하지 못해 하단에서 잘리므로,
|
|
4
4
|
// in-flow(relative)로 두고 트리거의 화면상 좌측 위치/뷰포트 너비를 측정해
|
|
5
5
|
// 좌우로 full-bleed시킨다. 높이는 in-flow라 실제 영역을 차지하고,
|
|
6
6
|
// 옵션이 많으면 List 내부(max-height)에서 스크롤된다. (리사이즈/스크롤 시 추적)
|
|
7
|
-
return t.useLayoutEffect((()=>{if(!
|
|
8
|
-
/*#__PURE__*/e.jsx(
|
|
7
|
+
return t.useLayoutEffect((()=>{if(!j||!C)return;const e=y.current;if(!e)return;const t=()=>{const{left:t}=e.getBoundingClientRect(),r=document.documentElement.clientWidth;E({marginLeft:h-t,width:r-2*h})};return t(),window.addEventListener("scroll",t,!0),window.addEventListener("resize",t),()=>{window.removeEventListener("scroll",t,!0),window.removeEventListener("resize",t)}}),[j,C,h,y]),/*#__PURE__*/e.jsxs("div",{"data-testid":"design-system--textFieldDropdown",ref:y,className:"group/dropdown relative flex w-full flex-col gap-2 outline-hidden",onKeyDown:q,tabIndex:p?-1:0,role:"combobox","aria-haspopup":"listbox","aria-expanded":j,"aria-disabled":p,children:[
|
|
8
|
+
/*#__PURE__*/e.jsx(l.SelectBox,{placeholder:c,value:null==a?void 0:a.value,leadingIcon:null==a?void 0:a.leadingIcon,disabled:p,isListOpen:j,onClick:k,error:x,className:v,variant:g,label:L}),B&&/*#__PURE__*/e.jsx(o.SupportTextContainer,{errorMessage:w,supportMessage:m}),j&&/*#__PURE__*/e.jsx(i.Box,{"data-testid":"design-system--textFieldDropdown-panel",className:r.twJoin("z-40",C?"relative":r.twJoin("absolute w-full","label"===g?"top-[72px]":"top-[54px]")),style:C?D:void 0,children:/*#__PURE__*/e.jsx(s.List.Root,{children:d.map(((t,r)=>/*#__PURE__*/e.jsx(s.List.Item,{text:t.value,leadingIcon:t.leadingIcon,onClick:()=>I(t),selected:t.key===(null==a?void 0:a.key),isFocused:r===b},t.key)))})})]})};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
"use strict";var e=require("react/jsx-runtime"),t=require("tailwind-merge");require("../../DataDisplays/Avatar/Avatar.js");var
|
|
2
|
-
return e.jsxs(
|
|
3
|
-
/*#__PURE__*/e.jsx("div",{className:t.twMerge("tracking-default absolute",d?"text-w-gray-400":n?"text-w-red-500":
|
|
4
|
-
/*#__PURE__*/e.jsx(
|
|
5
|
-
|
|
1
|
+
"use strict";var e=require("react/jsx-runtime"),t=require("tailwind-merge");require("../../DataDisplays/Avatar/Avatar.js");var r=require("../../Base/Typography/Typography.js"),a=require("../../Base/Layouts/Box/Box.js");require("../../Base/Layouts/FullBleed/FullBleed.js"),require("react");var s=require("../../DataDisplays/SystemIcon/SystemIcon.js");require("../../DataDisplays/SystemIcon/SystemIcon.constants.js"),require("../../DataDisplays/Accordion/Accordion.js");var i=require("../TextFieldContainer/TextFieldContainer.js");const o=({label:s,value:i,placeholder:o,isFocused:l,isError:n,disabled:d})=>{const c=!!o;/*#__PURE__*/
|
|
2
|
+
return e.jsxs(a.Box,{className:"relative flex h-[42px] w-full flex-col gap-0.5 py-px","data-testid":"design-system--selectBox-label",children:[
|
|
3
|
+
/*#__PURE__*/e.jsx("div",{className:t.twMerge("tracking-default absolute",d?"text-w-gray-400":n?"text-w-red-500":l?"text-primary-500":"text-w-gray-400 group-hover:text-primary-500",c?"typo-caption11":l||i?"scale-[0.6875] -translate-y-0.5 origin-top-left transition-transform duration-300":"typo-body16 transition-transform duration-300 translate-y-2 origin-top-left"),"data-testid":"design-system--label-text",children:s}),
|
|
4
|
+
/*#__PURE__*/e.jsx(r.Typography,{"data-testid":"design-system--selectBox-text",variant:"body16",className:t.twJoin(d?"text-w-gray-300":i?"text-w-gray-600":"text-w-gray-300","w-full pt-[14px]"),children:i||(c?o:"")})]})};exports.SelectBox=({placeholder:a="",value:l="",isListOpen:n,disabled:d=!1,error:c,onClick:y,className:x,variant:u="default",label:p})=>/*#__PURE__*/e.jsxs(i.TextFieldContainer,{isDisabled:d,isFocused:n,isError:c,testId:"design-system--selectBox",onClick:y,className:t.twMerge(// 래퍼(group/dropdown)가 키보드 포커스를 받으면 트리거에 포커스링을 표시한다.
|
|
5
|
+
!d&&"group-focus-visible/dropdown:border-primary group-focus-visible/dropdown:ring-primary-100 group-focus-visible/dropdown:ring-2",x),children:["label"===u?/*#__PURE__*/e.jsx(o,{label:p,value:l,placeholder:a,isFocused:n,isError:c,disabled:d}):/*#__PURE__*/e.jsx(r.Typography,{"data-testid":"design-system--selectBox-text",variant:"body16",className:t.twJoin(d&&l?"text-w-gray-300":d&&!l?"text-w-gray-200":l?"text-w-gray-600":"text-w-gray-300","w-full"),children:l||a}),
|
|
6
|
+
/*#__PURE__*/e.jsx("div",{className:t.twJoin("transition-transform duration-300",n&&"rotate-180"),children:/*#__PURE__*/e.jsx(s.SystemIcon,{name:"medium_arrow_down",className:d?"text-w-gray-300":"text-w-gray-600",testId:"design-system--selectBox-icon"})})]});
|
|
@@ -1 +1,3 @@
|
|
|
1
|
-
"use strict";var e=require("react"),t=require("@wishket/yogokit");exports.useDropdown=({items:r,onItemClick:
|
|
1
|
+
"use strict";var e=require("react"),t=require("@wishket/yogokit");exports.useDropdown=({items:r,onItemClick:n,disabled:l})=>{const[s,u]=e.useState(!1),[c,o]=e.useState(-1),a=e.useRef(null),i=e.useRef(s),k=e.useCallback((()=>{i.current&&(u(!1),o(-1))}),[]);t.useClickOutside(a,k);const f=e=>{n(e),k()};return{isListOpen:s,focusedIndex:c,ref:a,handleItemClick:f,toggleListOpen:e=>{null==e||e.preventDefault(),l||u((e=>(i.current=!e,!e)))},handleKeyDown:e=>{
|
|
2
|
+
// 닫힌 상태에서 Enter/Space/ArrowDown으로 리스트를 연다 (WCAG 2.1.1 키보드 접근성)
|
|
3
|
+
if(s)switch(e.key){case"ArrowDown":e.preventDefault(),o((e=>{const t=e<r.length-1?e+1:e,n=a.current;if(n){const e=n.querySelectorAll("li")[t];null==e||e.scrollIntoView({block:"nearest"})}return t}));break;case"ArrowUp":e.preventDefault(),o((e=>{const t=e>0?e-1:e,r=a.current;if(r){const e=r.querySelectorAll("li")[t];null==e||e.scrollIntoView({block:"nearest"})}return t}));break;case"Enter":e.preventDefault(),c>=0&&f(r[c]);break;case"Escape":e.preventDefault(),k()}else"Enter"!==e.key&&" "!==e.key&&"ArrowDown"!==e.key||(e.preventDefault(),l||i.current||(i.current=!0,u(!0)))}}};
|
|
@@ -1 +1,3 @@
|
|
|
1
|
-
import{useState as e,useRef as
|
|
1
|
+
import{useState as e,useRef as r,useCallback as t}from"react";import{useClickOutside as n}from"@wishket/yogokit";const l=({items:l,onItemClick:o,disabled:c})=>{const[s,u]=e(!1),[a,i]=e(-1),f=r(null),k=r(s),p=t((()=>{k.current&&(u(!1),i(-1))}),[]);n(f,p);const w=e=>{o(e),p()};return{isListOpen:s,focusedIndex:a,ref:f,handleItemClick:w,toggleListOpen:e=>{null==e||e.preventDefault(),c||u((e=>(k.current=!e,!e)))},handleKeyDown:e=>{
|
|
2
|
+
// 닫힌 상태에서 Enter/Space/ArrowDown으로 리스트를 연다 (WCAG 2.1.1 키보드 접근성)
|
|
3
|
+
if(s)switch(e.key){case"ArrowDown":e.preventDefault(),i((e=>{const r=e<l.length-1?e+1:e,t=f.current;if(t){const e=t.querySelectorAll("li")[r];null==e||e.scrollIntoView({block:"nearest"})}return r}));break;case"ArrowUp":e.preventDefault(),i((e=>{const r=e>0?e-1:e,t=f.current;if(t){const e=t.querySelectorAll("li")[r];null==e||e.scrollIntoView({block:"nearest"})}return r}));break;case"Enter":e.preventDefault(),a>=0&&w(l[a]);break;case"Escape":e.preventDefault(),p()}else"Enter"!==e.key&&" "!==e.key&&"ArrowDown"!==e.key||(e.preventDefault(),c||k.current||(k.current=!0,u(!0)))}}};export{l as useDropdown};
|