sellmate-design-system-react 0.1.10 → 0.2.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.
Files changed (163) hide show
  1. package/dist/components/SActionModal/SActionModal.cjs +10 -4
  2. package/dist/components/SActionModal/SActionModal.cjs.map +1 -1
  3. package/dist/components/SActionModal/SActionModal.js +10 -4
  4. package/dist/components/SActionModal/SActionModal.js.map +1 -1
  5. package/dist/components/SBarcodeInput/SBarcodeInput.cjs +22 -5
  6. package/dist/components/SBarcodeInput/SBarcodeInput.cjs.map +1 -1
  7. package/dist/components/SBarcodeInput/SBarcodeInput.d.ts +3 -1
  8. package/dist/components/SBarcodeInput/SBarcodeInput.js +22 -5
  9. package/dist/components/SBarcodeInput/SBarcodeInput.js.map +1 -1
  10. package/dist/components/SCalendar/SCalendar.cjs +9 -3
  11. package/dist/components/SCalendar/SCalendar.cjs.map +1 -1
  12. package/dist/components/SCalendar/SCalendar.js +9 -3
  13. package/dist/components/SCalendar/SCalendar.js.map +1 -1
  14. package/dist/components/SChip/SChip.cjs +9 -3
  15. package/dist/components/SChip/SChip.cjs.map +1 -1
  16. package/dist/components/SChip/SChip.js +9 -3
  17. package/dist/components/SChip/SChip.js.map +1 -1
  18. package/dist/components/SChipInput/SChipInput.cjs +44 -13
  19. package/dist/components/SChipInput/SChipInput.cjs.map +1 -1
  20. package/dist/components/SChipInput/SChipInput.d.ts +5 -0
  21. package/dist/components/SChipInput/SChipInput.js +44 -13
  22. package/dist/components/SChipInput/SChipInput.js.map +1 -1
  23. package/dist/components/SChipInput/index.d.ts +1 -1
  24. package/dist/components/SCircleProgress/SCircleProgress.cjs +6 -2
  25. package/dist/components/SCircleProgress/SCircleProgress.cjs.map +1 -1
  26. package/dist/components/SCircleProgress/SCircleProgress.js +6 -2
  27. package/dist/components/SCircleProgress/SCircleProgress.js.map +1 -1
  28. package/dist/components/SConfirmModal/SConfirmModal.cjs +20 -13
  29. package/dist/components/SConfirmModal/SConfirmModal.cjs.map +1 -1
  30. package/dist/components/SConfirmModal/SConfirmModal.d.ts +7 -4
  31. package/dist/components/SConfirmModal/SConfirmModal.js +20 -13
  32. package/dist/components/SConfirmModal/SConfirmModal.js.map +1 -1
  33. package/dist/components/SDatePicker/SDatePicker.cjs +22 -5
  34. package/dist/components/SDatePicker/SDatePicker.cjs.map +1 -1
  35. package/dist/components/SDatePicker/SDatePicker.d.ts +3 -1
  36. package/dist/components/SDatePicker/SDatePicker.js +22 -5
  37. package/dist/components/SDatePicker/SDatePicker.js.map +1 -1
  38. package/dist/components/SDateRangePicker/SDateRangePicker.cjs +22 -5
  39. package/dist/components/SDateRangePicker/SDateRangePicker.cjs.map +1 -1
  40. package/dist/components/SDateRangePicker/SDateRangePicker.d.ts +3 -1
  41. package/dist/components/SDateRangePicker/SDateRangePicker.js +22 -5
  42. package/dist/components/SDateRangePicker/SDateRangePicker.js.map +1 -1
  43. package/dist/components/SDropdownButton/SDropdownButton.cjs +3 -1
  44. package/dist/components/SDropdownButton/SDropdownButton.cjs.map +1 -1
  45. package/dist/components/SDropdownButton/SDropdownButton.js +3 -1
  46. package/dist/components/SDropdownButton/SDropdownButton.js.map +1 -1
  47. package/dist/components/SField/SField.cjs +20 -5
  48. package/dist/components/SField/SField.cjs.map +1 -1
  49. package/dist/components/SField/SField.d.ts +4 -1
  50. package/dist/components/SField/SField.js +20 -5
  51. package/dist/components/SField/SField.js.map +1 -1
  52. package/dist/components/SFilePicker/SFilePicker.cjs +23 -6
  53. package/dist/components/SFilePicker/SFilePicker.cjs.map +1 -1
  54. package/dist/components/SFilePicker/SFilePicker.d.ts +3 -1
  55. package/dist/components/SFilePicker/SFilePicker.js +23 -6
  56. package/dist/components/SFilePicker/SFilePicker.js.map +1 -1
  57. package/dist/components/SGhostButton/SGhostButton.cjs +9 -3
  58. package/dist/components/SGhostButton/SGhostButton.cjs.map +1 -1
  59. package/dist/components/SGhostButton/SGhostButton.d.ts +5 -1
  60. package/dist/components/SGhostButton/SGhostButton.js +9 -3
  61. package/dist/components/SGhostButton/SGhostButton.js.map +1 -1
  62. package/dist/components/SGnb/SGnb.cjs +3297 -0
  63. package/dist/components/SGnb/SGnb.cjs.map +1 -0
  64. package/dist/components/SGnb/SGnb.d.ts +35 -0
  65. package/dist/components/SGnb/SGnb.js +3295 -0
  66. package/dist/components/SGnb/SGnb.js.map +1 -0
  67. package/dist/components/SGnb/gnb.config.d.ts +63 -0
  68. package/dist/components/SGnb/index.d.ts +2 -0
  69. package/dist/components/SGuide/SGuide.cjs +9 -3
  70. package/dist/components/SGuide/SGuide.cjs.map +1 -1
  71. package/dist/components/SGuide/SGuide.js +9 -3
  72. package/dist/components/SGuide/SGuide.js.map +1 -1
  73. package/dist/components/SInput/SInput.cjs +22 -5
  74. package/dist/components/SInput/SInput.cjs.map +1 -1
  75. package/dist/components/SInput/SInput.d.ts +4 -1
  76. package/dist/components/SInput/SInput.js +22 -5
  77. package/dist/components/SInput/SInput.js.map +1 -1
  78. package/dist/components/SKeyValueTable/SKeyValueTable.cjs +511 -209
  79. package/dist/components/SKeyValueTable/SKeyValueTable.cjs.map +1 -1
  80. package/dist/components/SKeyValueTable/SKeyValueTable.d.ts +27 -6
  81. package/dist/components/SKeyValueTable/SKeyValueTable.js +510 -208
  82. package/dist/components/SKeyValueTable/SKeyValueTable.js.map +1 -1
  83. package/dist/components/SLayout/SLayout.cjs +79 -0
  84. package/dist/components/SLayout/SLayout.cjs.map +1 -0
  85. package/dist/components/SLayout/SLayout.d.ts +41 -0
  86. package/dist/components/SLayout/SLayout.js +75 -0
  87. package/dist/components/SLayout/SLayout.js.map +1 -0
  88. package/dist/components/SLayout/index.d.ts +1 -0
  89. package/dist/components/SLoadingContainer/SLoadingContainer.cjs +6 -2
  90. package/dist/components/SLoadingContainer/SLoadingContainer.cjs.map +1 -1
  91. package/dist/components/SLoadingContainer/SLoadingContainer.js +6 -2
  92. package/dist/components/SLoadingContainer/SLoadingContainer.js.map +1 -1
  93. package/dist/components/SLoadingContainer/loading.cjs +6 -2
  94. package/dist/components/SLoadingContainer/loading.cjs.map +1 -1
  95. package/dist/components/SLoadingContainer/loading.js +6 -2
  96. package/dist/components/SLoadingContainer/loading.js.map +1 -1
  97. package/dist/components/SLoadingModal/SLoadingModal.cjs +16 -6
  98. package/dist/components/SLoadingModal/SLoadingModal.cjs.map +1 -1
  99. package/dist/components/SLoadingModal/SLoadingModal.js +16 -6
  100. package/dist/components/SLoadingModal/SLoadingModal.js.map +1 -1
  101. package/dist/components/SModalContainer/SModalContainer.cjs +10 -4
  102. package/dist/components/SModalContainer/SModalContainer.cjs.map +1 -1
  103. package/dist/components/SModalContainer/SModalContainer.d.ts +10 -0
  104. package/dist/components/SModalContainer/SModalContainer.js +10 -4
  105. package/dist/components/SModalContainer/SModalContainer.js.map +1 -1
  106. package/dist/components/SNumberInput/SNumberInput.cjs +22 -5
  107. package/dist/components/SNumberInput/SNumberInput.cjs.map +1 -1
  108. package/dist/components/SNumberInput/SNumberInput.d.ts +2 -0
  109. package/dist/components/SNumberInput/SNumberInput.js +22 -5
  110. package/dist/components/SNumberInput/SNumberInput.js.map +1 -1
  111. package/dist/components/SPage/SPage.cjs +86 -0
  112. package/dist/components/SPage/SPage.cjs.map +1 -0
  113. package/dist/components/SPage/SPage.d.ts +13 -0
  114. package/dist/components/SPage/SPage.js +84 -0
  115. package/dist/components/SPage/SPage.js.map +1 -0
  116. package/dist/components/SPage/index.d.ts +1 -0
  117. package/dist/components/SPopover/SPopover.cjs +9 -3
  118. package/dist/components/SPopover/SPopover.cjs.map +1 -1
  119. package/dist/components/SPopover/SPopover.js +9 -3
  120. package/dist/components/SPopover/SPopover.js.map +1 -1
  121. package/dist/components/SPortal/SPortal.cjs +3 -1
  122. package/dist/components/SPortal/SPortal.cjs.map +1 -1
  123. package/dist/components/SPortal/SPortal.js +3 -1
  124. package/dist/components/SPortal/SPortal.js.map +1 -1
  125. package/dist/components/SSelect/SSelect.cjs +545 -265
  126. package/dist/components/SSelect/SSelect.cjs.map +1 -1
  127. package/dist/components/SSelect/SSelect.d.ts +4 -2
  128. package/dist/components/SSelect/SSelect.js +546 -265
  129. package/dist/components/SSelect/SSelect.js.map +1 -1
  130. package/dist/components/STable/STable.cjs +552 -268
  131. package/dist/components/STable/STable.cjs.map +1 -1
  132. package/dist/components/STable/STable.js +553 -268
  133. package/dist/components/STable/STable.js.map +1 -1
  134. package/dist/components/STextLink/STextLink.cjs +2 -0
  135. package/dist/components/STextLink/STextLink.cjs.map +1 -1
  136. package/dist/components/STextLink/STextLink.js +2 -0
  137. package/dist/components/STextLink/STextLink.js.map +1 -1
  138. package/dist/components/STextarea/STextarea.cjs +22 -5
  139. package/dist/components/STextarea/STextarea.cjs.map +1 -1
  140. package/dist/components/STextarea/STextarea.d.ts +2 -0
  141. package/dist/components/STextarea/STextarea.js +22 -5
  142. package/dist/components/STextarea/STextarea.js.map +1 -1
  143. package/dist/components/SToast/SToast.cjs +9 -3
  144. package/dist/components/SToast/SToast.cjs.map +1 -1
  145. package/dist/components/SToast/SToast.js +9 -3
  146. package/dist/components/SToast/SToast.js.map +1 -1
  147. package/dist/components/SToast/SToastContainer.cjs +9 -3
  148. package/dist/components/SToast/SToastContainer.cjs.map +1 -1
  149. package/dist/components/SToast/SToastContainer.js +9 -3
  150. package/dist/components/SToast/SToastContainer.js.map +1 -1
  151. package/dist/components/STooltip/STooltip.cjs +9 -3
  152. package/dist/components/STooltip/STooltip.cjs.map +1 -1
  153. package/dist/components/STooltip/STooltip.js +9 -3
  154. package/dist/components/STooltip/STooltip.js.map +1 -1
  155. package/dist/index.cjs +840 -199
  156. package/dist/index.cjs.map +1 -1
  157. package/dist/index.d.ts +3 -1
  158. package/dist/index.js +832 -200
  159. package/dist/index.js.map +1 -1
  160. package/dist/lib/portal-container.d.ts +7 -0
  161. package/dist/styles.css +253 -63
  162. package/dist/theme.css +66 -13
  163. package/package.json +1 -1
