@wishket/design-system 3.3.0 → 3.4.0

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.
@@ -0,0 +1,4 @@
1
+ import React from 'react';
2
+ import { ServiceLogoPartProps } from '../ServiceLogo.types';
3
+ declare const RiseErpSymbol: React.FC<ServiceLogoPartProps>;
4
+ export { RiseErpSymbol };
@@ -0,0 +1,3 @@
1
+ import{jsxs as e,jsx as t}from"react/jsx-runtime";import"react";const i=({className:i})=>/*#__PURE__*/e("svg",{xmlns:"http://www.w3.org/2000/svg",width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",className:i,"data-testid":"design-system-logo--rise-erp-symbol",children:[
2
+ /*#__PURE__*/t("rect",{x:"2",y:"2",width:"20",height:"20",rx:"3.75",fill:"#0A1120"}),
3
+ /*#__PURE__*/t("polyline",{points:"7,15.75 12,8.25 17,15.75",stroke:"#F59E0B",strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round"})]});export{i as RiseErpSymbol};
@@ -6,3 +6,4 @@ export { YozmITSymbol } from './YozmITSymbol';
6
6
  export { YozmITText } from './YozmITText';
7
7
  export { JobsSymbol } from './JobsSymbol';
8
8
  export { AIDPSymbol } from './AIDPSymbol';
9
+ export { RiseErpSymbol } from './RiseErpSymbol';
@@ -1 +1 @@
1
- import{WishketSymbolText as o}from"./Icons/WishketSymbolText.js";import{WishketSymbol as m}from"./Icons/WishketSymbol.js";import{WishketText as s}from"./Icons/WishketText.js";import{YozmITSymbolText as t}from"./Icons/YozmITSymbolText.js";import{YozmITSymbol as r}from"./Icons/YozmITSymbol.js";import{YozmITText as e}from"./Icons/YozmITText.js";import{JobsSymbol as i}from"./Icons/JobsSymbol.js";import{AIDPSymbol as y}from"./Icons/AIDPSymbol.js";const I=new Map([["wishket_symbol",m],["wishket_symbol_text",o],["wishket_text",s],["yozmIT_symbol",r],["yozmIT_symbol_text",t],["yozmIT_text",e],["jobs_symbol",i],["aidp_symbol",y]]);export{I as LogoMap};
1
+ import{WishketSymbolText as o}from"./Icons/WishketSymbolText.js";import{WishketSymbol as m}from"./Icons/WishketSymbol.js";import{WishketText as s}from"./Icons/WishketText.js";import{YozmITSymbolText as t}from"./Icons/YozmITSymbolText.js";import{YozmITSymbol as r}from"./Icons/YozmITSymbol.js";import{YozmITText as e}from"./Icons/YozmITText.js";import{JobsSymbol as i}from"./Icons/JobsSymbol.js";import{AIDPSymbol as y}from"./Icons/AIDPSymbol.js";import{RiseErpSymbol as b}from"./Icons/RiseErpSymbol.js";const I=new Map([["wishket_symbol",m],["wishket_symbol_text",o],["wishket_text",s],["yozmIT_symbol",r],["yozmIT_symbol_text",t],["yozmIT_text",e],["jobs_symbol",i],["aidp_symbol",y],["rise_erp_symbol",b]]);export{I as LogoMap};
@@ -1,4 +1,4 @@
1
- export type ServiceLogoNames = 'wishket_symbol' | 'wishket_symbol_text' | 'wishket_text' | 'yozmIT_symbol' | 'yozmIT_symbol_text' | 'yozmIT_text' | 'jobs_symbol' | 'aidp_symbol';
1
+ export type ServiceLogoNames = 'wishket_symbol' | 'wishket_symbol_text' | 'wishket_text' | 'yozmIT_symbol' | 'yozmIT_symbol_text' | 'yozmIT_text' | 'jobs_symbol' | 'aidp_symbol' | 'rise_erp_symbol';
2
2
  export type ServiceLogoPartProps = {
3
3
  className?: string;
4
4
  variant?: 'default' | 'disabled' | 'bluegray' | 'white';
@@ -18,6 +18,7 @@ export interface TextFieldDropdownProps {
18
18
  variant?: SelectBoxVariant;
19
19
  label?: string;
20
20
  panelWidth?: 'trigger' | 'viewport';
21
+ panelGutter?: number;
21
22
  }
22
23
  /**
23
24
  * 드롭다운 형태의 텍스트 필드 컴포넌트입니다.
@@ -36,7 +37,8 @@ export interface TextFieldDropdownProps {
36
37
  * @param {boolean} [props.isError] - 오류 상태 여부
37
38
  * @param {'default' | 'label'} [props.variant='default'] - 트리거(SelectBox)의 디자인 변형 타입. `TextField`의 variant와 동일한 시맨틱입니다.
38
39
  * @param {string} [props.label] - `variant="label"`일 때 트리거 위에 플로팅되는 라벨
39
- * @param {'trigger' | 'viewport'} [props.panelWidth='trigger'] - 옵션 패널의 너비 기준. `'trigger'`(기본)는 트리거와 동일한 너비. `'viewport'`는 트리거가 좁아도(예: 모바일 grid 2열) 패널이 화면 전체 너비로 펼쳐져 옵션이 잘리지 않음.
40
+ * @param {number} [props.panelGutter=20] - `panelWidth="viewport"`일 패널과 화면 좌우 사이에 여백(px). 기본값 `20`.
41
+ * @param {'trigger' | 'viewport'} [props.panelWidth='trigger'] - 옵션 패널의 너비 기준. `'trigger'`(기본)는 트리거와 동일한 너비로 트리거 바로 아래에 `absolute`로 겹쳐 펼쳐집니다. `'viewport'`는 트리거가 좁은 컨테이너(예: 모바일 grid 2열)에 있어도 패널이 컨테이너 바깥, 화면 전체 너비로 펼쳐집니다. 이때 패널은 `fixed`가 아니라 in-flow로 렌더되어 자기 높이만큼 실제 영역을 차지하므로(아래 콘텐츠를 밀어냄) 뷰포트 하단에서 잘리지 않고, 옵션이 많으면 패널 내부에서 스크롤됩니다.
40
42
  *
41
43
  * @example
42
44
  * ```tsx
@@ -64,5 +66,5 @@ export interface TextFieldDropdownProps {
64
66
  * />
65
67
  * ```
66
68
  */
67
- declare const TextFieldDropdown: ({ selectedItem, items, onItemClick, placeholder, disabled, isError, errorMessage, supportMessage, className, variant, label, panelWidth, }: TextFieldDropdownProps) => import("react/jsx-runtime").JSX.Element;
69
+ declare const TextFieldDropdown: ({ selectedItem, items, onItemClick, placeholder, disabled, isError, errorMessage, supportMessage, className, variant, label, panelWidth, panelGutter, }: TextFieldDropdownProps) => import("react/jsx-runtime").JSX.Element;
68
70
  export { TextFieldDropdown };
@@ -1,4 +1,4 @@
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 s}from"../List/List.js";import{SupportTextContainer as n}from"../SupportTextContainer/SupportTextContainer.js";import{useDropdown as a}from"../../../hooks/useDropdown.js";import{SelectBox as d}from"./TextFieldDropdown.parts.js";
1
+ "use client";import{jsxs as e,jsx as t}from"react/jsx-runtime";import{useState as o,useLayoutEffect as i}from"react";import{twJoin as r}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 d}from"../../../hooks/useDropdown.js";import{SelectBox as a}from"./TextFieldDropdown.parts.js";
2
2
  /**
3
3
  * 드롭다운 형태의 텍스트 필드 컴포넌트입니다.
4
4
  *
@@ -16,7 +16,8 @@
16
16
  * @param {boolean} [props.isError] - 오류 상태 여부
17
17
  * @param {'default' | 'label'} [props.variant='default'] - 트리거(SelectBox)의 디자인 변형 타입. `TextField`의 variant와 동일한 시맨틱입니다.
18
18
  * @param {string} [props.label] - `variant="label"`일 때 트리거 위에 플로팅되는 라벨
19
- * @param {'trigger' | 'viewport'} [props.panelWidth='trigger'] - 옵션 패널의 너비 기준. `'trigger'`(기본)는 트리거와 동일한 너비. `'viewport'`는 트리거가 좁아도(예: 모바일 grid 2열) 패널이 화면 전체 너비로 펼쳐져 옵션이 잘리지 않음.
19
+ * @param {number} [props.panelGutter=20] - `panelWidth="viewport"`일 패널과 화면 좌우 사이에 여백(px). 기본값 `20`.
20
+ * @param {'trigger' | 'viewport'} [props.panelWidth='trigger'] - 옵션 패널의 너비 기준. `'trigger'`(기본)는 트리거와 동일한 너비로 트리거 바로 아래에 `absolute`로 겹쳐 펼쳐집니다. `'viewport'`는 트리거가 좁은 컨테이너(예: 모바일 grid 2열)에 있어도 패널이 컨테이너 바깥, 화면 전체 너비로 펼쳐집니다. 이때 패널은 `fixed`가 아니라 in-flow로 렌더되어 자기 높이만큼 실제 영역을 차지하므로(아래 콘텐츠를 밀어냄) 뷰포트 하단에서 잘리지 않고, 옵션이 많으면 패널 내부에서 스크롤됩니다.
20
21
  *
21
22
  * @example
22
23
  * ```tsx
@@ -43,8 +44,11 @@
43
44
  * selectedItem={items[0]}
44
45
  * />
45
46
  * ```
46
- */const p=({selectedItem:p,items:m,onItemClick:c,placeholder:u,disabled:f,isError:g,errorMessage:v,supportMessage:w,className:x,variant:h="default",label:I,panelWidth:L="trigger"})=>{const{isListOpen:y,focusedIndex:b,ref:k,handleItemClick:C,toggleListOpen:j,handleKeyDown:B}=a({items:m,onItemClick:c,disabled:f}),D=!!w||!!v,F="label"===h?72:54,E="viewport"===L,[M,N]=o(0);
47
- // viewport 패널은 트리거 폭을 벗어나 화면 전체 너비로 떠야 하므로,
48
- // 트리거의 화면상 위치를 측정해 fixed로 배치한다. (스크롤/리사이즈 추적)
49
- return r((()=>{if(!y||!E)return;const e=k.current;if(!e)return;const t=()=>{N(e.getBoundingClientRect().top+F)};return t(),window.addEventListener("scroll",t,!0),window.addEventListener("resize",t),()=>{window.removeEventListener("scroll",t,!0),window.removeEventListener("resize",t)}}),[y,E,F,k]),/*#__PURE__*/e("div",{"data-testid":"design-system--textFieldDropdown",ref:k,className:"relative flex w-full flex-col gap-2 outline-hidden",onKeyDown:B,tabIndex:0,children:[
50
- /*#__PURE__*/t(d,{placeholder:u,value:null==p?void 0:p.value,leadingIcon:null==p?void 0:p.leadingIcon,disabled:f,isListOpen:y,onClick:j,error:g,className:x,variant:h,label:I}),D&&/*#__PURE__*/t(n,{errorMessage:v,supportMessage:w}),y&&/*#__PURE__*/t(l,{"data-testid":"design-system--textFieldDropdown-panel",className:i("z-40",E?"fixed right-5 left-5":i("absolute w-full","label"===h?"top-[72px]":"top-[54px]")),style:E?{top:M}:void 0,children:/*#__PURE__*/t(s.Root,{children:m.map(((e,o)=>/*#__PURE__*/t(s.Item,{text:e.value,leadingIcon:e.leadingIcon,onClick:()=>C(e),selected:e.key===(null==p?void 0:p.key),isFocused:o===b},e.key)))})})]})};export{p as TextFieldDropdown};
47
+ */const m=({selectedItem:m,items:c,onItemClick:p,placeholder:u,disabled:f,isError:v,errorMessage:g,supportMessage:w,className:x,variant:h="default",label:L,panelWidth:I="trigger",panelGutter:y=20})=>{const{isListOpen:k,focusedIndex:b,ref:C,handleItemClick:j,toggleListOpen:B,handleKeyDown:D}=d({items:c,onItemClick:p,disabled:f}),E=!!w||!!g,F="viewport"===I,[M,N]=o(void 0);
48
+ // viewport 패널은 좁은 컨테이너 바깥, 화면 전체 너비로 펼쳐져야 한다.
49
+ // fixed로 띄우면 out-of-flow라 영역을 차지하지 못해 하단에서 잘리므로,
50
+ // in-flow(relative) 두고 트리거의 화면상 좌측 위치/뷰포트 너비를 측정해
51
+ // 좌우로 full-bleed시킨다. 높이는 in-flow라 실제 영역을 차지하고,
52
+ // 옵션이 많으면 List 내부(max-height)에서 스크롤된다. (리사이즈/스크롤 시 추적)
53
+ return i((()=>{if(!k||!F)return;const e=C.current;if(!e)return;const t=()=>{const{left:t}=e.getBoundingClientRect(),o=document.documentElement.clientWidth;N({marginLeft:y-t,width:o-2*y})};return t(),window.addEventListener("scroll",t,!0),window.addEventListener("resize",t),()=>{window.removeEventListener("scroll",t,!0),window.removeEventListener("resize",t)}}),[k,F,y,C]),/*#__PURE__*/e("div",{"data-testid":"design-system--textFieldDropdown",ref:C,className:"relative flex w-full flex-col gap-2 outline-hidden",onKeyDown:D,tabIndex:0,children:[
54
+ /*#__PURE__*/t(a,{placeholder:u,value:null==m?void 0:m.value,leadingIcon:null==m?void 0:m.leadingIcon,disabled:f,isListOpen:k,onClick:B,error:v,className:x,variant:h,label:L}),E&&/*#__PURE__*/t(s,{errorMessage:g,supportMessage:w}),k&&/*#__PURE__*/t(l,{"data-testid":"design-system--textFieldDropdown-panel",className:r("z-40",F?"relative":r("absolute w-full","label"===h?"top-[72px]":"top-[54px]")),style:F?M:void 0,children:/*#__PURE__*/t(n.Root,{children:c.map(((e,o)=>/*#__PURE__*/t(n.Item,{text:e.value,leadingIcon:e.leadingIcon,onClick:()=>j(e),selected:e.key===(null==m?void 0:m.key),isFocused:o===b},e.key)))})})]})};export{m as TextFieldDropdown};
@@ -0,0 +1,3 @@
1
+ "use strict";var e=require("react/jsx-runtime");require("react");exports.RiseErpSymbol=({className:s})=>/*#__PURE__*/e.jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",className:s,"data-testid":"design-system-logo--rise-erp-symbol",children:[
2
+ /*#__PURE__*/e.jsx("rect",{x:"2",y:"2",width:"20",height:"20",rx:"3.75",fill:"#0A1120"}),
3
+ /*#__PURE__*/e.jsx("polyline",{points:"7,15.75 12,8.25 17,15.75",stroke:"#F59E0B",strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round"})]});
@@ -1 +1 @@
1
- "use strict";var o=require("./Icons/WishketSymbolText.js"),e=require("./Icons/WishketSymbol.js"),s=require("./Icons/WishketText.js"),t=require("./Icons/YozmITSymbolText.js"),m=require("./Icons/YozmITSymbol.js"),b=require("./Icons/YozmITText.js"),y=require("./Icons/JobsSymbol.js"),i=require("./Icons/AIDPSymbol.js");const r=new Map([["wishket_symbol",e.WishketSymbol],["wishket_symbol_text",o.WishketSymbolText],["wishket_text",s.WishketText],["yozmIT_symbol",m.YozmITSymbol],["yozmIT_symbol_text",t.YozmITSymbolText],["yozmIT_text",b.YozmITText],["jobs_symbol",y.JobsSymbol],["aidp_symbol",i.AIDPSymbol]]);exports.LogoMap=r;
1
+ "use strict";var e=require("./Icons/WishketSymbolText.js"),o=require("./Icons/WishketSymbol.js"),s=require("./Icons/WishketText.js"),m=require("./Icons/YozmITSymbolText.js"),t=require("./Icons/YozmITSymbol.js"),r=require("./Icons/YozmITText.js"),b=require("./Icons/JobsSymbol.js"),y=require("./Icons/AIDPSymbol.js"),i=require("./Icons/RiseErpSymbol.js");const l=new Map([["wishket_symbol",o.WishketSymbol],["wishket_symbol_text",e.WishketSymbolText],["wishket_text",s.WishketText],["yozmIT_symbol",t.YozmITSymbol],["yozmIT_symbol_text",m.YozmITSymbolText],["yozmIT_text",r.YozmITText],["jobs_symbol",b.JobsSymbol],["aidp_symbol",y.AIDPSymbol],["rise_erp_symbol",i.RiseErpSymbol]]);exports.LogoMap=l;
@@ -1,5 +1,8 @@
1
- "use client";"use strict";var e=require("react/jsx-runtime"),t=require("react"),r=require("tailwind-merge"),s=require("../../Base/Layouts/Box/Box.js");require("../../Base/Layouts/FullBleed/FullBleed.js");var i=require("../List/List.js"),l=require("../SupportTextContainer/SupportTextContainer.js"),o=require("../../../hooks/useDropdown.js"),n=require("./TextFieldDropdown.parts.js");exports.TextFieldDropdown=({selectedItem:a,items:d,onItemClick:u,placeholder:c,disabled:p,isError:x,errorMessage:w,supportMessage:v,className:g,variant:m="default",label:f,panelWidth:L="trigger"})=>{const{isListOpen:j,focusedIndex:h,ref:y,handleItemClick:I,toggleListOpen:b,handleKeyDown:k}=o.useDropdown({items:d,onItemClick:u,disabled:p}),q=!!v||!!w,B="label"===m?72:54,C="viewport"===L,[D,F]=t.useState(0);
2
- // viewport 패널은 트리거 폭을 벗어나 화면 전체 너비로 떠야 하므로,
3
- // 트리거의 화면상 위치를 측정해 fixed로 배치한다. (스크롤/리사이즈 추적)
4
- return t.useLayoutEffect((()=>{if(!j||!C)return;const e=y.current;if(!e)return;const t=()=>{F(e.getBoundingClientRect().top+B)};return t(),window.addEventListener("scroll",t,!0),window.addEventListener("resize",t),()=>{window.removeEventListener("scroll",t,!0),window.removeEventListener("resize",t)}}),[j,C,B,y]),/*#__PURE__*/e.jsxs("div",{"data-testid":"design-system--textFieldDropdown",ref:y,className:"relative flex w-full flex-col gap-2 outline-hidden",onKeyDown:k,tabIndex:0,children:[
5
- /*#__PURE__*/e.jsx(n.SelectBox,{placeholder:c,value:null==a?void 0:a.value,leadingIcon:null==a?void 0:a.leadingIcon,disabled:p,isListOpen:j,onClick:b,error:x,className:g,variant:m,label:f}),q&&/*#__PURE__*/e.jsx(l.SupportTextContainer,{errorMessage:w,supportMessage:v}),j&&/*#__PURE__*/e.jsx(s.Box,{"data-testid":"design-system--textFieldDropdown-panel",className:r.twJoin("z-40",C?"fixed right-5 left-5":r.twJoin("absolute w-full","label"===m?"top-[72px]":"top-[54px]")),style:C?{top:D}:void 0,children:/*#__PURE__*/e.jsx(i.List.Root,{children:d.map(((t,r)=>/*#__PURE__*/e.jsx(i.List.Item,{text:t.value,leadingIcon:t.leadingIcon,onClick:()=>I(t),selected:t.key===(null==a?void 0:a.key),isFocused:r===h},t.key)))})})]})};
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"),n=require("../SupportTextContainer/SupportTextContainer.js"),l=require("../../../hooks/useDropdown.js"),o=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:j=20})=>{const{isListOpen:h,focusedIndex:y,ref:I,handleItemClick:k,toggleListOpen:q,handleKeyDown:B}=l.useDropdown({items:d,onItemClick:u,disabled:p}),C=!!m||!!w,b="viewport"===f,[D,E]=t.useState(void 0);
2
+ // viewport 패널은 좁은 컨테이너 바깥, 화면 전체 너비로 펼쳐져야 한다.
3
+ // fixed로 띄우면 out-of-flow라 영역을 차지하지 못해 하단에서 잘리므로,
4
+ // in-flow(relative) 두고 트리거의 화면상 좌측 위치/뷰포트 너비를 측정해
5
+ // 좌우로 full-bleed시킨다. 높이는 in-flow라 실제 영역을 차지하고,
6
+ // 옵션이 많으면 List 내부(max-height)에서 스크롤된다. (리사이즈/스크롤 시 추적)
7
+ return t.useLayoutEffect((()=>{if(!h||!b)return;const e=I.current;if(!e)return;const t=()=>{const{left:t}=e.getBoundingClientRect(),r=document.documentElement.clientWidth;E({marginLeft:j-t,width:r-2*j})};return t(),window.addEventListener("scroll",t,!0),window.addEventListener("resize",t),()=>{window.removeEventListener("scroll",t,!0),window.removeEventListener("resize",t)}}),[h,b,j,I]),/*#__PURE__*/e.jsxs("div",{"data-testid":"design-system--textFieldDropdown",ref:I,className:"relative flex w-full flex-col gap-2 outline-hidden",onKeyDown:B,tabIndex:0,children:[
8
+ /*#__PURE__*/e.jsx(o.SelectBox,{placeholder:c,value:null==a?void 0:a.value,leadingIcon:null==a?void 0:a.leadingIcon,disabled:p,isListOpen:h,onClick:q,error:x,className:v,variant:g,label:L}),C&&/*#__PURE__*/e.jsx(n.SupportTextContainer,{errorMessage:w,supportMessage:m}),h&&/*#__PURE__*/e.jsx(i.Box,{"data-testid":"design-system--textFieldDropdown-panel",className:r.twJoin("z-40",b?"relative":r.twJoin("absolute w-full","label"===g?"top-[72px]":"top-[54px]")),style:b?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:()=>k(t),selected:t.key===(null==a?void 0:a.key),isFocused:r===y},t.key)))})})]})};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wishket/design-system",
3
- "version": "3.3.0",
3
+ "version": "3.4.0",
4
4
  "type": "module",
5
5
  "description": "Wishket Design System",
6
6
  "main": "dist/index.js",