@hua-labs/hua-ux 0.1.0-alpha.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +839 -0
- package/dist/framework/a11y/components/LiveRegion.d.ts +64 -0
- package/dist/framework/a11y/components/LiveRegion.d.ts.map +1 -0
- package/dist/framework/a11y/components/LiveRegion.js +43 -0
- package/dist/framework/a11y/components/SkipToContent.d.ts +62 -0
- package/dist/framework/a11y/components/SkipToContent.d.ts.map +1 -0
- package/dist/framework/a11y/components/SkipToContent.js +60 -0
- package/dist/framework/a11y/hooks/useFocusManagement.d.ts +60 -0
- package/dist/framework/a11y/hooks/useFocusManagement.d.ts.map +1 -0
- package/dist/framework/a11y/hooks/useFocusManagement.js +71 -0
- package/dist/framework/a11y/hooks/useFocusTrap.d.ts +64 -0
- package/dist/framework/a11y/hooks/useFocusTrap.d.ts.map +1 -0
- package/dist/framework/a11y/hooks/useFocusTrap.js +185 -0
- package/dist/framework/a11y/hooks/useLiveRegion.d.ts +56 -0
- package/dist/framework/a11y/hooks/useLiveRegion.d.ts.map +1 -0
- package/dist/framework/a11y/hooks/useLiveRegion.js +60 -0
- package/dist/framework/a11y/index.d.ts +16 -0
- package/dist/framework/a11y/index.d.ts.map +1 -0
- package/dist/framework/a11y/index.js +11 -0
- package/dist/framework/branding/context.d.ts +52 -0
- package/dist/framework/branding/context.d.ts.map +1 -0
- package/dist/framework/branding/context.js +96 -0
- package/dist/framework/branding/css-vars.d.ts +34 -0
- package/dist/framework/branding/css-vars.d.ts.map +1 -0
- package/dist/framework/branding/css-vars.js +95 -0
- package/dist/framework/branding/tailwind-config.d.ts +38 -0
- package/dist/framework/branding/tailwind-config.d.ts.map +1 -0
- package/dist/framework/branding/tailwind-config.js +66 -0
- package/dist/framework/components/BrandedButton.d.ts +53 -0
- package/dist/framework/components/BrandedButton.d.ts.map +1 -0
- package/dist/framework/components/BrandedButton.js +40 -0
- package/dist/framework/components/BrandedCard.d.ts +52 -0
- package/dist/framework/components/BrandedCard.d.ts.map +1 -0
- package/dist/framework/components/BrandedCard.js +73 -0
- package/dist/framework/components/ErrorBoundary.d.ts +92 -0
- package/dist/framework/components/ErrorBoundary.d.ts.map +1 -0
- package/dist/framework/components/ErrorBoundary.js +121 -0
- package/dist/framework/components/HuaUxLayout.d.ts +29 -0
- package/dist/framework/components/HuaUxLayout.d.ts.map +1 -0
- package/dist/framework/components/HuaUxLayout.js +32 -0
- package/dist/framework/components/HuaUxPage.d.ts +48 -0
- package/dist/framework/components/HuaUxPage.d.ts.map +1 -0
- package/dist/framework/components/HuaUxPage.js +105 -0
- package/dist/framework/components/Providers.d.ts +17 -0
- package/dist/framework/components/Providers.d.ts.map +1 -0
- package/dist/framework/components/Providers.js +72 -0
- package/dist/framework/components/WelcomePage.d.ts +44 -0
- package/dist/framework/components/WelcomePage.d.ts.map +1 -0
- package/dist/framework/components/WelcomePage.js +80 -0
- package/dist/framework/config/index.d.ts +182 -0
- package/dist/framework/config/index.d.ts.map +1 -0
- package/dist/framework/config/index.js +329 -0
- package/dist/framework/config/merge.d.ts +26 -0
- package/dist/framework/config/merge.d.ts.map +1 -0
- package/dist/framework/config/merge.js +160 -0
- package/dist/framework/config/schema.d.ts +25 -0
- package/dist/framework/config/schema.d.ts.map +1 -0
- package/dist/framework/config/schema.js +122 -0
- package/dist/framework/hooks/useMotion.d.ts +45 -0
- package/dist/framework/hooks/useMotion.d.ts.map +1 -0
- package/dist/framework/hooks/useMotion.js +40 -0
- package/dist/framework/index.d.ts +37 -0
- package/dist/framework/index.d.ts.map +1 -0
- package/dist/framework/index.js +42 -0
- package/dist/framework/license/errors.d.ts +15 -0
- package/dist/framework/license/errors.d.ts.map +1 -0
- package/dist/framework/license/errors.js +52 -0
- package/dist/framework/license/index.d.ts +70 -0
- package/dist/framework/license/index.d.ts.map +1 -0
- package/dist/framework/license/index.js +124 -0
- package/dist/framework/license/loader.d.ts +26 -0
- package/dist/framework/license/loader.d.ts.map +1 -0
- package/dist/framework/license/loader.js +137 -0
- package/dist/framework/license/types.d.ts +67 -0
- package/dist/framework/license/types.d.ts.map +1 -0
- package/dist/framework/license/types.js +18 -0
- package/dist/framework/loading/components/SkeletonGroup.d.ts +44 -0
- package/dist/framework/loading/components/SkeletonGroup.d.ts.map +1 -0
- package/dist/framework/loading/components/SkeletonGroup.js +34 -0
- package/dist/framework/loading/components/SuspenseWrapper.d.ts +58 -0
- package/dist/framework/loading/components/SuspenseWrapper.d.ts.map +1 -0
- package/dist/framework/loading/components/SuspenseWrapper.js +40 -0
- package/dist/framework/loading/hoc/withSuspense.d.ts +46 -0
- package/dist/framework/loading/hoc/withSuspense.d.ts.map +1 -0
- package/dist/framework/loading/hoc/withSuspense.js +54 -0
- package/dist/framework/loading/hooks/useDelayedLoading.d.ts +56 -0
- package/dist/framework/loading/hooks/useDelayedLoading.d.ts.map +1 -0
- package/dist/framework/loading/hooks/useDelayedLoading.js +97 -0
- package/dist/framework/loading/hooks/useLoadingState.d.ts +69 -0
- package/dist/framework/loading/hooks/useLoadingState.d.ts.map +1 -0
- package/dist/framework/loading/hooks/useLoadingState.js +59 -0
- package/dist/framework/loading/index.d.ts +16 -0
- package/dist/framework/loading/index.d.ts.map +1 -0
- package/dist/framework/loading/index.js +13 -0
- package/dist/framework/middleware/i18n.d.ts +90 -0
- package/dist/framework/middleware/i18n.d.ts.map +1 -0
- package/dist/framework/middleware/i18n.js +99 -0
- package/dist/framework/plugins/index.d.ts +8 -0
- package/dist/framework/plugins/index.d.ts.map +1 -0
- package/dist/framework/plugins/index.js +6 -0
- package/dist/framework/plugins/registry.d.ts +95 -0
- package/dist/framework/plugins/registry.d.ts.map +1 -0
- package/dist/framework/plugins/registry.js +160 -0
- package/dist/framework/plugins/types.d.ts +97 -0
- package/dist/framework/plugins/types.d.ts.map +1 -0
- package/dist/framework/plugins/types.js +6 -0
- package/dist/framework/seo/geo/examples.d.ts +87 -0
- package/dist/framework/seo/geo/examples.d.ts.map +1 -0
- package/dist/framework/seo/geo/examples.js +295 -0
- package/dist/framework/seo/geo/generateGEOMetadata.d.ts +107 -0
- package/dist/framework/seo/geo/generateGEOMetadata.d.ts.map +1 -0
- package/dist/framework/seo/geo/generateGEOMetadata.js +404 -0
- package/dist/framework/seo/geo/index.d.ts +19 -0
- package/dist/framework/seo/geo/index.d.ts.map +1 -0
- package/dist/framework/seo/geo/index.js +21 -0
- package/dist/framework/seo/geo/presets.d.ts +52 -0
- package/dist/framework/seo/geo/presets.d.ts.map +1 -0
- package/dist/framework/seo/geo/presets.js +47 -0
- package/dist/framework/seo/geo/structuredData.d.ts +187 -0
- package/dist/framework/seo/geo/structuredData.d.ts.map +1 -0
- package/dist/framework/seo/geo/structuredData.js +354 -0
- package/dist/framework/seo/geo/test-utils.d.ts +78 -0
- package/dist/framework/seo/geo/test-utils.d.ts.map +1 -0
- package/dist/framework/seo/geo/test-utils.js +139 -0
- package/dist/framework/seo/geo/types.d.ts +225 -0
- package/dist/framework/seo/geo/types.d.ts.map +1 -0
- package/dist/framework/seo/geo/types.js +51 -0
- package/dist/framework/types/index.d.ts +577 -0
- package/dist/framework/types/index.d.ts.map +1 -0
- package/dist/framework/types/index.js +6 -0
- package/dist/framework/utils/data-fetching.d.ts +45 -0
- package/dist/framework/utils/data-fetching.d.ts.map +1 -0
- package/dist/framework/utils/data-fetching.js +74 -0
- package/dist/framework/utils/file-structure.d.ts +29 -0
- package/dist/framework/utils/file-structure.d.ts.map +1 -0
- package/dist/framework/utils/file-structure.js +72 -0
- package/dist/framework/utils/metadata.d.ts +109 -0
- package/dist/framework/utils/metadata.d.ts.map +1 -0
- package/dist/framework/utils/metadata.js +105 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +21 -0
- package/dist/presets/index.d.ts +8 -0
- package/dist/presets/index.d.ts.map +1 -0
- package/dist/presets/index.js +7 -0
- package/dist/presets/marketing.d.ts +41 -0
- package/dist/presets/marketing.d.ts.map +1 -0
- package/dist/presets/marketing.js +81 -0
- package/dist/presets/product.d.ts +41 -0
- package/dist/presets/product.d.ts.map +1 -0
- package/dist/presets/product.js +74 -0
- package/package.json +91 -0
- package/src/framework/README.md +329 -0
- package/src/framework/__tests__/branding/css-vars.test.ts +147 -0
- package/src/framework/__tests__/components/ErrorBoundary.test.tsx +146 -0
- package/src/framework/__tests__/config/defineConfig.test.ts +138 -0
- package/src/framework/__tests__/hooks/useMotion.test.ts +105 -0
- package/src/framework/__tests__/seo/geo/generateGEOMetadata.test.ts +207 -0
- package/src/framework/__tests__/seo/geo/structuredData.test.ts +262 -0
- package/src/framework/a11y/components/LiveRegion.tsx +89 -0
- package/src/framework/a11y/components/SkipToContent.tsx +103 -0
- package/src/framework/a11y/hooks/useFocusManagement.ts +125 -0
- package/src/framework/a11y/hooks/useFocusTrap.ts +239 -0
- package/src/framework/a11y/hooks/useLiveRegion.ts +95 -0
- package/src/framework/a11y/index.ts +17 -0
- package/src/framework/branding/context.tsx +135 -0
- package/src/framework/branding/css-vars.ts +110 -0
- package/src/framework/branding/tailwind-config.ts +90 -0
- package/src/framework/components/BrandedButton.tsx +94 -0
- package/src/framework/components/BrandedCard.tsx +87 -0
- package/src/framework/components/ErrorBoundary.tsx +215 -0
- package/src/framework/components/HuaUxLayout.tsx +36 -0
- package/src/framework/components/HuaUxPage.tsx +138 -0
- package/src/framework/components/Providers.tsx +98 -0
- package/src/framework/components/WelcomePage.tsx +207 -0
- package/src/framework/config/index.ts +349 -0
- package/src/framework/config/merge.ts +190 -0
- package/src/framework/config/schema.ts +140 -0
- package/src/framework/hooks/useMotion.ts +57 -0
- package/src/framework/index.ts +122 -0
- package/src/framework/license/errors.ts +63 -0
- package/src/framework/license/index.ts +137 -0
- package/src/framework/license/loader.ts +158 -0
- package/src/framework/license/types.ts +95 -0
- package/src/framework/loading/components/SkeletonGroup.tsx +70 -0
- package/src/framework/loading/components/SuspenseWrapper.tsx +88 -0
- package/src/framework/loading/hoc/withSuspense.tsx +96 -0
- package/src/framework/loading/hooks/useDelayedLoading.ts +127 -0
- package/src/framework/loading/hooks/useLoadingState.ts +103 -0
- package/src/framework/loading/index.ts +19 -0
- package/src/framework/middleware/i18n.ts +161 -0
- package/src/framework/middleware/index.ts +7 -0
- package/src/framework/plugins/index.ts +13 -0
- package/src/framework/plugins/registry.ts +186 -0
- package/src/framework/plugins/types.ts +106 -0
- package/src/framework/seo/geo/examples.tsx +415 -0
- package/src/framework/seo/geo/generateGEOMetadata.ts +441 -0
- package/src/framework/seo/geo/index.ts +61 -0
- package/src/framework/seo/geo/presets.ts +58 -0
- package/src/framework/seo/geo/structuredData.ts +422 -0
- package/src/framework/seo/geo/test-utils.ts +179 -0
- package/src/framework/seo/geo/types.ts +315 -0
- package/src/framework/types/index.ts +623 -0
- package/src/framework/utils/data-fetching.ts +95 -0
- package/src/framework/utils/file-structure.ts +88 -0
- package/src/framework/utils/metadata.ts +152 -0
- package/src/index.ts +31 -0
- package/src/presets/index.ts +8 -0
- package/src/presets/marketing.ts +88 -0
- package/src/presets/product.ts +81 -0
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @hua-labs/hua-ux/framework - useLiveRegion
|
|
3
|
+
*
|
|
4
|
+
* 프로그래밍 방식으로 Live Region을 사용하는 hook
|
|
5
|
+
* Hook for programmatically using Live Region
|
|
6
|
+
*/
|
|
7
|
+
'use client';
|
|
8
|
+
import React, { useCallback, useState } from 'react';
|
|
9
|
+
import { LiveRegion } from '../components/LiveRegion';
|
|
10
|
+
/**
|
|
11
|
+
* useLiveRegion Hook
|
|
12
|
+
*
|
|
13
|
+
* 프로그래밍 방식으로 Live Region을 사용할 수 있습니다.
|
|
14
|
+
* Allows programmatic use of Live Region.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```tsx
|
|
18
|
+
* function MyComponent() {
|
|
19
|
+
* const { announce, LiveRegionComponent } = useLiveRegion();
|
|
20
|
+
*
|
|
21
|
+
* const handleClick = () => {
|
|
22
|
+
* announce('버튼이 클릭되었습니다');
|
|
23
|
+
* };
|
|
24
|
+
*
|
|
25
|
+
* return (
|
|
26
|
+
* <div>
|
|
27
|
+
* <button onClick={handleClick}>Click me</button>
|
|
28
|
+
* {LiveRegionComponent}
|
|
29
|
+
* </div>
|
|
30
|
+
* );
|
|
31
|
+
* }
|
|
32
|
+
* ```
|
|
33
|
+
*
|
|
34
|
+
* @param defaultPoliteness - 기본 politeness 레벨
|
|
35
|
+
* @returns Live Region 제어 함수와 컴포넌트
|
|
36
|
+
*/
|
|
37
|
+
export function useLiveRegion(defaultPoliteness = 'polite') {
|
|
38
|
+
const [message, setMessage] = useState(undefined);
|
|
39
|
+
const [politeness, setPoliteness] = useState(defaultPoliteness);
|
|
40
|
+
const announce = useCallback((newMessage, newPoliteness) => {
|
|
41
|
+
// 메시지를 초기화한 후 다시 설정하여 스크린 리더가 변경을 감지하도록 함
|
|
42
|
+
setMessage(undefined);
|
|
43
|
+
// 다음 틱에 메시지 설정
|
|
44
|
+
setTimeout(() => {
|
|
45
|
+
setMessage(newMessage);
|
|
46
|
+
if (newPoliteness) {
|
|
47
|
+
setPoliteness(newPoliteness);
|
|
48
|
+
}
|
|
49
|
+
}, 0);
|
|
50
|
+
}, []);
|
|
51
|
+
const LiveRegionComponent = React.createElement(LiveRegion, {
|
|
52
|
+
message,
|
|
53
|
+
politeness,
|
|
54
|
+
});
|
|
55
|
+
return {
|
|
56
|
+
announce,
|
|
57
|
+
LiveRegionComponent,
|
|
58
|
+
message,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @hua-labs/hua-ux/framework - Accessibility (a11y)
|
|
3
|
+
*
|
|
4
|
+
* WCAG 2.1 준수를 위한 접근성 도구 모음
|
|
5
|
+
* Accessibility tools for WCAG 2.1 compliance
|
|
6
|
+
*/
|
|
7
|
+
export { useFocusManagement } from './hooks/useFocusManagement';
|
|
8
|
+
export { useFocusTrap } from './hooks/useFocusTrap';
|
|
9
|
+
export { SkipToContent } from './components/SkipToContent';
|
|
10
|
+
export { LiveRegion } from './components/LiveRegion';
|
|
11
|
+
export { useLiveRegion } from './hooks/useLiveRegion';
|
|
12
|
+
export type { FocusManagementOptions } from './hooks/useFocusManagement';
|
|
13
|
+
export type { FocusTrapOptions } from './hooks/useFocusTrap';
|
|
14
|
+
export type { SkipToContentProps } from './components/SkipToContent';
|
|
15
|
+
export type { LiveRegionProps } from './components/LiveRegion';
|
|
16
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/framework/a11y/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAEtD,YAAY,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AACzE,YAAY,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,YAAY,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AACrE,YAAY,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @hua-labs/hua-ux/framework - Accessibility (a11y)
|
|
3
|
+
*
|
|
4
|
+
* WCAG 2.1 준수를 위한 접근성 도구 모음
|
|
5
|
+
* Accessibility tools for WCAG 2.1 compliance
|
|
6
|
+
*/
|
|
7
|
+
export { useFocusManagement } from './hooks/useFocusManagement';
|
|
8
|
+
export { useFocusTrap } from './hooks/useFocusTrap';
|
|
9
|
+
export { SkipToContent } from './components/SkipToContent';
|
|
10
|
+
export { LiveRegion } from './components/LiveRegion';
|
|
11
|
+
export { useLiveRegion } from './hooks/useLiveRegion';
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @hua-labs/hua-ux/framework - Branding Context
|
|
3
|
+
*
|
|
4
|
+
* 브랜딩 설정을 컴포넌트에서 사용하기 위한 Context
|
|
5
|
+
*/
|
|
6
|
+
import React from 'react';
|
|
7
|
+
import type { HuaUxConfig } from '../types';
|
|
8
|
+
/**
|
|
9
|
+
* BrandingProvider component
|
|
10
|
+
*
|
|
11
|
+
* 브랜딩 설정을 제공하고 CSS 변수를 자동으로 주입하는 Provider입니다.
|
|
12
|
+
* Provides branding configuration and automatically injects CSS variables.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```tsx
|
|
16
|
+
* <BrandingProvider branding={config.branding}>
|
|
17
|
+
* {children}
|
|
18
|
+
* </BrandingProvider>
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export declare function BrandingProvider({ branding, children, }: {
|
|
22
|
+
branding: NonNullable<HuaUxConfig['branding']> | null;
|
|
23
|
+
children: React.ReactNode;
|
|
24
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
25
|
+
/**
|
|
26
|
+
* useBranding hook
|
|
27
|
+
*
|
|
28
|
+
* 브랜딩 설정을 가져오는 훅입니다.
|
|
29
|
+
*
|
|
30
|
+
* @returns Branding configuration or null
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* ```tsx
|
|
34
|
+
* function MyComponent() {
|
|
35
|
+
* const branding = useBranding();
|
|
36
|
+
* const primaryColor = branding?.colors?.primary || 'blue';
|
|
37
|
+
* return <div style={{ color: primaryColor }}>Hello</div>;
|
|
38
|
+
* }
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
export declare function useBranding(): NonNullable<HuaUxConfig['branding']> | null;
|
|
42
|
+
/**
|
|
43
|
+
* Get color from branding
|
|
44
|
+
*
|
|
45
|
+
* 브랜딩에서 색상을 가져옵니다. 없으면 기본값을 반환합니다.
|
|
46
|
+
*
|
|
47
|
+
* @param colorKey - Color key (primary, secondary, etc.)
|
|
48
|
+
* @param defaultValue - Default color if not found
|
|
49
|
+
* @returns Color value
|
|
50
|
+
*/
|
|
51
|
+
export declare function useBrandingColor(colorKey: keyof NonNullable<NonNullable<HuaUxConfig['branding']>['colors']>, defaultValue?: string): string | undefined;
|
|
52
|
+
//# sourceMappingURL=context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../../src/framework/branding/context.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAoC,MAAM,OAAO,CAAC;AACzD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAiB5C;;;;;;;;;;;;GAYG;AACH,wBAAgB,gBAAgB,CAAC,EAC/B,QAAQ,EACR,QAAQ,GACT,EAAE;IACD,QAAQ,EAAE,WAAW,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC,GAAG,IAAI,CAAC;IACtD,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B,2CAmDA;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,WAAW,IAAI,WAAW,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC,GAAG,IAAI,CAGzE;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,MAAM,WAAW,CAAC,WAAW,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAC3E,YAAY,CAAC,EAAE,MAAM,GACpB,MAAM,GAAG,SAAS,CAGpB"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @hua-labs/hua-ux/framework - Branding Context
|
|
3
|
+
*
|
|
4
|
+
* 브랜딩 설정을 컴포넌트에서 사용하기 위한 Context
|
|
5
|
+
*/
|
|
6
|
+
'use client';
|
|
7
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
8
|
+
import React, { createContext, useContext } from 'react';
|
|
9
|
+
import { generateCSSVariables } from './css-vars';
|
|
10
|
+
/**
|
|
11
|
+
* Branding context
|
|
12
|
+
*/
|
|
13
|
+
const BrandingContext = createContext({
|
|
14
|
+
branding: null,
|
|
15
|
+
});
|
|
16
|
+
/**
|
|
17
|
+
* BrandingProvider component
|
|
18
|
+
*
|
|
19
|
+
* 브랜딩 설정을 제공하고 CSS 변수를 자동으로 주입하는 Provider입니다.
|
|
20
|
+
* Provides branding configuration and automatically injects CSS variables.
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```tsx
|
|
24
|
+
* <BrandingProvider branding={config.branding}>
|
|
25
|
+
* {children}
|
|
26
|
+
* </BrandingProvider>
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
export function BrandingProvider({ branding, children, }) {
|
|
30
|
+
// SSR 시 초기 CSS 변수 주입 (FOUC 방지)
|
|
31
|
+
// Inject initial CSS variables on SSR (prevent FOUC)
|
|
32
|
+
// Next.js의 suppressHydrationWarning을 사용하여 클라이언트 하이드레이션 시 경고 방지
|
|
33
|
+
// Use Next.js suppressHydrationWarning to prevent warnings during client hydration
|
|
34
|
+
const cssVarsString = React.useMemo(() => {
|
|
35
|
+
if (!branding)
|
|
36
|
+
return '';
|
|
37
|
+
return generateCSSVariables(branding);
|
|
38
|
+
}, [branding]);
|
|
39
|
+
// 클라이언트 사이드에서 CSS 변수 동적 업데이트
|
|
40
|
+
// Dynamically update CSS variables on client side
|
|
41
|
+
React.useEffect(() => {
|
|
42
|
+
if (!branding || !cssVarsString)
|
|
43
|
+
return;
|
|
44
|
+
// style 태그 생성 또는 업데이트
|
|
45
|
+
// Create or update style tag
|
|
46
|
+
const styleId = 'hua-ux-branding-vars';
|
|
47
|
+
let styleElement = document.getElementById(styleId);
|
|
48
|
+
if (!styleElement) {
|
|
49
|
+
styleElement = document.createElement('style');
|
|
50
|
+
styleElement.id = styleId;
|
|
51
|
+
document.head.appendChild(styleElement);
|
|
52
|
+
}
|
|
53
|
+
styleElement.textContent = cssVarsString;
|
|
54
|
+
// Cleanup
|
|
55
|
+
return () => {
|
|
56
|
+
const element = document.getElementById(styleId);
|
|
57
|
+
if (element) {
|
|
58
|
+
element.remove();
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
}, [branding, cssVarsString]);
|
|
62
|
+
return (_jsxs(BrandingContext.Provider, { value: { branding }, children: [cssVarsString && (_jsx("style", { id: "hua-ux-branding-vars", dangerouslySetInnerHTML: { __html: cssVarsString }, suppressHydrationWarning: true })), children] }));
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* useBranding hook
|
|
66
|
+
*
|
|
67
|
+
* 브랜딩 설정을 가져오는 훅입니다.
|
|
68
|
+
*
|
|
69
|
+
* @returns Branding configuration or null
|
|
70
|
+
*
|
|
71
|
+
* @example
|
|
72
|
+
* ```tsx
|
|
73
|
+
* function MyComponent() {
|
|
74
|
+
* const branding = useBranding();
|
|
75
|
+
* const primaryColor = branding?.colors?.primary || 'blue';
|
|
76
|
+
* return <div style={{ color: primaryColor }}>Hello</div>;
|
|
77
|
+
* }
|
|
78
|
+
* ```
|
|
79
|
+
*/
|
|
80
|
+
export function useBranding() {
|
|
81
|
+
const { branding } = useContext(BrandingContext);
|
|
82
|
+
return branding;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Get color from branding
|
|
86
|
+
*
|
|
87
|
+
* 브랜딩에서 색상을 가져옵니다. 없으면 기본값을 반환합니다.
|
|
88
|
+
*
|
|
89
|
+
* @param colorKey - Color key (primary, secondary, etc.)
|
|
90
|
+
* @param defaultValue - Default color if not found
|
|
91
|
+
* @returns Color value
|
|
92
|
+
*/
|
|
93
|
+
export function useBrandingColor(colorKey, defaultValue) {
|
|
94
|
+
const branding = useBranding();
|
|
95
|
+
return branding?.colors?.[colorKey] || defaultValue;
|
|
96
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @hua-labs/hua-ux/framework - CSS Variables Generator
|
|
3
|
+
*
|
|
4
|
+
* 브랜딩 설정을 CSS 변수로 자동 생성
|
|
5
|
+
*/
|
|
6
|
+
import type { HuaUxConfig } from '../types';
|
|
7
|
+
/**
|
|
8
|
+
* Generate CSS variables from branding configuration
|
|
9
|
+
*
|
|
10
|
+
* 브랜딩 설정을 CSS 변수 문자열로 변환합니다.
|
|
11
|
+
*
|
|
12
|
+
* @param branding - Branding configuration
|
|
13
|
+
* @returns CSS variables string
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```ts
|
|
17
|
+
* const css = generateCSSVariables({
|
|
18
|
+
* colors: { primary: '#3B82F6' },
|
|
19
|
+
* typography: { fontFamily: ['Inter', 'sans-serif'] },
|
|
20
|
+
* });
|
|
21
|
+
* // Returns: ":root {\n --color-primary: #3B82F6;\n --font-family: Inter, sans-serif;\n}"
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
export declare function generateCSSVariables(branding: NonNullable<HuaUxConfig['branding']>): string;
|
|
25
|
+
/**
|
|
26
|
+
* Generate CSS variables as object
|
|
27
|
+
*
|
|
28
|
+
* 브랜딩 설정을 CSS 변수 객체로 변환합니다.
|
|
29
|
+
*
|
|
30
|
+
* @param branding - Branding configuration
|
|
31
|
+
* @returns CSS variables object
|
|
32
|
+
*/
|
|
33
|
+
export declare function generateCSSVariablesObject(branding: NonNullable<HuaUxConfig['branding']>): Record<string, string>;
|
|
34
|
+
//# sourceMappingURL=css-vars.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"css-vars.d.ts","sourceRoot":"","sources":["../../../src/framework/branding/css-vars.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAE5C;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,WAAW,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC,GAAG,MAAM,CAsC3F;AAED;;;;;;;GAOG;AACH,wBAAgB,0BAA0B,CACxC,QAAQ,EAAE,WAAW,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC,GAC7C,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAkCxB"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @hua-labs/hua-ux/framework - CSS Variables Generator
|
|
3
|
+
*
|
|
4
|
+
* 브랜딩 설정을 CSS 변수로 자동 생성
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Generate CSS variables from branding configuration
|
|
8
|
+
*
|
|
9
|
+
* 브랜딩 설정을 CSS 변수 문자열로 변환합니다.
|
|
10
|
+
*
|
|
11
|
+
* @param branding - Branding configuration
|
|
12
|
+
* @returns CSS variables string
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```ts
|
|
16
|
+
* const css = generateCSSVariables({
|
|
17
|
+
* colors: { primary: '#3B82F6' },
|
|
18
|
+
* typography: { fontFamily: ['Inter', 'sans-serif'] },
|
|
19
|
+
* });
|
|
20
|
+
* // Returns: ":root {\n --color-primary: #3B82F6;\n --font-family: Inter, sans-serif;\n}"
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export function generateCSSVariables(branding) {
|
|
24
|
+
const vars = [];
|
|
25
|
+
// 색상 변수
|
|
26
|
+
if (branding.colors) {
|
|
27
|
+
Object.entries(branding.colors).forEach(([key, value]) => {
|
|
28
|
+
if (value) {
|
|
29
|
+
vars.push(` --color-${key}: ${value};`);
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
// 타이포그래피 변수
|
|
34
|
+
if (branding.typography) {
|
|
35
|
+
if (branding.typography.fontFamily) {
|
|
36
|
+
vars.push(` --font-family: ${branding.typography.fontFamily.join(', ')};`);
|
|
37
|
+
}
|
|
38
|
+
if (branding.typography.fontSize) {
|
|
39
|
+
Object.entries(branding.typography.fontSize).forEach(([key, value]) => {
|
|
40
|
+
if (value) {
|
|
41
|
+
vars.push(` --font-size-${key}: ${value};`);
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
// 커스텀 변수
|
|
47
|
+
if (branding.customVariables) {
|
|
48
|
+
Object.entries(branding.customVariables).forEach(([key, value]) => {
|
|
49
|
+
vars.push(` --${key}: ${value};`);
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
if (vars.length === 0) {
|
|
53
|
+
return '';
|
|
54
|
+
}
|
|
55
|
+
return `:root {\n${vars.join('\n')}\n}`;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Generate CSS variables as object
|
|
59
|
+
*
|
|
60
|
+
* 브랜딩 설정을 CSS 변수 객체로 변환합니다.
|
|
61
|
+
*
|
|
62
|
+
* @param branding - Branding configuration
|
|
63
|
+
* @returns CSS variables object
|
|
64
|
+
*/
|
|
65
|
+
export function generateCSSVariablesObject(branding) {
|
|
66
|
+
const vars = {};
|
|
67
|
+
// 색상 변수
|
|
68
|
+
if (branding.colors) {
|
|
69
|
+
Object.entries(branding.colors).forEach(([key, value]) => {
|
|
70
|
+
if (value) {
|
|
71
|
+
vars[`--color-${key}`] = value;
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
// 타이포그래피 변수
|
|
76
|
+
if (branding.typography) {
|
|
77
|
+
if (branding.typography.fontFamily) {
|
|
78
|
+
vars['--font-family'] = branding.typography.fontFamily.join(', ');
|
|
79
|
+
}
|
|
80
|
+
if (branding.typography.fontSize) {
|
|
81
|
+
Object.entries(branding.typography.fontSize).forEach(([key, value]) => {
|
|
82
|
+
if (value) {
|
|
83
|
+
vars[`--font-size-${key}`] = value;
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
// 커스텀 변수
|
|
89
|
+
if (branding.customVariables) {
|
|
90
|
+
Object.entries(branding.customVariables).forEach(([key, value]) => {
|
|
91
|
+
vars[`--${key}`] = value;
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
return vars;
|
|
95
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @hua-labs/hua-ux/framework - Tailwind Config Generator
|
|
3
|
+
*
|
|
4
|
+
* 브랜딩 설정을 Tailwind Config로 자동 생성
|
|
5
|
+
*/
|
|
6
|
+
import type { HuaUxConfig } from '../types';
|
|
7
|
+
/**
|
|
8
|
+
* Generate Tailwind config from branding configuration
|
|
9
|
+
*
|
|
10
|
+
* 브랜딩 설정을 Tailwind Config 객체로 변환합니다.
|
|
11
|
+
*
|
|
12
|
+
* @param branding - Branding configuration
|
|
13
|
+
* @returns Tailwind config object
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```ts
|
|
17
|
+
* const tailwindConfig = generateTailwindConfig({
|
|
18
|
+
* colors: { primary: '#3B82F6' },
|
|
19
|
+
* typography: { fontFamily: ['Inter', 'sans-serif'] },
|
|
20
|
+
* });
|
|
21
|
+
*
|
|
22
|
+
* // Use in tailwind.config.js:
|
|
23
|
+
* module.exports = {
|
|
24
|
+
* ...tailwindConfig,
|
|
25
|
+
* // ... other config
|
|
26
|
+
* };
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
export declare function generateTailwindConfig(branding: NonNullable<HuaUxConfig['branding']>): {
|
|
30
|
+
theme: {
|
|
31
|
+
extend: {
|
|
32
|
+
colors?: Record<string, string>;
|
|
33
|
+
fontFamily?: Record<string, string[]>;
|
|
34
|
+
fontSize?: Record<string, string>;
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
};
|
|
38
|
+
//# sourceMappingURL=tailwind-config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tailwind-config.d.ts","sourceRoot":"","sources":["../../../src/framework/branding/tailwind-config.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAE5C;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,WAAW,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC,GAC7C;IACD,KAAK,EAAE;QACL,MAAM,EAAE;YACN,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;YAChC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;YACtC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;SACnC,CAAC;KACH,CAAC;CACH,CAiDA"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @hua-labs/hua-ux/framework - Tailwind Config Generator
|
|
3
|
+
*
|
|
4
|
+
* 브랜딩 설정을 Tailwind Config로 자동 생성
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Generate Tailwind config from branding configuration
|
|
8
|
+
*
|
|
9
|
+
* 브랜딩 설정을 Tailwind Config 객체로 변환합니다.
|
|
10
|
+
*
|
|
11
|
+
* @param branding - Branding configuration
|
|
12
|
+
* @returns Tailwind config object
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```ts
|
|
16
|
+
* const tailwindConfig = generateTailwindConfig({
|
|
17
|
+
* colors: { primary: '#3B82F6' },
|
|
18
|
+
* typography: { fontFamily: ['Inter', 'sans-serif'] },
|
|
19
|
+
* });
|
|
20
|
+
*
|
|
21
|
+
* // Use in tailwind.config.js:
|
|
22
|
+
* module.exports = {
|
|
23
|
+
* ...tailwindConfig,
|
|
24
|
+
* // ... other config
|
|
25
|
+
* };
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
export function generateTailwindConfig(branding) {
|
|
29
|
+
const config = {
|
|
30
|
+
theme: {
|
|
31
|
+
extend: {},
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
// 색상 설정
|
|
35
|
+
if (branding.colors) {
|
|
36
|
+
const colors = {};
|
|
37
|
+
Object.entries(branding.colors).forEach(([key, value]) => {
|
|
38
|
+
if (value) {
|
|
39
|
+
colors[key] = value;
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
if (Object.keys(colors).length > 0) {
|
|
43
|
+
config.theme.extend.colors = colors;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
// 타이포그래피 설정
|
|
47
|
+
if (branding.typography) {
|
|
48
|
+
if (branding.typography.fontFamily) {
|
|
49
|
+
config.theme.extend.fontFamily = {
|
|
50
|
+
sans: branding.typography.fontFamily,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
if (branding.typography.fontSize) {
|
|
54
|
+
const fontSize = {};
|
|
55
|
+
Object.entries(branding.typography.fontSize).forEach(([key, value]) => {
|
|
56
|
+
if (value) {
|
|
57
|
+
fontSize[key] = value;
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
if (Object.keys(fontSize).length > 0) {
|
|
61
|
+
config.theme.extend.fontSize = fontSize;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return config;
|
|
66
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @hua-labs/hua-ux/framework - BrandedButton
|
|
3
|
+
*
|
|
4
|
+
* Button 컴포넌트에 branding을 자동으로 적용하는 wrapper
|
|
5
|
+
* Wrapper that automatically applies branding to Button component
|
|
6
|
+
*
|
|
7
|
+
* CSS 변수를 사용하여 Tailwind의 최적화를 활용합니다.
|
|
8
|
+
* Uses CSS variables to leverage Tailwind's optimization.
|
|
9
|
+
*/
|
|
10
|
+
import * as React from 'react';
|
|
11
|
+
import type { ComponentPropsWithoutRef } from 'react';
|
|
12
|
+
import { Button } from '@hua-labs/ui';
|
|
13
|
+
/**
|
|
14
|
+
* BrandedButton Component
|
|
15
|
+
*
|
|
16
|
+
* Button 컴포넌트에 branding 설정을 자동으로 적용합니다.
|
|
17
|
+
* Automatically applies branding configuration to Button component.
|
|
18
|
+
*
|
|
19
|
+
* **자동 적용되는 branding**:
|
|
20
|
+
* - Primary 색상: `variant="default"`일 때 `bg-[var(--color-primary)]` 사용
|
|
21
|
+
* - Secondary 색상: `variant="secondary"`일 때 `bg-[var(--color-secondary)]` 사용
|
|
22
|
+
* - Accent 색상: `variant="outline"`일 때 `border-[var(--color-accent)]` 사용
|
|
23
|
+
*
|
|
24
|
+
* **Auto-applied branding**:
|
|
25
|
+
* - Primary color: Uses `bg-[var(--color-primary)]` when `variant="default"`
|
|
26
|
+
* - Secondary color: Uses `bg-[var(--color-secondary)]` when `variant="secondary"`
|
|
27
|
+
* - Accent color: Uses `border-[var(--color-accent)]` when `variant="outline"`
|
|
28
|
+
*
|
|
29
|
+
* **CSS 변수 방식의 장점**:
|
|
30
|
+
* - Tailwind의 JIT 컴파일러 최적화 활용
|
|
31
|
+
* - 인라인 스타일 없이 깔끔한 코드
|
|
32
|
+
* - 런타임에 동적으로 색상 변경 가능
|
|
33
|
+
*
|
|
34
|
+
* **Advantages of CSS variables**:
|
|
35
|
+
* - Leverages Tailwind's JIT compiler optimization
|
|
36
|
+
* - Clean code without inline styles
|
|
37
|
+
* - Dynamic color changes at runtime
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* ```tsx
|
|
41
|
+
* // branding 설정이 있으면 자동으로 primary 색상 적용
|
|
42
|
+
* // Automatically applies primary color if branding is configured
|
|
43
|
+
* <BrandedButton variant="default">저장</BrandedButton>
|
|
44
|
+
*
|
|
45
|
+
* // branding이 없으면 기본 Button과 동일하게 동작
|
|
46
|
+
* // Works same as default Button if branding is not configured
|
|
47
|
+
* <BrandedButton variant="outline">취소</BrandedButton>
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
type BrandedButtonProps = ComponentPropsWithoutRef<typeof Button>;
|
|
51
|
+
export declare const BrandedButton: React.ForwardRefExoticComponent<BrandedButtonProps & React.RefAttributes<HTMLButtonElement | HTMLAnchorElement>>;
|
|
52
|
+
export {};
|
|
53
|
+
//# sourceMappingURL=BrandedButton.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BrandedButton.d.ts","sourceRoot":"","sources":["../../../src/framework/components/BrandedButton.tsx"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,OAAO,CAAC;AACtD,OAAO,EAAE,MAAM,EAAS,MAAM,cAAc,CAAC;AAG7C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,KAAK,kBAAkB,GAAG,wBAAwB,CAAC,OAAO,MAAM,CAAC,CAAC;AAElE,eAAO,MAAM,aAAa,kHAmCxB,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @hua-labs/hua-ux/framework - BrandedButton
|
|
3
|
+
*
|
|
4
|
+
* Button 컴포넌트에 branding을 자동으로 적용하는 wrapper
|
|
5
|
+
* Wrapper that automatically applies branding to Button component
|
|
6
|
+
*
|
|
7
|
+
* CSS 변수를 사용하여 Tailwind의 최적화를 활용합니다.
|
|
8
|
+
* Uses CSS variables to leverage Tailwind's optimization.
|
|
9
|
+
*/
|
|
10
|
+
'use client';
|
|
11
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
12
|
+
import * as React from 'react';
|
|
13
|
+
import { Button, merge } from '@hua-labs/ui';
|
|
14
|
+
import { useBranding } from '../branding/context';
|
|
15
|
+
export const BrandedButton = React.forwardRef((props, ref) => {
|
|
16
|
+
const { variant = 'default', className, ...restProps } = props;
|
|
17
|
+
const branding = useBranding();
|
|
18
|
+
// Branding 색상이 있으면 Tailwind arbitrary values 사용
|
|
19
|
+
// Use Tailwind arbitrary values if branding colors exist
|
|
20
|
+
let brandingClasses = '';
|
|
21
|
+
if (branding?.colors) {
|
|
22
|
+
if (variant === 'default' && branding.colors.primary) {
|
|
23
|
+
// Primary 색상을 배경으로 사용
|
|
24
|
+
// Use primary color as background
|
|
25
|
+
brandingClasses = 'bg-[var(--color-primary)] text-white border-[var(--color-primary)] hover:opacity-90';
|
|
26
|
+
}
|
|
27
|
+
else if (variant === 'secondary' && branding.colors.secondary) {
|
|
28
|
+
// Secondary 색상을 배경으로 사용
|
|
29
|
+
// Use secondary color as background
|
|
30
|
+
brandingClasses = 'bg-[var(--color-secondary)] text-white border-[var(--color-secondary)] hover:opacity-90';
|
|
31
|
+
}
|
|
32
|
+
else if (variant === 'outline' && branding.colors.accent) {
|
|
33
|
+
// Accent 색상을 테두리와 텍스트로 사용
|
|
34
|
+
// Use accent color for border and text
|
|
35
|
+
brandingClasses = 'border-[var(--color-accent)] text-[var(--color-accent)] bg-transparent hover:bg-[var(--color-accent)]/10';
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return (_jsx(Button, { ref: ref, variant: variant, className: merge(brandingClasses, className), ...restProps }));
|
|
39
|
+
});
|
|
40
|
+
BrandedButton.displayName = 'BrandedButton';
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @hua-labs/hua-ux/framework - BrandedCard
|
|
3
|
+
*
|
|
4
|
+
* Card 컴포넌트에 branding을 자동으로 적용하는 wrapper
|
|
5
|
+
* Wrapper that automatically applies branding to Card component
|
|
6
|
+
*
|
|
7
|
+
* CSS 변수를 사용하여 Tailwind의 최적화를 활용합니다.
|
|
8
|
+
* Uses CSS variables to leverage Tailwind's optimization.
|
|
9
|
+
*/
|
|
10
|
+
import React from 'react';
|
|
11
|
+
import { type CardProps } from '@hua-labs/ui';
|
|
12
|
+
/**
|
|
13
|
+
* BrandedCard Component
|
|
14
|
+
*
|
|
15
|
+
* Card 컴포넌트에 branding 설정을 자동으로 적용합니다.
|
|
16
|
+
* Automatically applies branding configuration to Card component.
|
|
17
|
+
*
|
|
18
|
+
* **자동 적용되는 branding**:
|
|
19
|
+
* - Accent 색상: `variant="outline"`일 때 `border-[var(--color-accent)]` 사용
|
|
20
|
+
* - Primary 색상: `variant="default"`일 때 `bg-[var(--color-primary)]/5` 사용
|
|
21
|
+
*
|
|
22
|
+
* **Auto-applied branding**:
|
|
23
|
+
* - Accent color: Uses `border-[var(--color-accent)]` when `variant="outline"`
|
|
24
|
+
* - Primary color: Uses `bg-[var(--color-primary)]/5` when `variant="default"`
|
|
25
|
+
*
|
|
26
|
+
* **CSS 변수 방식의 장점**:
|
|
27
|
+
* - Tailwind의 JIT 컴파일러 최적화 활용
|
|
28
|
+
* - 인라인 스타일 없이 깔끔한 코드
|
|
29
|
+
* - 런타임에 동적으로 색상 변경 가능
|
|
30
|
+
*
|
|
31
|
+
* **Advantages of CSS variables**:
|
|
32
|
+
* - Leverages Tailwind's JIT compiler optimization
|
|
33
|
+
* - Clean code without inline styles
|
|
34
|
+
* - Dynamic color changes at runtime
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* ```tsx
|
|
38
|
+
* // branding 설정이 있으면 자동으로 색상 적용
|
|
39
|
+
* // Automatically applies colors if branding is configured
|
|
40
|
+
* <BrandedCard variant="outline">
|
|
41
|
+
* <CardContent>내용</CardContent>
|
|
42
|
+
* </BrandedCard>
|
|
43
|
+
*
|
|
44
|
+
* // branding이 없으면 기본 Card와 동일하게 동작
|
|
45
|
+
* // Works same as default Card if branding is not configured
|
|
46
|
+
* <BrandedCard variant="elevated">
|
|
47
|
+
* <CardContent>내용</CardContent>
|
|
48
|
+
* </BrandedCard>
|
|
49
|
+
* ```
|
|
50
|
+
*/
|
|
51
|
+
export declare const BrandedCard: React.ForwardRefExoticComponent<CardProps & React.RefAttributes<HTMLDivElement>>;
|
|
52
|
+
//# sourceMappingURL=BrandedCard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BrandedCard.d.ts","sourceRoot":"","sources":["../../../src/framework/components/BrandedCard.tsx"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAe,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AAG3D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,eAAO,MAAM,WAAW,kFA6BvB,CAAC"}
|