sellmate-design-system-react 0.1.7 → 0.1.9
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/SActionModal/SActionModal.cjs +11 -3
- package/dist/components/SActionModal/SActionModal.cjs.map +1 -1
- package/dist/components/SActionModal/SActionModal.js +11 -3
- package/dist/components/SActionModal/SActionModal.js.map +1 -1
- package/dist/components/SBarcodeInput/SBarcodeInput.cjs +226 -209
- package/dist/components/SBarcodeInput/SBarcodeInput.cjs.map +1 -1
- package/dist/components/SBarcodeInput/SBarcodeInput.js +226 -209
- package/dist/components/SBarcodeInput/SBarcodeInput.js.map +1 -1
- package/dist/components/SCalendar/SCalendar.cjs +9 -1
- package/dist/components/SCalendar/SCalendar.cjs.map +1 -1
- package/dist/components/SCalendar/SCalendar.js +9 -1
- package/dist/components/SCalendar/SCalendar.js.map +1 -1
- package/dist/components/SChip/SChip.cjs +9 -1
- package/dist/components/SChip/SChip.cjs.map +1 -1
- package/dist/components/SChip/SChip.d.ts +1 -1
- package/dist/components/SChip/SChip.js +9 -1
- package/dist/components/SChip/SChip.js.map +1 -1
- package/dist/components/SChipInput/SChipInput.cjs +260 -235
- package/dist/components/SChipInput/SChipInput.cjs.map +1 -1
- package/dist/components/SChipInput/SChipInput.js +259 -235
- package/dist/components/SChipInput/SChipInput.js.map +1 -1
- package/dist/components/SCircleProgress/SCircleProgress.cjs +56 -58
- package/dist/components/SCircleProgress/SCircleProgress.cjs.map +1 -1
- package/dist/components/SCircleProgress/SCircleProgress.js +56 -58
- package/dist/components/SCircleProgress/SCircleProgress.js.map +1 -1
- package/dist/components/SConfirmModal/SConfirmModal.cjs +9 -1
- package/dist/components/SConfirmModal/SConfirmModal.cjs.map +1 -1
- package/dist/components/SConfirmModal/SConfirmModal.js +9 -1
- package/dist/components/SConfirmModal/SConfirmModal.js.map +1 -1
- package/dist/components/SDatePicker/SDatePicker.cjs +247 -221
- package/dist/components/SDatePicker/SDatePicker.cjs.map +1 -1
- package/dist/components/SDatePicker/SDatePicker.js +247 -221
- package/dist/components/SDatePicker/SDatePicker.js.map +1 -1
- package/dist/components/SDateRangePicker/SDateRangePicker.cjs +308 -256
- package/dist/components/SDateRangePicker/SDateRangePicker.cjs.map +1 -1
- package/dist/components/SDateRangePicker/SDateRangePicker.js +308 -256
- package/dist/components/SDateRangePicker/SDateRangePicker.js.map +1 -1
- package/dist/components/SDropdownButton/SDropdownButton.cjs +51 -4
- package/dist/components/SDropdownButton/SDropdownButton.cjs.map +1 -1
- package/dist/components/SDropdownButton/SDropdownButton.js +52 -5
- package/dist/components/SDropdownButton/SDropdownButton.js.map +1 -1
- package/dist/components/SField/SField.cjs +226 -21
- package/dist/components/SField/SField.cjs.map +1 -1
- package/dist/components/SField/SField.d.ts +11 -0
- package/dist/components/SField/SField.js +226 -21
- package/dist/components/SField/SField.js.map +1 -1
- package/dist/components/SFilePicker/SFilePicker.cjs +306 -278
- package/dist/components/SFilePicker/SFilePicker.cjs.map +1 -1
- package/dist/components/SFilePicker/SFilePicker.d.ts +4 -2
- package/dist/components/SFilePicker/SFilePicker.js +306 -278
- package/dist/components/SFilePicker/SFilePicker.js.map +1 -1
- package/dist/components/SGhostButton/SGhostButton.cjs +8 -0
- package/dist/components/SGhostButton/SGhostButton.cjs.map +1 -1
- package/dist/components/SGhostButton/SGhostButton.js +8 -0
- package/dist/components/SGhostButton/SGhostButton.js.map +1 -1
- package/dist/components/SGuide/SGuide.cjs +12 -1
- package/dist/components/SGuide/SGuide.cjs.map +1 -1
- package/dist/components/SGuide/SGuide.js +12 -1
- package/dist/components/SGuide/SGuide.js.map +1 -1
- package/dist/components/SInput/SInput.cjs +226 -209
- package/dist/components/SInput/SInput.cjs.map +1 -1
- package/dist/components/SInput/SInput.js +226 -209
- package/dist/components/SInput/SInput.js.map +1 -1
- package/dist/components/SKeyValueTable/SKeyValueTable.cjs +640 -453
- package/dist/components/SKeyValueTable/SKeyValueTable.cjs.map +1 -1
- package/dist/components/SKeyValueTable/SKeyValueTable.d.ts +3 -1
- package/dist/components/SKeyValueTable/SKeyValueTable.js +640 -453
- package/dist/components/SKeyValueTable/SKeyValueTable.js.map +1 -1
- package/dist/components/SLoadingContainer/SLoadingContainer.cjs +64 -58
- package/dist/components/SLoadingContainer/SLoadingContainer.cjs.map +1 -1
- package/dist/components/SLoadingContainer/SLoadingContainer.js +64 -58
- package/dist/components/SLoadingContainer/SLoadingContainer.js.map +1 -1
- package/dist/components/SLoadingContainer/loading.cjs +64 -58
- package/dist/components/SLoadingContainer/loading.cjs.map +1 -1
- package/dist/components/SLoadingContainer/loading.js +64 -58
- package/dist/components/SLoadingContainer/loading.js.map +1 -1
- package/dist/components/SLoadingModal/SLoadingModal.cjs +68 -61
- package/dist/components/SLoadingModal/SLoadingModal.cjs.map +1 -1
- package/dist/components/SLoadingModal/SLoadingModal.js +68 -61
- package/dist/components/SLoadingModal/SLoadingModal.js.map +1 -1
- package/dist/components/SModalContainer/SModalContainer.cjs +9 -1
- package/dist/components/SModalContainer/SModalContainer.cjs.map +1 -1
- package/dist/components/SModalContainer/SModalContainer.js +9 -1
- package/dist/components/SModalContainer/SModalContainer.js.map +1 -1
- package/dist/components/SNumberInput/SNumberInput.cjs +334 -50
- package/dist/components/SNumberInput/SNumberInput.cjs.map +1 -1
- package/dist/components/SNumberInput/SNumberInput.d.ts +2 -0
- package/dist/components/SNumberInput/SNumberInput.js +334 -50
- package/dist/components/SNumberInput/SNumberInput.js.map +1 -1
- package/dist/components/SPagination/SPagination.cjs +1 -1
- package/dist/components/SPagination/SPagination.cjs.map +1 -1
- package/dist/components/SPagination/SPagination.js +1 -1
- package/dist/components/SPagination/SPagination.js.map +1 -1
- package/dist/components/SPopover/SPopover.cjs +20 -3
- package/dist/components/SPopover/SPopover.cjs.map +1 -1
- package/dist/components/SPopover/SPopover.js +20 -4
- package/dist/components/SPopover/SPopover.js.map +1 -1
- package/dist/components/SPopup/SPopup.cjs +2 -2
- package/dist/components/SPopup/SPopup.cjs.map +1 -1
- package/dist/components/SPopup/SPopup.js +2 -2
- package/dist/components/SPopup/SPopup.js.map +1 -1
- package/dist/components/SPortal/SPortal.cjs +8 -0
- package/dist/components/SPortal/SPortal.cjs.map +1 -1
- package/dist/components/SPortal/SPortal.js +8 -0
- package/dist/components/SPortal/SPortal.js.map +1 -1
- package/dist/components/SSelect/SSelect.cjs +76 -32
- package/dist/components/SSelect/SSelect.cjs.map +1 -1
- package/dist/components/SSelect/SSelect.js +76 -32
- package/dist/components/SSelect/SSelect.js.map +1 -1
- package/dist/components/STable/STable.cjs +133 -91
- package/dist/components/STable/STable.cjs.map +1 -1
- package/dist/components/STable/STable.js +133 -91
- package/dist/components/STable/STable.js.map +1 -1
- package/dist/components/STextLink/STextLink.cjs +137 -3
- package/dist/components/STextLink/STextLink.cjs.map +1 -1
- package/dist/components/STextLink/STextLink.d.ts +1 -1
- package/dist/components/STextLink/STextLink.js +118 -4
- package/dist/components/STextLink/STextLink.js.map +1 -1
- package/dist/components/STextarea/STextarea.cjs +226 -21
- package/dist/components/STextarea/STextarea.cjs.map +1 -1
- package/dist/components/STextarea/STextarea.js +226 -21
- package/dist/components/STextarea/STextarea.js.map +1 -1
- package/dist/components/SToast/SToast.cjs +8 -0
- package/dist/components/SToast/SToast.cjs.map +1 -1
- package/dist/components/SToast/SToast.js +8 -0
- package/dist/components/SToast/SToast.js.map +1 -1
- package/dist/components/SToast/SToastContainer.cjs +11 -3
- package/dist/components/SToast/SToastContainer.cjs.map +1 -1
- package/dist/components/SToast/SToastContainer.js +11 -3
- package/dist/components/SToast/SToastContainer.js.map +1 -1
- package/dist/components/STooltip/STooltip.cjs +217 -14
- package/dist/components/STooltip/STooltip.cjs.map +1 -1
- package/dist/components/STooltip/STooltip.js +217 -14
- package/dist/components/STooltip/STooltip.js.map +1 -1
- package/dist/index.cjs +532 -300
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +531 -300
- package/dist/index.js.map +1 -1
- package/dist/lib/floating-anim.cjs +8 -0
- package/dist/lib/floating-anim.cjs.map +1 -1
- package/dist/lib/floating-anim.d.ts +5 -1
- package/dist/lib/floating-anim.js +8 -0
- package/dist/lib/floating-anim.js.map +1 -1
- package/dist/styles.css +175 -66
- package/dist/theme.css +49 -22
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/lib/cn.ts","../../../src/components/SCircleProgress/SCircleProgress.tsx","../../../src/components/SLoadingContainer/SLoadingContainer.tsx","../../../src/components/SLoadingContainer/loading.tsx"],"names":["extendTailwindMerge","clsx","forwardRef","SCircleProgress","jsxs","jsx","SLoadingContainer","mounted","useState","useEffect","useRef","useCallback","createPortal","useSyncExternalStore","createRoot"],"mappings":"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","file":"loading.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-spinner-color-arc)', track: 'var(--cmp-spinner-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-spinner-color-track)' },\n complete: { arc: '#01BB4B', track: 'var(--cmp-spinner-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 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 { value = 0, type = 'primary', indeterminate = false, label, className, style },\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\n return (\n <div\n ref={ref}\n className={cn('inline-flex flex-col items-center gap-[8px]', className)}\n style={style}\n >\n {/* percent 는 원(ring) 중앙에 오버레이 */}\n <div className=\"relative h-[80px] w-[80px]\">\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 {!indeterminate && (\n <span\n className=\"absolute inset-0 flex items-center justify-center text-[16px] font-bold leading-[26px]\"\n style={{ color: percentColor }}\n >\n {Math.round(v)}%\n </span>\n )}\n </div>\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","'use client';\n\nimport { forwardRef, useCallback, useEffect, useRef, useState, type CSSProperties } from 'react';\nimport { createPortal } from 'react-dom';\nimport { cn } from '../../lib/cn';\nimport { SCircleProgress } from '../SCircleProgress';\n\nexport interface SLoadingContainerProps {\n /** 오버레이 표시 여부 (Stencil의 show()/hide() 명령형 API → 제어 prop으로 대체) */\n open?: boolean;\n /** 스피너 하단 메시지 */\n message?: string;\n /** z-index. 기본값(1200)은 토스트(1100)·모달(1000/1001) 위 — 전체 화면을 막는 최상단 블로킹 오버레이 */\n zIndex?: number;\n className?: string;\n style?: CSSProperties;\n}\n\n/**\n * SLoadingContainer — sd-loading-container 포팅.\n * 전체 화면 딤 오버레이 + inverse 스피너. React에서는 `open` 제어 prop 사용.\n * body 로 portal 해 조상의 스태킹 컨텍스트에 갇히지 않고 항상 최상단에 뜨게 한다.\n */\nexport const SLoadingContainer = forwardRef<HTMLDivElement, SLoadingContainerProps>(\n function SLoadingContainer({ open = false, message, zIndex = 1200, className, style }, ref) {\n // portal 은 클라이언트에서만 (SSR 시 document 없음) — 마운트 후 body 로 렌더\n const [mounted, setMounted] = useState(false);\n useEffect(() => setMounted(true), []);\n\n // body 로 portal 된 블로킹 오버레이라, 클릭이 document 까지 전파되면 Radix Dialog 의\n // \"바깥 클릭\" 감지에 걸려 열려있는 모달이 닫힌다. 오버레이 요소에 네이티브 pointerdown\n // 리스너를 직접 붙여(요소 자신에서 가장 먼저 발화) 전파를 끊어 document 리스너를 차단한다.\n const innerRef = useRef<HTMLDivElement | null>(null);\n const setRef = useCallback(\n (node: HTMLDivElement | null) => {\n innerRef.current = node;\n if (typeof ref === 'function') ref(node);\n else if (ref) ref.current = node;\n },\n [ref],\n );\n useEffect(() => {\n const el = innerRef.current;\n if (!el) return;\n const stop = (e: Event) => e.stopPropagation();\n el.addEventListener('pointerdown', stop);\n el.addEventListener('mousedown', stop);\n return () => {\n el.removeEventListener('pointerdown', stop);\n el.removeEventListener('mousedown', stop);\n };\n }, [mounted]);\n\n const overlay = (\n <div\n ref={setRef}\n aria-hidden={!open}\n className={cn(\n 'fixed inset-0 flex items-center justify-center transition-opacity duration-200',\n open\n ? 'pointer-events-auto visible opacity-100'\n : 'pointer-events-none invisible opacity-0',\n className,\n )}\n style={{ zIndex, ...style }}\n >\n <div className=\"absolute inset-0 bg-black/40\" />\n <div className=\"relative flex flex-col items-center gap-[16px]\">\n <SCircleProgress indeterminate type=\"inverse\" />\n {message && (\n <p className=\"m-0 max-w-[400px] break-keep text-center text-[14px] font-medium leading-[22px] text-[color:var(--color-white)]\">\n {message}\n </p>\n )}\n </div>\n </div>\n );\n\n if (!mounted) return null;\n return createPortal(overlay, document.body);\n },\n);\n","'use client';\n\nimport { useSyncExternalStore } from 'react';\nimport { createRoot } from 'react-dom/client';\nimport { SLoadingContainer } from './SLoadingContainer';\n\n/**\n * 전역 로딩 오버레이 싱글톤 — sd-loading-container 의 `sdLoading.show()/hide()` 포팅.\n * 앱 어디서든 `loading.show({ message })` / `loading.hide()` 로 호출한다.\n * 최초 show 시 document.body 에 오버레이 루트를 자동 마운트한다.\n */\ninterface LoadingState {\n open: boolean;\n message?: string;\n}\n\nlet state: LoadingState = { open: false, message: undefined };\nconst listeners = new Set<() => void>();\n\nconst emit = () => listeners.forEach(l => l());\nconst setState = (patch: Partial<LoadingState>) => {\n state = { ...state, ...patch };\n emit();\n};\nconst subscribe = (cb: () => void) => {\n listeners.add(cb);\n return () => listeners.delete(cb);\n};\nconst getSnapshot = () => state;\n\n/** 오버레이 뷰포트 — 스토어를 구독해 SLoadingContainer 를 렌더한다. 직접 배치도 가능. */\nexport function SLoadingViewport() {\n const s = useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n return <SLoadingContainer open={s.open} message={s.message} />;\n}\n\nlet mounted = false;\nfunction ensureMounted() {\n if (mounted || typeof document === 'undefined') return;\n mounted = true;\n const host = document.createElement('div');\n host.setAttribute('data-sd-loading-root', '');\n document.body.appendChild(host);\n createRoot(host).render(<SLoadingViewport />);\n}\n\nexport const loading = {\n /** 로딩 오버레이 표시 (메시지 갱신도 동일 호출) */\n show(options: { message?: string } = {}) {\n ensureMounted();\n setState({ open: true, message: options.message });\n },\n /** 로딩 오버레이 숨김 */\n hide() {\n setState({ open: false });\n },\n};\n"]}
|
|
1
|
+
{"version":3,"sources":["../../../src/lib/cn.ts","../../../src/components/SCircleProgress/SCircleProgress.tsx","../../../src/components/SLoadingContainer/SLoadingContainer.tsx","../../../src/components/SLoadingContainer/loading.tsx"],"names":["extendTailwindMerge","clsx","forwardRef","SCircleProgress","jsxs","jsx","SLoadingContainer","mounted","useState","useEffect","useRef","useCallback","createPortal","useSyncExternalStore","createRoot"],"mappings":"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","file":"loading.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 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 { value = 0, type = 'primary', indeterminate = false, label, className, style },\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\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 <svg\n viewBox={`0 0 ${VIEWBOX} ${VIEWBOX}`}\n xmlns=\"http://www.w3.org/2000/svg\"\n className={cn('h-[80px] w-[80px]', indeterminate && 'origin-center animate-circle-spin')}\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 {/* percent 는 원(ring) 아래에 표시 */}\n {!indeterminate && (\n <span\n className=\"text-center text-[16px] font-bold leading-[26px]\"\n style={{ color: percentColor }}\n >\n {Math.round(v)}%\n </span>\n )}\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","'use client';\n\nimport { forwardRef, useCallback, useEffect, useRef, useState, type CSSProperties } from 'react';\nimport { createPortal } from 'react-dom';\nimport { cn } from '../../lib/cn';\nimport { SCircleProgress } from '../SCircleProgress';\n\nexport interface SLoadingContainerProps {\n /** 오버레이 표시 여부 (Stencil의 show()/hide() 명령형 API → 제어 prop으로 대체) */\n open?: boolean;\n /** 스피너 하단 메시지 */\n message?: string;\n /** z-index. 기본값(1200)은 토스트(1100)·모달(1000/1001) 위 — 전체 화면을 막는 최상단 블로킹 오버레이 */\n zIndex?: number;\n className?: string;\n style?: CSSProperties;\n}\n\n/**\n * SLoadingContainer — sd-loading-container 포팅.\n * 전체 화면 딤 오버레이 + inverse 스피너. React에서는 `open` 제어 prop 사용.\n * body 로 portal 해 조상의 스태킹 컨텍스트에 갇히지 않고 항상 최상단에 뜨게 한다.\n */\nexport const SLoadingContainer = forwardRef<HTMLDivElement, SLoadingContainerProps>(\n function SLoadingContainer({ open = false, message, zIndex = 1200, className, style }, ref) {\n // portal 은 클라이언트에서만 (SSR 시 document 없음) — 마운트 후 body 로 렌더\n const [mounted, setMounted] = useState(false);\n useEffect(() => setMounted(true), []);\n\n // 오버레이 표시 중 배경 스크롤 차단\n useEffect(() => {\n if (!open) return;\n const prev = document.body.style.overflow;\n document.body.style.overflow = 'hidden';\n return () => {\n document.body.style.overflow = prev;\n };\n }, [open]);\n\n // body 로 portal 된 블로킹 오버레이라, 클릭이 document 까지 전파되면 Radix Dialog 의\n // \"바깥 클릭\" 감지에 걸려 열려있는 모달이 닫힌다. 오버레이 요소에 네이티브 pointerdown\n // 리스너를 직접 붙여(요소 자신에서 가장 먼저 발화) 전파를 끊어 document 리스너를 차단한다.\n const innerRef = useRef<HTMLDivElement | null>(null);\n const setRef = useCallback(\n (node: HTMLDivElement | null) => {\n innerRef.current = node;\n if (typeof ref === 'function') ref(node);\n else if (ref) ref.current = node;\n },\n [ref],\n );\n useEffect(() => {\n const el = innerRef.current;\n if (!el) return;\n const stop = (e: Event) => e.stopPropagation();\n el.addEventListener('pointerdown', stop);\n el.addEventListener('mousedown', stop);\n return () => {\n el.removeEventListener('pointerdown', stop);\n el.removeEventListener('mousedown', stop);\n };\n }, [mounted]);\n\n const overlay = (\n <div\n ref={setRef}\n aria-hidden={!open}\n className={cn(\n 'fixed inset-0 flex items-center justify-center transition-opacity duration-200',\n open\n ? 'pointer-events-auto visible opacity-100'\n : 'pointer-events-none invisible opacity-0',\n className,\n )}\n style={{ zIndex, ...style }}\n >\n <div className=\"absolute inset-0 bg-black/40\" />\n <div className=\"relative flex flex-col items-center gap-[16px]\">\n <SCircleProgress indeterminate type=\"inverse\" />\n {message && (\n <p className=\"m-0 max-w-[400px] break-keep text-center text-[14px] font-medium leading-[22px] text-[color:var(--color-white)]\">\n {message}\n </p>\n )}\n </div>\n </div>\n );\n\n if (!mounted) return null;\n return createPortal(overlay, document.body);\n },\n);\n","'use client';\n\nimport { useSyncExternalStore } from 'react';\nimport { createRoot } from 'react-dom/client';\nimport { SLoadingContainer } from './SLoadingContainer';\n\n/**\n * 전역 로딩 오버레이 싱글톤 — sd-loading-container 의 `sdLoading.show()/hide()` 포팅.\n * 앱 어디서든 `loading.show({ message })` / `loading.hide()` 로 호출한다.\n * 최초 show 시 document.body 에 오버레이 루트를 자동 마운트한다.\n */\ninterface LoadingState {\n open: boolean;\n message?: string;\n}\n\nlet state: LoadingState = { open: false, message: undefined };\nconst listeners = new Set<() => void>();\n\nconst emit = () => listeners.forEach(l => l());\nconst setState = (patch: Partial<LoadingState>) => {\n state = { ...state, ...patch };\n emit();\n};\nconst subscribe = (cb: () => void) => {\n listeners.add(cb);\n return () => listeners.delete(cb);\n};\nconst getSnapshot = () => state;\n\n/** 오버레이 뷰포트 — 스토어를 구독해 SLoadingContainer 를 렌더한다. 직접 배치도 가능. */\nexport function SLoadingViewport() {\n const s = useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n return <SLoadingContainer open={s.open} message={s.message} />;\n}\n\nlet mounted = false;\nfunction ensureMounted() {\n if (mounted || typeof document === 'undefined') return;\n mounted = true;\n const host = document.createElement('div');\n host.setAttribute('data-sd-loading-root', '');\n document.body.appendChild(host);\n createRoot(host).render(<SLoadingViewport />);\n}\n\nexport const loading = {\n /** 로딩 오버레이 표시 (메시지 갱신도 동일 호출) */\n show(options: { message?: string } = {}) {\n ensureMounted();\n setState({ open: true, message: options.message });\n },\n /** 로딩 오버레이 숨김 */\n hide() {\n setState({ open: false });\n },\n};\n"]}
|
|
@@ -21,11 +21,11 @@ var RADIUS = 34;
|
|
|
21
21
|
var STROKE = 12;
|
|
22
22
|
var CIRCUMFERENCE = 2 * Math.PI * RADIUS;
|
|
23
23
|
var COLOR_MAP = {
|
|
24
|
-
primary: { arc: "var(--cmp-
|
|
24
|
+
primary: { arc: "var(--cmp-progress-active-color)", track: "var(--cmp-progress-color-track)" },
|
|
25
25
|
// inverse: 어두운 배경용 — arc 흰색, track 은 흰색 40%(회색 링)
|
|
26
26
|
inverse: { arc: "var(--color-white)", track: "rgba(255,255,255,0.4)" },
|
|
27
|
-
error: { arc: "var(--color-red-75)", track: "var(--cmp-
|
|
28
|
-
complete: { arc: "#01BB4B", track: "var(--cmp-
|
|
27
|
+
error: { arc: "var(--color-red-75)", track: "var(--cmp-progress-color-track)" },
|
|
28
|
+
complete: { arc: "#01BB4B", track: "var(--cmp-progress-color-track)" }
|
|
29
29
|
};
|
|
30
30
|
var clamp = (v) => Number.isFinite(v) ? Math.max(0, Math.min(100, v)) : 0;
|
|
31
31
|
var SCircleProgress = forwardRef(
|
|
@@ -39,65 +39,63 @@ var SCircleProgress = forwardRef(
|
|
|
39
39
|
"div",
|
|
40
40
|
{
|
|
41
41
|
ref,
|
|
42
|
-
className: cn(
|
|
42
|
+
className: cn(
|
|
43
|
+
"inline-flex flex-col items-center gap-[var(--cmp-progress-circular-gap)]",
|
|
44
|
+
className
|
|
45
|
+
),
|
|
43
46
|
style,
|
|
44
47
|
children: [
|
|
45
|
-
/* @__PURE__ */ jsxs(
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
{
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
48
|
+
/* @__PURE__ */ jsxs(
|
|
49
|
+
"svg",
|
|
50
|
+
{
|
|
51
|
+
viewBox: `0 0 ${VIEWBOX} ${VIEWBOX}`,
|
|
52
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
53
|
+
className: cn("h-[80px] w-[80px]", indeterminate && "origin-center animate-circle-spin"),
|
|
54
|
+
children: [
|
|
55
|
+
/* @__PURE__ */ jsx(
|
|
56
|
+
"circle",
|
|
57
|
+
{
|
|
58
|
+
cx: c,
|
|
59
|
+
cy: c,
|
|
60
|
+
r: RADIUS,
|
|
61
|
+
fill: "none",
|
|
62
|
+
strokeWidth: STROKE,
|
|
63
|
+
style: { stroke: colors.track }
|
|
64
|
+
}
|
|
54
65
|
),
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
cy: c,
|
|
72
|
-
r: RADIUS,
|
|
73
|
-
fill: "none",
|
|
74
|
-
strokeWidth: STROKE,
|
|
75
|
-
strokeLinecap: "round",
|
|
76
|
-
className: cn(
|
|
77
|
-
"origin-center",
|
|
78
|
-
indeterminate ? "animate-circle-arc" : "-rotate-90 transition-[stroke-dasharray] duration-[400ms] ease-linear"
|
|
79
|
-
),
|
|
80
|
-
style: {
|
|
81
|
-
stroke: colors.arc,
|
|
82
|
-
...indeterminate ? {} : { strokeDasharray: `${filled} ${CIRCUMFERENCE}`, strokeDashoffset: 0 }
|
|
83
|
-
}
|
|
66
|
+
/* @__PURE__ */ jsx(
|
|
67
|
+
"circle",
|
|
68
|
+
{
|
|
69
|
+
cx: c,
|
|
70
|
+
cy: c,
|
|
71
|
+
r: RADIUS,
|
|
72
|
+
fill: "none",
|
|
73
|
+
strokeWidth: STROKE,
|
|
74
|
+
strokeLinecap: "round",
|
|
75
|
+
className: cn(
|
|
76
|
+
"origin-center",
|
|
77
|
+
indeterminate ? "animate-circle-arc" : "-rotate-90 transition-[stroke-dasharray] duration-[400ms] ease-linear"
|
|
78
|
+
),
|
|
79
|
+
style: {
|
|
80
|
+
stroke: colors.arc,
|
|
81
|
+
...indeterminate ? {} : { strokeDasharray: `${filled} ${CIRCUMFERENCE}`, strokeDashoffset: 0 }
|
|
84
82
|
}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
83
|
+
}
|
|
84
|
+
)
|
|
85
|
+
]
|
|
86
|
+
}
|
|
87
|
+
),
|
|
88
|
+
!indeterminate && /* @__PURE__ */ jsxs(
|
|
89
|
+
"span",
|
|
90
|
+
{
|
|
91
|
+
className: "text-center text-[16px] font-bold leading-[26px]",
|
|
92
|
+
style: { color: percentColor },
|
|
93
|
+
children: [
|
|
94
|
+
Math.round(v),
|
|
95
|
+
"%"
|
|
96
|
+
]
|
|
97
|
+
}
|
|
98
|
+
),
|
|
101
99
|
label && /* @__PURE__ */ jsx("span", { className: "text-center text-[12px] font-normal leading-[20px] text-[color:var(--cmp-progress-color-label)]", children: label })
|
|
102
100
|
]
|
|
103
101
|
}
|
|
@@ -108,6 +106,14 @@ var SLoadingContainer = forwardRef(
|
|
|
108
106
|
function SLoadingContainer2({ open = false, message, zIndex = 1200, className, style }, ref) {
|
|
109
107
|
const [mounted2, setMounted] = useState(false);
|
|
110
108
|
useEffect(() => setMounted(true), []);
|
|
109
|
+
useEffect(() => {
|
|
110
|
+
if (!open) return;
|
|
111
|
+
const prev = document.body.style.overflow;
|
|
112
|
+
document.body.style.overflow = "hidden";
|
|
113
|
+
return () => {
|
|
114
|
+
document.body.style.overflow = prev;
|
|
115
|
+
};
|
|
116
|
+
}, [open]);
|
|
111
117
|
const innerRef = useRef(null);
|
|
112
118
|
const setRef = useCallback(
|
|
113
119
|
(node) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/lib/cn.ts","../../../src/components/SCircleProgress/SCircleProgress.tsx","../../../src/components/SLoadingContainer/SLoadingContainer.tsx","../../../src/components/SLoadingContainer/loading.tsx"],"names":["SCircleProgress","forwardRef","SLoadingContainer","mounted","jsxs","jsx"],"mappings":"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","file":"loading.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-spinner-color-arc)', track: 'var(--cmp-spinner-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-spinner-color-track)' },\n complete: { arc: '#01BB4B', track: 'var(--cmp-spinner-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 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 { value = 0, type = 'primary', indeterminate = false, label, className, style },\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\n return (\n <div\n ref={ref}\n className={cn('inline-flex flex-col items-center gap-[8px]', className)}\n style={style}\n >\n {/* percent 는 원(ring) 중앙에 오버레이 */}\n <div className=\"relative h-[80px] w-[80px]\">\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 {!indeterminate && (\n <span\n className=\"absolute inset-0 flex items-center justify-center text-[16px] font-bold leading-[26px]\"\n style={{ color: percentColor }}\n >\n {Math.round(v)}%\n </span>\n )}\n </div>\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","'use client';\n\nimport { forwardRef, useCallback, useEffect, useRef, useState, type CSSProperties } from 'react';\nimport { createPortal } from 'react-dom';\nimport { cn } from '../../lib/cn';\nimport { SCircleProgress } from '../SCircleProgress';\n\nexport interface SLoadingContainerProps {\n /** 오버레이 표시 여부 (Stencil의 show()/hide() 명령형 API → 제어 prop으로 대체) */\n open?: boolean;\n /** 스피너 하단 메시지 */\n message?: string;\n /** z-index. 기본값(1200)은 토스트(1100)·모달(1000/1001) 위 — 전체 화면을 막는 최상단 블로킹 오버레이 */\n zIndex?: number;\n className?: string;\n style?: CSSProperties;\n}\n\n/**\n * SLoadingContainer — sd-loading-container 포팅.\n * 전체 화면 딤 오버레이 + inverse 스피너. React에서는 `open` 제어 prop 사용.\n * body 로 portal 해 조상의 스태킹 컨텍스트에 갇히지 않고 항상 최상단에 뜨게 한다.\n */\nexport const SLoadingContainer = forwardRef<HTMLDivElement, SLoadingContainerProps>(\n function SLoadingContainer({ open = false, message, zIndex = 1200, className, style }, ref) {\n // portal 은 클라이언트에서만 (SSR 시 document 없음) — 마운트 후 body 로 렌더\n const [mounted, setMounted] = useState(false);\n useEffect(() => setMounted(true), []);\n\n // body 로 portal 된 블로킹 오버레이라, 클릭이 document 까지 전파되면 Radix Dialog 의\n // \"바깥 클릭\" 감지에 걸려 열려있는 모달이 닫힌다. 오버레이 요소에 네이티브 pointerdown\n // 리스너를 직접 붙여(요소 자신에서 가장 먼저 발화) 전파를 끊어 document 리스너를 차단한다.\n const innerRef = useRef<HTMLDivElement | null>(null);\n const setRef = useCallback(\n (node: HTMLDivElement | null) => {\n innerRef.current = node;\n if (typeof ref === 'function') ref(node);\n else if (ref) ref.current = node;\n },\n [ref],\n );\n useEffect(() => {\n const el = innerRef.current;\n if (!el) return;\n const stop = (e: Event) => e.stopPropagation();\n el.addEventListener('pointerdown', stop);\n el.addEventListener('mousedown', stop);\n return () => {\n el.removeEventListener('pointerdown', stop);\n el.removeEventListener('mousedown', stop);\n };\n }, [mounted]);\n\n const overlay = (\n <div\n ref={setRef}\n aria-hidden={!open}\n className={cn(\n 'fixed inset-0 flex items-center justify-center transition-opacity duration-200',\n open\n ? 'pointer-events-auto visible opacity-100'\n : 'pointer-events-none invisible opacity-0',\n className,\n )}\n style={{ zIndex, ...style }}\n >\n <div className=\"absolute inset-0 bg-black/40\" />\n <div className=\"relative flex flex-col items-center gap-[16px]\">\n <SCircleProgress indeterminate type=\"inverse\" />\n {message && (\n <p className=\"m-0 max-w-[400px] break-keep text-center text-[14px] font-medium leading-[22px] text-[color:var(--color-white)]\">\n {message}\n </p>\n )}\n </div>\n </div>\n );\n\n if (!mounted) return null;\n return createPortal(overlay, document.body);\n },\n);\n","'use client';\n\nimport { useSyncExternalStore } from 'react';\nimport { createRoot } from 'react-dom/client';\nimport { SLoadingContainer } from './SLoadingContainer';\n\n/**\n * 전역 로딩 오버레이 싱글톤 — sd-loading-container 의 `sdLoading.show()/hide()` 포팅.\n * 앱 어디서든 `loading.show({ message })` / `loading.hide()` 로 호출한다.\n * 최초 show 시 document.body 에 오버레이 루트를 자동 마운트한다.\n */\ninterface LoadingState {\n open: boolean;\n message?: string;\n}\n\nlet state: LoadingState = { open: false, message: undefined };\nconst listeners = new Set<() => void>();\n\nconst emit = () => listeners.forEach(l => l());\nconst setState = (patch: Partial<LoadingState>) => {\n state = { ...state, ...patch };\n emit();\n};\nconst subscribe = (cb: () => void) => {\n listeners.add(cb);\n return () => listeners.delete(cb);\n};\nconst getSnapshot = () => state;\n\n/** 오버레이 뷰포트 — 스토어를 구독해 SLoadingContainer 를 렌더한다. 직접 배치도 가능. */\nexport function SLoadingViewport() {\n const s = useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n return <SLoadingContainer open={s.open} message={s.message} />;\n}\n\nlet mounted = false;\nfunction ensureMounted() {\n if (mounted || typeof document === 'undefined') return;\n mounted = true;\n const host = document.createElement('div');\n host.setAttribute('data-sd-loading-root', '');\n document.body.appendChild(host);\n createRoot(host).render(<SLoadingViewport />);\n}\n\nexport const loading = {\n /** 로딩 오버레이 표시 (메시지 갱신도 동일 호출) */\n show(options: { message?: string } = {}) {\n ensureMounted();\n setState({ open: true, message: options.message });\n },\n /** 로딩 오버레이 숨김 */\n hide() {\n setState({ open: false });\n },\n};\n"]}
|
|
1
|
+
{"version":3,"sources":["../../../src/lib/cn.ts","../../../src/components/SCircleProgress/SCircleProgress.tsx","../../../src/components/SLoadingContainer/SLoadingContainer.tsx","../../../src/components/SLoadingContainer/loading.tsx"],"names":["SCircleProgress","forwardRef","SLoadingContainer","mounted","jsxs","jsx"],"mappings":"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","file":"loading.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 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 { value = 0, type = 'primary', indeterminate = false, label, className, style },\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\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 <svg\n viewBox={`0 0 ${VIEWBOX} ${VIEWBOX}`}\n xmlns=\"http://www.w3.org/2000/svg\"\n className={cn('h-[80px] w-[80px]', indeterminate && 'origin-center animate-circle-spin')}\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 {/* percent 는 원(ring) 아래에 표시 */}\n {!indeterminate && (\n <span\n className=\"text-center text-[16px] font-bold leading-[26px]\"\n style={{ color: percentColor }}\n >\n {Math.round(v)}%\n </span>\n )}\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","'use client';\n\nimport { forwardRef, useCallback, useEffect, useRef, useState, type CSSProperties } from 'react';\nimport { createPortal } from 'react-dom';\nimport { cn } from '../../lib/cn';\nimport { SCircleProgress } from '../SCircleProgress';\n\nexport interface SLoadingContainerProps {\n /** 오버레이 표시 여부 (Stencil의 show()/hide() 명령형 API → 제어 prop으로 대체) */\n open?: boolean;\n /** 스피너 하단 메시지 */\n message?: string;\n /** z-index. 기본값(1200)은 토스트(1100)·모달(1000/1001) 위 — 전체 화면을 막는 최상단 블로킹 오버레이 */\n zIndex?: number;\n className?: string;\n style?: CSSProperties;\n}\n\n/**\n * SLoadingContainer — sd-loading-container 포팅.\n * 전체 화면 딤 오버레이 + inverse 스피너. React에서는 `open` 제어 prop 사용.\n * body 로 portal 해 조상의 스태킹 컨텍스트에 갇히지 않고 항상 최상단에 뜨게 한다.\n */\nexport const SLoadingContainer = forwardRef<HTMLDivElement, SLoadingContainerProps>(\n function SLoadingContainer({ open = false, message, zIndex = 1200, className, style }, ref) {\n // portal 은 클라이언트에서만 (SSR 시 document 없음) — 마운트 후 body 로 렌더\n const [mounted, setMounted] = useState(false);\n useEffect(() => setMounted(true), []);\n\n // 오버레이 표시 중 배경 스크롤 차단\n useEffect(() => {\n if (!open) return;\n const prev = document.body.style.overflow;\n document.body.style.overflow = 'hidden';\n return () => {\n document.body.style.overflow = prev;\n };\n }, [open]);\n\n // body 로 portal 된 블로킹 오버레이라, 클릭이 document 까지 전파되면 Radix Dialog 의\n // \"바깥 클릭\" 감지에 걸려 열려있는 모달이 닫힌다. 오버레이 요소에 네이티브 pointerdown\n // 리스너를 직접 붙여(요소 자신에서 가장 먼저 발화) 전파를 끊어 document 리스너를 차단한다.\n const innerRef = useRef<HTMLDivElement | null>(null);\n const setRef = useCallback(\n (node: HTMLDivElement | null) => {\n innerRef.current = node;\n if (typeof ref === 'function') ref(node);\n else if (ref) ref.current = node;\n },\n [ref],\n );\n useEffect(() => {\n const el = innerRef.current;\n if (!el) return;\n const stop = (e: Event) => e.stopPropagation();\n el.addEventListener('pointerdown', stop);\n el.addEventListener('mousedown', stop);\n return () => {\n el.removeEventListener('pointerdown', stop);\n el.removeEventListener('mousedown', stop);\n };\n }, [mounted]);\n\n const overlay = (\n <div\n ref={setRef}\n aria-hidden={!open}\n className={cn(\n 'fixed inset-0 flex items-center justify-center transition-opacity duration-200',\n open\n ? 'pointer-events-auto visible opacity-100'\n : 'pointer-events-none invisible opacity-0',\n className,\n )}\n style={{ zIndex, ...style }}\n >\n <div className=\"absolute inset-0 bg-black/40\" />\n <div className=\"relative flex flex-col items-center gap-[16px]\">\n <SCircleProgress indeterminate type=\"inverse\" />\n {message && (\n <p className=\"m-0 max-w-[400px] break-keep text-center text-[14px] font-medium leading-[22px] text-[color:var(--color-white)]\">\n {message}\n </p>\n )}\n </div>\n </div>\n );\n\n if (!mounted) return null;\n return createPortal(overlay, document.body);\n },\n);\n","'use client';\n\nimport { useSyncExternalStore } from 'react';\nimport { createRoot } from 'react-dom/client';\nimport { SLoadingContainer } from './SLoadingContainer';\n\n/**\n * 전역 로딩 오버레이 싱글톤 — sd-loading-container 의 `sdLoading.show()/hide()` 포팅.\n * 앱 어디서든 `loading.show({ message })` / `loading.hide()` 로 호출한다.\n * 최초 show 시 document.body 에 오버레이 루트를 자동 마운트한다.\n */\ninterface LoadingState {\n open: boolean;\n message?: string;\n}\n\nlet state: LoadingState = { open: false, message: undefined };\nconst listeners = new Set<() => void>();\n\nconst emit = () => listeners.forEach(l => l());\nconst setState = (patch: Partial<LoadingState>) => {\n state = { ...state, ...patch };\n emit();\n};\nconst subscribe = (cb: () => void) => {\n listeners.add(cb);\n return () => listeners.delete(cb);\n};\nconst getSnapshot = () => state;\n\n/** 오버레이 뷰포트 — 스토어를 구독해 SLoadingContainer 를 렌더한다. 직접 배치도 가능. */\nexport function SLoadingViewport() {\n const s = useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n return <SLoadingContainer open={s.open} message={s.message} />;\n}\n\nlet mounted = false;\nfunction ensureMounted() {\n if (mounted || typeof document === 'undefined') return;\n mounted = true;\n const host = document.createElement('div');\n host.setAttribute('data-sd-loading-root', '');\n document.body.appendChild(host);\n createRoot(host).render(<SLoadingViewport />);\n}\n\nexport const loading = {\n /** 로딩 오버레이 표시 (메시지 갱신도 동일 호출) */\n show(options: { message?: string } = {}) {\n ensureMounted();\n setState({ open: true, message: options.message });\n },\n /** 로딩 오버레이 숨김 */\n hide() {\n setState({ open: false });\n },\n};\n"]}
|
|
@@ -48,12 +48,20 @@ function usePortalContainer() {
|
|
|
48
48
|
// src/lib/floating-anim.ts
|
|
49
49
|
var FLOATING_SLIDE_ANIM = [
|
|
50
50
|
"data-[state=open]:data-[side=top]:animate-floating-in-top",
|
|
51
|
+
"data-[state=delayed-open]:data-[side=top]:animate-floating-in-top",
|
|
52
|
+
"data-[state=instant-open]:data-[side=top]:animate-floating-in-top",
|
|
51
53
|
"data-[state=closed]:data-[side=top]:animate-floating-out-top",
|
|
52
54
|
"data-[state=open]:data-[side=bottom]:animate-floating-in-bottom",
|
|
55
|
+
"data-[state=delayed-open]:data-[side=bottom]:animate-floating-in-bottom",
|
|
56
|
+
"data-[state=instant-open]:data-[side=bottom]:animate-floating-in-bottom",
|
|
53
57
|
"data-[state=closed]:data-[side=bottom]:animate-floating-out-bottom",
|
|
54
58
|
"data-[state=open]:data-[side=left]:animate-floating-in-left",
|
|
59
|
+
"data-[state=delayed-open]:data-[side=left]:animate-floating-in-left",
|
|
60
|
+
"data-[state=instant-open]:data-[side=left]:animate-floating-in-left",
|
|
55
61
|
"data-[state=closed]:data-[side=left]:animate-floating-out-left",
|
|
56
62
|
"data-[state=open]:data-[side=right]:animate-floating-in-right",
|
|
63
|
+
"data-[state=delayed-open]:data-[side=right]:animate-floating-in-right",
|
|
64
|
+
"data-[state=instant-open]:data-[side=right]:animate-floating-in-right",
|
|
57
65
|
"data-[state=closed]:data-[side=right]:animate-floating-out-right"
|
|
58
66
|
].join(" ");
|
|
59
67
|
|
|
@@ -3147,7 +3155,7 @@ function SModalContainer({
|
|
|
3147
3155
|
]
|
|
3148
3156
|
}
|
|
3149
3157
|
) }),
|
|
3150
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { ref: setPortalContainer, className: "fixed left-0 top-0 z-[1001]" })
|
|
3158
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { ref: setPortalContainer, className: "pointer-events-auto fixed left-0 top-0 z-[1001]" })
|
|
3151
3159
|
] }) });
|
|
3152
3160
|
}
|
|
3153
3161
|
var VIEWBOX = 80;
|
|
@@ -3155,11 +3163,11 @@ var RADIUS = 34;
|
|
|
3155
3163
|
var STROKE = 12;
|
|
3156
3164
|
var CIRCUMFERENCE = 2 * Math.PI * RADIUS;
|
|
3157
3165
|
var COLOR_MAP = {
|
|
3158
|
-
primary: { arc: "var(--cmp-
|
|
3166
|
+
primary: { arc: "var(--cmp-progress-active-color)", track: "var(--cmp-progress-color-track)" },
|
|
3159
3167
|
// inverse: 어두운 배경용 — arc 흰색, track 은 흰색 40%(회색 링)
|
|
3160
3168
|
inverse: { arc: "var(--color-white)", track: "rgba(255,255,255,0.4)" },
|
|
3161
|
-
error: { arc: "var(--color-red-75)", track: "var(--cmp-
|
|
3162
|
-
complete: { arc: "#01BB4B", track: "var(--cmp-
|
|
3169
|
+
error: { arc: "var(--color-red-75)", track: "var(--cmp-progress-color-track)" },
|
|
3170
|
+
complete: { arc: "#01BB4B", track: "var(--cmp-progress-color-track)" }
|
|
3163
3171
|
};
|
|
3164
3172
|
var clamp = (v) => Number.isFinite(v) ? Math.max(0, Math.min(100, v)) : 0;
|
|
3165
3173
|
var SCircleProgress = react.forwardRef(
|
|
@@ -3173,65 +3181,63 @@ var SCircleProgress = react.forwardRef(
|
|
|
3173
3181
|
"div",
|
|
3174
3182
|
{
|
|
3175
3183
|
ref,
|
|
3176
|
-
className: cn(
|
|
3184
|
+
className: cn(
|
|
3185
|
+
"inline-flex flex-col items-center gap-[var(--cmp-progress-circular-gap)]",
|
|
3186
|
+
className
|
|
3187
|
+
),
|
|
3177
3188
|
style,
|
|
3178
3189
|
children: [
|
|
3179
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
3180
|
-
|
|
3181
|
-
|
|
3182
|
-
{
|
|
3183
|
-
|
|
3184
|
-
|
|
3185
|
-
|
|
3186
|
-
|
|
3187
|
-
|
|
3190
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
3191
|
+
"svg",
|
|
3192
|
+
{
|
|
3193
|
+
viewBox: `0 0 ${VIEWBOX} ${VIEWBOX}`,
|
|
3194
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
3195
|
+
className: cn("h-[80px] w-[80px]", indeterminate && "origin-center animate-circle-spin"),
|
|
3196
|
+
children: [
|
|
3197
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3198
|
+
"circle",
|
|
3199
|
+
{
|
|
3200
|
+
cx: c,
|
|
3201
|
+
cy: c,
|
|
3202
|
+
r: RADIUS,
|
|
3203
|
+
fill: "none",
|
|
3204
|
+
strokeWidth: STROKE,
|
|
3205
|
+
style: { stroke: colors.track }
|
|
3206
|
+
}
|
|
3188
3207
|
),
|
|
3189
|
-
|
|
3190
|
-
|
|
3191
|
-
|
|
3192
|
-
|
|
3193
|
-
|
|
3194
|
-
|
|
3195
|
-
|
|
3196
|
-
|
|
3197
|
-
|
|
3198
|
-
|
|
3199
|
-
|
|
3200
|
-
|
|
3201
|
-
|
|
3202
|
-
|
|
3203
|
-
|
|
3204
|
-
|
|
3205
|
-
cy: c,
|
|
3206
|
-
r: RADIUS,
|
|
3207
|
-
fill: "none",
|
|
3208
|
-
strokeWidth: STROKE,
|
|
3209
|
-
strokeLinecap: "round",
|
|
3210
|
-
className: cn(
|
|
3211
|
-
"origin-center",
|
|
3212
|
-
indeterminate ? "animate-circle-arc" : "-rotate-90 transition-[stroke-dasharray] duration-[400ms] ease-linear"
|
|
3213
|
-
),
|
|
3214
|
-
style: {
|
|
3215
|
-
stroke: colors.arc,
|
|
3216
|
-
...indeterminate ? {} : { strokeDasharray: `${filled} ${CIRCUMFERENCE}`, strokeDashoffset: 0 }
|
|
3217
|
-
}
|
|
3208
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3209
|
+
"circle",
|
|
3210
|
+
{
|
|
3211
|
+
cx: c,
|
|
3212
|
+
cy: c,
|
|
3213
|
+
r: RADIUS,
|
|
3214
|
+
fill: "none",
|
|
3215
|
+
strokeWidth: STROKE,
|
|
3216
|
+
strokeLinecap: "round",
|
|
3217
|
+
className: cn(
|
|
3218
|
+
"origin-center",
|
|
3219
|
+
indeterminate ? "animate-circle-arc" : "-rotate-90 transition-[stroke-dasharray] duration-[400ms] ease-linear"
|
|
3220
|
+
),
|
|
3221
|
+
style: {
|
|
3222
|
+
stroke: colors.arc,
|
|
3223
|
+
...indeterminate ? {} : { strokeDasharray: `${filled} ${CIRCUMFERENCE}`, strokeDashoffset: 0 }
|
|
3218
3224
|
}
|
|
3219
|
-
|
|
3220
|
-
|
|
3221
|
-
|
|
3222
|
-
|
|
3223
|
-
|
|
3224
|
-
|
|
3225
|
-
|
|
3226
|
-
|
|
3227
|
-
|
|
3228
|
-
|
|
3229
|
-
|
|
3230
|
-
|
|
3231
|
-
|
|
3232
|
-
|
|
3233
|
-
|
|
3234
|
-
|
|
3225
|
+
}
|
|
3226
|
+
)
|
|
3227
|
+
]
|
|
3228
|
+
}
|
|
3229
|
+
),
|
|
3230
|
+
!indeterminate && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3231
|
+
"span",
|
|
3232
|
+
{
|
|
3233
|
+
className: "text-center text-[16px] font-bold leading-[26px]",
|
|
3234
|
+
style: { color: percentColor },
|
|
3235
|
+
children: [
|
|
3236
|
+
Math.round(v),
|
|
3237
|
+
"%"
|
|
3238
|
+
]
|
|
3239
|
+
}
|
|
3240
|
+
),
|
|
3235
3241
|
label && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-center text-[12px] font-normal leading-[20px] text-[color:var(--cmp-progress-color-label)]", children: label })
|
|
3236
3242
|
]
|
|
3237
3243
|
}
|
|
@@ -3405,7 +3411,7 @@ var SButton = react.forwardRef(function SButton2({
|
|
|
3405
3411
|
);
|
|
3406
3412
|
});
|
|
3407
3413
|
var DEFAULT_MESSAGE = {
|
|
3408
|
-
loading: "",
|
|
3414
|
+
loading: "\uC791\uC5C5 \uC9C4\uD589\uC911...",
|
|
3409
3415
|
error: "\uC791\uC5C5\uC5D0 \uC2E4\uD328\uD558\uC600\uC2B5\uB2C8\uB2E4. \uB2E4\uC2DC \uC2DC\uB3C4\uD574 \uC8FC\uC138\uC694."
|
|
3410
3416
|
};
|
|
3411
3417
|
var DEFAULT_BUTTON_LABEL = {
|
|
@@ -3427,6 +3433,7 @@ function SLoadingModal({
|
|
|
3427
3433
|
}) {
|
|
3428
3434
|
const resolvedMessage = message ?? DEFAULT_MESSAGE[state];
|
|
3429
3435
|
const lines = Array.isArray(resolvedMessage) ? resolvedMessage : resolvedMessage ? [resolvedMessage] : [];
|
|
3436
|
+
const showButton = useButton || state === "error";
|
|
3430
3437
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
3431
3438
|
SModalContainer,
|
|
3432
3439
|
{
|
|
@@ -3446,7 +3453,7 @@ function SLoadingModal({
|
|
|
3446
3453
|
},
|
|
3447
3454
|
i
|
|
3448
3455
|
)) }),
|
|
3449
|
-
|
|
3456
|
+
showButton && /* @__PURE__ */ jsxRuntime.jsx(
|
|
3450
3457
|
SButton,
|
|
3451
3458
|
{
|
|
3452
3459
|
color: "neutral",
|