@@ -1 +1 @@
1
- export { SChipInput, type SChipInputProps, type SChipInputSize } from './SChipInput';
1
+ export { SChipInput, type SChipInputMetaPlacement, type SChipInputProps, type SChipInputSize, } from './SChipInput';
@@ -48,8 +48,12 @@ var SCircleProgress = react.forwardRef(
48
48
  "span",
49
49
  {
50
50
  className: cn(
51
- "text-center text-[16px] font-bold leading-[26px]",
52
- innerValue && "absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2"
51
+ "text-center text-[16px] font-bold",
52
+ innerValue ? (
53
+ // leading-[normal]: 26px leading 은 폰트 content(19px) 위아래로 홀수(7px)만큼 남아
54
+ // 3px/4px 로 쪼개지고 글자가 링 중심보다 위로 뜬다. (leading-normal 은 1.5 라 동일 문제)
55
+ "absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 leading-[normal]"
56
+ ) : "leading-[26px]"
53
57
  ),
54
58
  style: { color: percentColor },
55
59
  children: [
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/lib/cn.ts","../../../src/components/SCircleProgress/SCircleProgress.tsx"],"names":["extendTailwindMerge","clsx","forwardRef","SCircleProgress","jsxs","jsx"],"mappings":"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","file":"SCircleProgress.cjs","sourcesContent":["import { clsx, type ClassValue } from 'clsx';\nimport { extendTailwindMerge } from 'tailwind-merge';\n\n/**\n * theme.css 의 --text-* 는 기본 Tailwind 폰트사이즈 스케일(xs/sm/base...)이 아닌\n * 숫자 스케일(10~32)이라, 확장 없이는 tailwind-merge 가 이를 텍스트 컬러 그룹으로\n * 오인해 text-12 같은 클래스를 text-(--color-var) 뒤에서 충돌 제거해버린다.\n */\nconst twMerge = extendTailwindMerge({\n extend: {\n classGroups: {\n 'font-size': [{ text: ['10', '11', '12', '13', '14', '16', '18', '20', '24', '28', '32'] }],\n },\n },\n});\n\n/**\n * className 병합 유틸.\n * clsx로 조건부 클래스를 합치고, tailwind-merge로 Tailwind 클래스 충돌을 해소한다.\n */\nexport function cn(...inputs: ClassValue[]): string {\n return twMerge(clsx(inputs));\n}\n","import { forwardRef, type CSSProperties } from 'react';\nimport { cn } from '../../lib/cn';\n\nexport type SCircleProgressType = 'primary' | 'inverse' | 'error' | 'complete';\n\nconst VIEWBOX = 80;\nconst RADIUS = 34;\nconst STROKE = 12;\nconst CIRCUMFERENCE = 2 * Math.PI * RADIUS;\n\nconst COLOR_MAP: Record<SCircleProgressType, { arc: string; track: string }> = {\n primary: { arc: 'var(--cmp-progress-active-color)', track: 'var(--cmp-progress-color-track)' },\n // inverse: 어두운 배경용 — arc 흰색, track 은 흰색 40%(회색 링)\n inverse: { arc: 'var(--color-white)', track: 'rgba(255,255,255,0.4)' },\n error: { arc: 'var(--color-red-75)', track: 'var(--cmp-progress-color-track)' },\n complete: { arc: '#01BB4B', track: 'var(--cmp-progress-color-track)' },\n};\n\nexport interface SCircleProgressProps {\n /** 진행률 (0–100) */\n value?: number;\n /** 색상 테마 */\n type?: SCircleProgressType;\n /** 불확정(스피너) 모드 — value 무시 */\n indeterminate?: boolean;\n /** 하단 레이블 */\n label?: string;\n /** true면 퍼센트를 원 아래가 아닌 원 가운데에 표시 */\n innerValue?: boolean;\n className?: string;\n style?: CSSProperties;\n}\n\nconst clamp = (v: number) => (Number.isFinite(v) ? Math.max(0, Math.min(100, v)) : 0);\n\n/** SCircleProgress — sd-circle-progress 포팅. determinate=진행률 arc, indeterminate=스피너. */\nexport const SCircleProgress = forwardRef<HTMLDivElement, SCircleProgressProps>(\n function SCircleProgress(\n {\n value = 0,\n type = 'primary',\n indeterminate = false,\n label,\n innerValue = false,\n className,\n style,\n },\n ref,\n ) {\n const v = clamp(value);\n const colors = COLOR_MAP[type];\n const c = VIEWBOX / 2;\n const percentColor = v === 0 ? 'var(--sys-color-fg-tertiary, #888888)' : colors.arc;\n const filled = (v / 100) * CIRCUMFERENCE;\n const showPercent = !indeterminate;\n const percentNode = (\n <span\n className={cn(\n 'text-center text-[16px] font-bold leading-[26px]',\n innerValue && 'absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2',\n )}\n style={{ color: percentColor }}\n >\n {Math.round(v)}%\n </span>\n );\n\n return (\n <div\n ref={ref}\n className={cn(\n 'inline-flex flex-col items-center gap-[var(--cmp-progress-circular-gap)]',\n className,\n )}\n style={style}\n >\n <div className={cn(innerValue && 'relative')}>\n <svg\n viewBox={`0 0 ${VIEWBOX} ${VIEWBOX}`}\n xmlns=\"http://www.w3.org/2000/svg\"\n className={cn(\n 'h-[80px] w-[80px]',\n indeterminate && 'origin-center animate-circle-spin',\n )}\n >\n <circle\n cx={c}\n cy={c}\n r={RADIUS}\n fill=\"none\"\n strokeWidth={STROKE}\n style={{ stroke: colors.track }}\n />\n <circle\n cx={c}\n cy={c}\n r={RADIUS}\n fill=\"none\"\n strokeWidth={STROKE}\n strokeLinecap=\"round\"\n className={cn(\n 'origin-center',\n indeterminate\n ? 'animate-circle-arc'\n : '-rotate-90 transition-[stroke-dasharray] duration-[400ms] ease-linear',\n )}\n style={{\n stroke: colors.arc,\n ...(indeterminate\n ? {}\n : { strokeDasharray: `${filled} ${CIRCUMFERENCE}`, strokeDashoffset: 0 }),\n }}\n />\n </svg>\n {/* innerValue: 원 가운데에 퍼센트 오버레이 */}\n {showPercent && innerValue && percentNode}\n </div>\n {/* 기본: 퍼센트를 원(ring) 아래에 표시 */}\n {showPercent && !innerValue && percentNode}\n {label && (\n <span className=\"text-center text-[12px] font-normal leading-[20px] text-[color:var(--cmp-progress-color-label)]\">\n {label}\n </span>\n )}\n </div>\n );\n },\n);\n"]}
1
+ {"version":3,"sources":["../../../src/lib/cn.ts","../../../src/components/SCircleProgress/SCircleProgress.tsx"],"names":["extendTailwindMerge","clsx","forwardRef","SCircleProgress","jsxs","jsx"],"mappings":"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","file":"SCircleProgress.cjs","sourcesContent":["import { clsx, type ClassValue } from 'clsx';\nimport { extendTailwindMerge } from 'tailwind-merge';\n\n/**\n * theme.css 의 --text-* 는 기본 Tailwind 폰트사이즈 스케일(xs/sm/base...)이 아닌\n * 숫자 스케일(10~32)이라, 확장 없이는 tailwind-merge 가 이를 텍스트 컬러 그룹으로\n * 오인해 text-12 같은 클래스를 text-(--color-var) 뒤에서 충돌 제거해버린다.\n */\nconst twMerge = extendTailwindMerge({\n extend: {\n classGroups: {\n 'font-size': [{ text: ['10', '11', '12', '13', '14', '16', '18', '20', '24', '28', '32'] }],\n },\n },\n});\n\n/**\n * className 병합 유틸.\n * clsx로 조건부 클래스를 합치고, tailwind-merge로 Tailwind 클래스 충돌을 해소한다.\n */\nexport function cn(...inputs: ClassValue[]): string {\n return twMerge(clsx(inputs));\n}\n","import { forwardRef, type CSSProperties } from 'react';\nimport { cn } from '../../lib/cn';\n\nexport type SCircleProgressType = 'primary' | 'inverse' | 'error' | 'complete';\n\nconst VIEWBOX = 80;\nconst RADIUS = 34;\nconst STROKE = 12;\nconst CIRCUMFERENCE = 2 * Math.PI * RADIUS;\n\nconst COLOR_MAP: Record<SCircleProgressType, { arc: string; track: string }> = {\n primary: { arc: 'var(--cmp-progress-active-color)', track: 'var(--cmp-progress-color-track)' },\n // inverse: 어두운 배경용 — arc 흰색, track 은 흰색 40%(회색 링)\n inverse: { arc: 'var(--color-white)', track: 'rgba(255,255,255,0.4)' },\n error: { arc: 'var(--color-red-75)', track: 'var(--cmp-progress-color-track)' },\n complete: { arc: '#01BB4B', track: 'var(--cmp-progress-color-track)' },\n};\n\nexport interface SCircleProgressProps {\n /** 진행률 (0–100) */\n value?: number;\n /** 색상 테마 */\n type?: SCircleProgressType;\n /** 불확정(스피너) 모드 — value 무시 */\n indeterminate?: boolean;\n /** 하단 레이블 */\n label?: string;\n /** true면 퍼센트를 원 아래가 아닌 원 가운데에 표시 */\n innerValue?: boolean;\n className?: string;\n style?: CSSProperties;\n}\n\nconst clamp = (v: number) => (Number.isFinite(v) ? Math.max(0, Math.min(100, v)) : 0);\n\n/** SCircleProgress — sd-circle-progress 포팅. determinate=진행률 arc, indeterminate=스피너. */\nexport const SCircleProgress = forwardRef<HTMLDivElement, SCircleProgressProps>(\n function SCircleProgress(\n {\n value = 0,\n type = 'primary',\n indeterminate = false,\n label,\n innerValue = false,\n className,\n style,\n },\n ref,\n ) {\n const v = clamp(value);\n const colors = COLOR_MAP[type];\n const c = VIEWBOX / 2;\n const percentColor = v === 0 ? 'var(--sys-color-fg-tertiary, #888888)' : colors.arc;\n const filled = (v / 100) * CIRCUMFERENCE;\n const showPercent = !indeterminate;\n const percentNode = (\n <span\n className={cn(\n 'text-center text-[16px] font-bold',\n innerValue\n ? // leading-[normal]: 26px leading 은 폰트 content(19px) 위아래로 홀수(7px)만큼 남아\n // 3px/4px 로 쪼개지고 글자가 링 중심보다 위로 뜬다. (leading-normal 은 1.5 라 동일 문제)\n 'absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 leading-[normal]'\n : 'leading-[26px]',\n )}\n style={{ color: percentColor }}\n >\n {Math.round(v)}%\n </span>\n );\n\n return (\n <div\n ref={ref}\n className={cn(\n 'inline-flex flex-col items-center gap-[var(--cmp-progress-circular-gap)]',\n className,\n )}\n style={style}\n >\n <div className={cn(innerValue && 'relative')}>\n <svg\n viewBox={`0 0 ${VIEWBOX} ${VIEWBOX}`}\n xmlns=\"http://www.w3.org/2000/svg\"\n className={cn(\n 'h-[80px] w-[80px]',\n indeterminate && 'origin-center animate-circle-spin',\n )}\n >\n <circle\n cx={c}\n cy={c}\n r={RADIUS}\n fill=\"none\"\n strokeWidth={STROKE}\n style={{ stroke: colors.track }}\n />\n <circle\n cx={c}\n cy={c}\n r={RADIUS}\n fill=\"none\"\n strokeWidth={STROKE}\n strokeLinecap=\"round\"\n className={cn(\n 'origin-center',\n indeterminate\n ? 'animate-circle-arc'\n : '-rotate-90 transition-[stroke-dasharray] duration-[400ms] ease-linear',\n )}\n style={{\n stroke: colors.arc,\n ...(indeterminate\n ? {}\n : { strokeDasharray: `${filled} ${CIRCUMFERENCE}`, strokeDashoffset: 0 }),\n }}\n />\n </svg>\n {/* innerValue: 원 가운데에 퍼센트 오버레이 */}\n {showPercent && innerValue && percentNode}\n </div>\n {/* 기본: 퍼센트를 원(ring) 아래에 표시 */}\n {showPercent && !innerValue && percentNode}\n {label && (\n <span className=\"text-center text-[12px] font-normal leading-[20px] text-[color:var(--cmp-progress-color-label)]\">\n {label}\n </span>\n )}\n </div>\n );\n },\n);\n"]}
@@ -46,8 +46,12 @@ var SCircleProgress = forwardRef(
46
46
  "span",
47
47
  {
48
48
  className: cn(
49
- "text-center text-[16px] font-bold leading-[26px]",
50
- innerValue && "absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2"
49
+ "text-center text-[16px] font-bold",
50
+ innerValue ? (
51
+ // leading-[normal]: 26px leading 은 폰트 content(19px) 위아래로 홀수(7px)만큼 남아
52
+ // 3px/4px 로 쪼개지고 글자가 링 중심보다 위로 뜬다. (leading-normal 은 1.5 라 동일 문제)
53
+ "absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 leading-[normal]"
54
+ ) : "leading-[26px]"
51
55
  ),
52
56
  style: { color: percentColor },
53
57
  children: [
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/lib/cn.ts","../../../src/components/SCircleProgress/SCircleProgress.tsx"],"names":["SCircleProgress"],"mappings":"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","file":"SCircleProgress.js","sourcesContent":["import { clsx, type ClassValue } from 'clsx';\nimport { extendTailwindMerge } from 'tailwind-merge';\n\n/**\n * theme.css 의 --text-* 는 기본 Tailwind 폰트사이즈 스케일(xs/sm/base...)이 아닌\n * 숫자 스케일(10~32)이라, 확장 없이는 tailwind-merge 가 이를 텍스트 컬러 그룹으로\n * 오인해 text-12 같은 클래스를 text-(--color-var) 뒤에서 충돌 제거해버린다.\n */\nconst twMerge = extendTailwindMerge({\n extend: {\n classGroups: {\n 'font-size': [{ text: ['10', '11', '12', '13', '14', '16', '18', '20', '24', '28', '32'] }],\n },\n },\n});\n\n/**\n * className 병합 유틸.\n * clsx로 조건부 클래스를 합치고, tailwind-merge로 Tailwind 클래스 충돌을 해소한다.\n */\nexport function cn(...inputs: ClassValue[]): string {\n return twMerge(clsx(inputs));\n}\n","import { forwardRef, type CSSProperties } from 'react';\nimport { cn } from '../../lib/cn';\n\nexport type SCircleProgressType = 'primary' | 'inverse' | 'error' | 'complete';\n\nconst VIEWBOX = 80;\nconst RADIUS = 34;\nconst STROKE = 12;\nconst CIRCUMFERENCE = 2 * Math.PI * RADIUS;\n\nconst COLOR_MAP: Record<SCircleProgressType, { arc: string; track: string }> = {\n primary: { arc: 'var(--cmp-progress-active-color)', track: 'var(--cmp-progress-color-track)' },\n // inverse: 어두운 배경용 — arc 흰색, track 은 흰색 40%(회색 링)\n inverse: { arc: 'var(--color-white)', track: 'rgba(255,255,255,0.4)' },\n error: { arc: 'var(--color-red-75)', track: 'var(--cmp-progress-color-track)' },\n complete: { arc: '#01BB4B', track: 'var(--cmp-progress-color-track)' },\n};\n\nexport interface SCircleProgressProps {\n /** 진행률 (0–100) */\n value?: number;\n /** 색상 테마 */\n type?: SCircleProgressType;\n /** 불확정(스피너) 모드 — value 무시 */\n indeterminate?: boolean;\n /** 하단 레이블 */\n label?: string;\n /** true면 퍼센트를 원 아래가 아닌 원 가운데에 표시 */\n innerValue?: boolean;\n className?: string;\n style?: CSSProperties;\n}\n\nconst clamp = (v: number) => (Number.isFinite(v) ? Math.max(0, Math.min(100, v)) : 0);\n\n/** SCircleProgress — sd-circle-progress 포팅. determinate=진행률 arc, indeterminate=스피너. */\nexport const SCircleProgress = forwardRef<HTMLDivElement, SCircleProgressProps>(\n function SCircleProgress(\n {\n value = 0,\n type = 'primary',\n indeterminate = false,\n label,\n innerValue = false,\n className,\n style,\n },\n ref,\n ) {\n const v = clamp(value);\n const colors = COLOR_MAP[type];\n const c = VIEWBOX / 2;\n const percentColor = v === 0 ? 'var(--sys-color-fg-tertiary, #888888)' : colors.arc;\n const filled = (v / 100) * CIRCUMFERENCE;\n const showPercent = !indeterminate;\n const percentNode = (\n <span\n className={cn(\n 'text-center text-[16px] font-bold leading-[26px]',\n innerValue && 'absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2',\n )}\n style={{ color: percentColor }}\n >\n {Math.round(v)}%\n </span>\n );\n\n return (\n <div\n ref={ref}\n className={cn(\n 'inline-flex flex-col items-center gap-[var(--cmp-progress-circular-gap)]',\n className,\n )}\n style={style}\n >\n <div className={cn(innerValue && 'relative')}>\n <svg\n viewBox={`0 0 ${VIEWBOX} ${VIEWBOX}`}\n xmlns=\"http://www.w3.org/2000/svg\"\n className={cn(\n 'h-[80px] w-[80px]',\n indeterminate && 'origin-center animate-circle-spin',\n )}\n >\n <circle\n cx={c}\n cy={c}\n r={RADIUS}\n fill=\"none\"\n strokeWidth={STROKE}\n style={{ stroke: colors.track }}\n />\n <circle\n cx={c}\n cy={c}\n r={RADIUS}\n fill=\"none\"\n strokeWidth={STROKE}\n strokeLinecap=\"round\"\n className={cn(\n 'origin-center',\n indeterminate\n ? 'animate-circle-arc'\n : '-rotate-90 transition-[stroke-dasharray] duration-[400ms] ease-linear',\n )}\n style={{\n stroke: colors.arc,\n ...(indeterminate\n ? {}\n : { strokeDasharray: `${filled} ${CIRCUMFERENCE}`, strokeDashoffset: 0 }),\n }}\n />\n </svg>\n {/* innerValue: 원 가운데에 퍼센트 오버레이 */}\n {showPercent && innerValue && percentNode}\n </div>\n {/* 기본: 퍼센트를 원(ring) 아래에 표시 */}\n {showPercent && !innerValue && percentNode}\n {label && (\n <span className=\"text-center text-[12px] font-normal leading-[20px] text-[color:var(--cmp-progress-color-label)]\">\n {label}\n </span>\n )}\n </div>\n );\n },\n);\n"]}
1
+ {"version":3,"sources":["../../../src/lib/cn.ts","../../../src/components/SCircleProgress/SCircleProgress.tsx"],"names":["SCircleProgress"],"mappings":"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","file":"SCircleProgress.js","sourcesContent":["import { clsx, type ClassValue } from 'clsx';\nimport { extendTailwindMerge } from 'tailwind-merge';\n\n/**\n * theme.css 의 --text-* 는 기본 Tailwind 폰트사이즈 스케일(xs/sm/base...)이 아닌\n * 숫자 스케일(10~32)이라, 확장 없이는 tailwind-merge 가 이를 텍스트 컬러 그룹으로\n * 오인해 text-12 같은 클래스를 text-(--color-var) 뒤에서 충돌 제거해버린다.\n */\nconst twMerge = extendTailwindMerge({\n extend: {\n classGroups: {\n 'font-size': [{ text: ['10', '11', '12', '13', '14', '16', '18', '20', '24', '28', '32'] }],\n },\n },\n});\n\n/**\n * className 병합 유틸.\n * clsx로 조건부 클래스를 합치고, tailwind-merge로 Tailwind 클래스 충돌을 해소한다.\n */\nexport function cn(...inputs: ClassValue[]): string {\n return twMerge(clsx(inputs));\n}\n","import { forwardRef, type CSSProperties } from 'react';\nimport { cn } from '../../lib/cn';\n\nexport type SCircleProgressType = 'primary' | 'inverse' | 'error' | 'complete';\n\nconst VIEWBOX = 80;\nconst RADIUS = 34;\nconst STROKE = 12;\nconst CIRCUMFERENCE = 2 * Math.PI * RADIUS;\n\nconst COLOR_MAP: Record<SCircleProgressType, { arc: string; track: string }> = {\n primary: { arc: 'var(--cmp-progress-active-color)', track: 'var(--cmp-progress-color-track)' },\n // inverse: 어두운 배경용 — arc 흰색, track 은 흰색 40%(회색 링)\n inverse: { arc: 'var(--color-white)', track: 'rgba(255,255,255,0.4)' },\n error: { arc: 'var(--color-red-75)', track: 'var(--cmp-progress-color-track)' },\n complete: { arc: '#01BB4B', track: 'var(--cmp-progress-color-track)' },\n};\n\nexport interface SCircleProgressProps {\n /** 진행률 (0–100) */\n value?: number;\n /** 색상 테마 */\n type?: SCircleProgressType;\n /** 불확정(스피너) 모드 — value 무시 */\n indeterminate?: boolean;\n /** 하단 레이블 */\n label?: string;\n /** true면 퍼센트를 원 아래가 아닌 원 가운데에 표시 */\n innerValue?: boolean;\n className?: string;\n style?: CSSProperties;\n}\n\nconst clamp = (v: number) => (Number.isFinite(v) ? Math.max(0, Math.min(100, v)) : 0);\n\n/** SCircleProgress — sd-circle-progress 포팅. determinate=진행률 arc, indeterminate=스피너. */\nexport const SCircleProgress = forwardRef<HTMLDivElement, SCircleProgressProps>(\n function SCircleProgress(\n {\n value = 0,\n type = 'primary',\n indeterminate = false,\n label,\n innerValue = false,\n className,\n style,\n },\n ref,\n ) {\n const v = clamp(value);\n const colors = COLOR_MAP[type];\n const c = VIEWBOX / 2;\n const percentColor = v === 0 ? 'var(--sys-color-fg-tertiary, #888888)' : colors.arc;\n const filled = (v / 100) * CIRCUMFERENCE;\n const showPercent = !indeterminate;\n const percentNode = (\n <span\n className={cn(\n 'text-center text-[16px] font-bold',\n innerValue\n ? // leading-[normal]: 26px leading 은 폰트 content(19px) 위아래로 홀수(7px)만큼 남아\n // 3px/4px 로 쪼개지고 글자가 링 중심보다 위로 뜬다. (leading-normal 은 1.5 라 동일 문제)\n 'absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 leading-[normal]'\n : 'leading-[26px]',\n )}\n style={{ color: percentColor }}\n >\n {Math.round(v)}%\n </span>\n );\n\n return (\n <div\n ref={ref}\n className={cn(\n 'inline-flex flex-col items-center gap-[var(--cmp-progress-circular-gap)]',\n className,\n )}\n style={style}\n >\n <div className={cn(innerValue && 'relative')}>\n <svg\n viewBox={`0 0 ${VIEWBOX} ${VIEWBOX}`}\n xmlns=\"http://www.w3.org/2000/svg\"\n className={cn(\n 'h-[80px] w-[80px]',\n indeterminate && 'origin-center animate-circle-spin',\n )}\n >\n <circle\n cx={c}\n cy={c}\n r={RADIUS}\n fill=\"none\"\n strokeWidth={STROKE}\n style={{ stroke: colors.track }}\n />\n <circle\n cx={c}\n cy={c}\n r={RADIUS}\n fill=\"none\"\n strokeWidth={STROKE}\n strokeLinecap=\"round\"\n className={cn(\n 'origin-center',\n indeterminate\n ? 'animate-circle-arc'\n : '-rotate-90 transition-[stroke-dasharray] duration-[400ms] ease-linear',\n )}\n style={{\n stroke: colors.arc,\n ...(indeterminate\n ? {}\n : { strokeDasharray: `${filled} ${CIRCUMFERENCE}`, strokeDashoffset: 0 }),\n }}\n />\n </svg>\n {/* innerValue: 원 가운데에 퍼센트 오버레이 */}\n {showPercent && innerValue && percentNode}\n </div>\n {/* 기본: 퍼센트를 원(ring) 아래에 표시 */}\n {showPercent && !innerValue && percentNode}\n {label && (\n <span className=\"text-center text-[12px] font-normal leading-[20px] text-[color:var(--cmp-progress-color-label)]\">\n {label}\n </span>\n )}\n </div>\n );\n },\n);\n"]}
@@ -40,7 +40,9 @@ function cn(...inputs) {
40
40
  return twMerge(clsx.clsx(inputs));
41
41
  }
42
42
  var PortalContainerContext = react.createContext(null);
43
+ var InsideModalContext = react.createContext(false);
43
44
  var PortalContainerProvider = PortalContainerContext.Provider;
45
+ var InsideModalProvider = InsideModalContext.Provider;
44
46
  function usePortalContainer() {
45
47
  return react.useContext(PortalContainerContext) ?? void 0;
46
48
  }
@@ -2996,6 +2998,8 @@ function SGhostButton({
2996
2998
  tooltipText,
2997
2999
  disabled = false,
2998
3000
  onClick,
3001
+ anchorClassName,
3002
+ anchorStyle,
2999
3003
  className,
3000
3004
  style
3001
3005
  }) {
@@ -3018,6 +3022,8 @@ function SGhostButton({
3018
3022
  };
3019
3023
  const s = SIZE[size];
3020
3024
  const contentColor = disabled ? intent === "inverse" ? "var(--cmp-ghostButton-inverse-disabled)" : "var(--cmp-ghostButton-icon-disabled)" : `var(--cmp-ghostButton-${intent}-content)`;
3025
+ const text = (tooltipText ?? "").trim();
3026
+ const hasTooltip = text !== "";
3021
3027
  const btn = /* @__PURE__ */ jsxRuntime.jsxs(
3022
3028
  "button",
3023
3029
  {
@@ -3058,13 +3064,13 @@ function SGhostButton({
3058
3064
  ]
3059
3065
  }
3060
3066
  );
3061
- const text = (tooltipText ?? "").trim();
3062
- if (text === "") return btn;
3067
+ if (!hasTooltip) return btn;
3063
3068
  return /* @__PURE__ */ jsxRuntime.jsxs(RPopover__namespace.Root, { open, onOpenChange: setOpen, children: [
3064
3069
  /* @__PURE__ */ jsxRuntime.jsx(RPopover__namespace.Anchor, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
3065
3070
  "span",
3066
3071
  {
3067
- className: "inline-flex",
3072
+ className: cn("inline-flex", anchorClassName),
3073
+ style: anchorStyle,
3068
3074
  onMouseEnter: openNow,
3069
3075
  onMouseLeave: startHide,
3070
3076
  onFocus: openNow,
@@ -3148,7 +3154,7 @@ function SModalContainer({
3148
3154
  className: "absolute right-[16px] top-[16px] z-10"
3149
3155
  }
3150
3156
  ),
3151
- /* @__PURE__ */ jsxRuntime.jsx(PortalContainerProvider, { value: portalContainer, children })
3157
+ /* @__PURE__ */ jsxRuntime.jsx(InsideModalProvider, { value: true, children: /* @__PURE__ */ jsxRuntime.jsx(PortalContainerProvider, { value: portalContainer, children }) })
3152
3158
  ]
3153
3159
  }
3154
3160
  )
@@ -3360,7 +3366,8 @@ function SConfirmModal({
3360
3366
  tagSize = "sm",
3361
3367
  tagColor = "grey",
3362
3368
  slotLabel,
3363
- children,
3369
+ tagSlot,
3370
+ optionSlot,
3364
3371
  mainButtonLabel = "\uD655\uC778",
3365
3372
  mainButtonName,
3366
3373
  subButtonLabel,
@@ -3370,6 +3377,9 @@ function SConfirmModal({
3370
3377
  }) {
3371
3378
  const iconName = TYPE_ICON[type];
3372
3379
  const mainStyle = MAIN_BUTTON_STYLE[mainButtonName ?? DEFAULT_MAIN_BUTTON[type]];
3380
+ const tagNode = tagSlot ?? (tagLabel ? /* @__PURE__ */ jsxRuntime.jsx(STag, { shape: tagShape, size: tagSize, color: tagColor, label: tagLabel }) : null);
3381
+ const optionNode = optionSlot ?? (slotLabel ? /* @__PURE__ */ jsxRuntime.jsx("span", { children: slotLabel }) : null);
3382
+ const hasBody = topMessage.length > 0 || bottomMessage.length > 0 || tagNode != null || optionNode != null;
3373
3383
  return /* @__PURE__ */ jsxRuntime.jsx(
3374
3384
  SModalContainer,
3375
3385
  {
@@ -3395,15 +3405,12 @@ function SConfirmModal({
3395
3405
  }
3396
3406
  )
3397
3407
  ] }),
3398
- (topMessage.length > 0 || bottomMessage.length > 0 || tagLabel || slotLabel || children) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center gap-[20px] text-center text-[12px] font-normal leading-[20px] text-[color:var(--cmp-modal-confirm-message-color)]", children: [
3408
+ hasBody && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center gap-[20px] text-center text-[12px] font-normal leading-[20px] text-[color:var(--cmp-modal-confirm-message-color)] w-full", children: [
3399
3409
  topMessage.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-[2px]", children: topMessage.map((m, i) => /* @__PURE__ */ jsxRuntime.jsx("p", { className: "m-0", children: m }, i)) }),
3400
- (tagLabel || slotLabel || children) && // content-box: 흰 박스 + 1px 테두리 + 패딩 + 14/700 (원본 sd-confirm-modal__content-box)
3401
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-center gap-[8px] rounded-[8px] border border-solid border-[color:var(--color-grey-30)] bg-white px-[16px] py-[12px] text-[14px] font-bold leading-[22px]", children: [
3402
- tagLabel && /* @__PURE__ */ jsxRuntime.jsx(STag, { shape: tagShape, size: tagSize, color: tagColor, label: tagLabel }),
3403
- slotLabel && /* @__PURE__ */ jsxRuntime.jsx("span", { children: slotLabel }),
3404
- children
3405
- ] }),
3406
- bottomMessage.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-[2px]", children: bottomMessage.map((m, i) => /* @__PURE__ */ jsxRuntime.jsx("p", { className: "m-0", children: m }, i)) })
3410
+ tagNode != null && // tag 위치 content-box: 흰 박스 + 1px 테두리 + 패딩 + 14/700 (원본 sd-confirm-modal__content-box)
3411
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-center gap-[8px] rounded-[8px] border border-solid border-[color:var(--color-grey-30)] bg-white px-[16px] py-[12px] text-[14px] font-bold leading-[22px] w-full", children: tagNode }),
3412
+ bottomMessage.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-[2px]", children: bottomMessage.map((m, i) => /* @__PURE__ */ jsxRuntime.jsx("p", { className: "m-0", children: m }, i)) }),
3413
+ optionNode != null && optionNode
3407
3414
  ] })
3408
3415
  ] }),
3409
3416
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-[8px]", children: [