@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.
Files changed (210) hide show
  1. package/README.md +839 -0
  2. package/dist/framework/a11y/components/LiveRegion.d.ts +64 -0
  3. package/dist/framework/a11y/components/LiveRegion.d.ts.map +1 -0
  4. package/dist/framework/a11y/components/LiveRegion.js +43 -0
  5. package/dist/framework/a11y/components/SkipToContent.d.ts +62 -0
  6. package/dist/framework/a11y/components/SkipToContent.d.ts.map +1 -0
  7. package/dist/framework/a11y/components/SkipToContent.js +60 -0
  8. package/dist/framework/a11y/hooks/useFocusManagement.d.ts +60 -0
  9. package/dist/framework/a11y/hooks/useFocusManagement.d.ts.map +1 -0
  10. package/dist/framework/a11y/hooks/useFocusManagement.js +71 -0
  11. package/dist/framework/a11y/hooks/useFocusTrap.d.ts +64 -0
  12. package/dist/framework/a11y/hooks/useFocusTrap.d.ts.map +1 -0
  13. package/dist/framework/a11y/hooks/useFocusTrap.js +185 -0
  14. package/dist/framework/a11y/hooks/useLiveRegion.d.ts +56 -0
  15. package/dist/framework/a11y/hooks/useLiveRegion.d.ts.map +1 -0
  16. package/dist/framework/a11y/hooks/useLiveRegion.js +60 -0
  17. package/dist/framework/a11y/index.d.ts +16 -0
  18. package/dist/framework/a11y/index.d.ts.map +1 -0
  19. package/dist/framework/a11y/index.js +11 -0
  20. package/dist/framework/branding/context.d.ts +52 -0
  21. package/dist/framework/branding/context.d.ts.map +1 -0
  22. package/dist/framework/branding/context.js +96 -0
  23. package/dist/framework/branding/css-vars.d.ts +34 -0
  24. package/dist/framework/branding/css-vars.d.ts.map +1 -0
  25. package/dist/framework/branding/css-vars.js +95 -0
  26. package/dist/framework/branding/tailwind-config.d.ts +38 -0
  27. package/dist/framework/branding/tailwind-config.d.ts.map +1 -0
  28. package/dist/framework/branding/tailwind-config.js +66 -0
  29. package/dist/framework/components/BrandedButton.d.ts +53 -0
  30. package/dist/framework/components/BrandedButton.d.ts.map +1 -0
  31. package/dist/framework/components/BrandedButton.js +40 -0
  32. package/dist/framework/components/BrandedCard.d.ts +52 -0
  33. package/dist/framework/components/BrandedCard.d.ts.map +1 -0
  34. package/dist/framework/components/BrandedCard.js +73 -0
  35. package/dist/framework/components/ErrorBoundary.d.ts +92 -0
  36. package/dist/framework/components/ErrorBoundary.d.ts.map +1 -0
  37. package/dist/framework/components/ErrorBoundary.js +121 -0
  38. package/dist/framework/components/HuaUxLayout.d.ts +29 -0
  39. package/dist/framework/components/HuaUxLayout.d.ts.map +1 -0
  40. package/dist/framework/components/HuaUxLayout.js +32 -0
  41. package/dist/framework/components/HuaUxPage.d.ts +48 -0
  42. package/dist/framework/components/HuaUxPage.d.ts.map +1 -0
  43. package/dist/framework/components/HuaUxPage.js +105 -0
  44. package/dist/framework/components/Providers.d.ts +17 -0
  45. package/dist/framework/components/Providers.d.ts.map +1 -0
  46. package/dist/framework/components/Providers.js +72 -0
  47. package/dist/framework/components/WelcomePage.d.ts +44 -0
  48. package/dist/framework/components/WelcomePage.d.ts.map +1 -0
  49. package/dist/framework/components/WelcomePage.js +80 -0
  50. package/dist/framework/config/index.d.ts +182 -0
  51. package/dist/framework/config/index.d.ts.map +1 -0
  52. package/dist/framework/config/index.js +329 -0
  53. package/dist/framework/config/merge.d.ts +26 -0
  54. package/dist/framework/config/merge.d.ts.map +1 -0
  55. package/dist/framework/config/merge.js +160 -0
  56. package/dist/framework/config/schema.d.ts +25 -0
  57. package/dist/framework/config/schema.d.ts.map +1 -0
  58. package/dist/framework/config/schema.js +122 -0
  59. package/dist/framework/hooks/useMotion.d.ts +45 -0
  60. package/dist/framework/hooks/useMotion.d.ts.map +1 -0
  61. package/dist/framework/hooks/useMotion.js +40 -0
  62. package/dist/framework/index.d.ts +37 -0
  63. package/dist/framework/index.d.ts.map +1 -0
  64. package/dist/framework/index.js +42 -0
  65. package/dist/framework/license/errors.d.ts +15 -0
  66. package/dist/framework/license/errors.d.ts.map +1 -0
  67. package/dist/framework/license/errors.js +52 -0
  68. package/dist/framework/license/index.d.ts +70 -0
  69. package/dist/framework/license/index.d.ts.map +1 -0
  70. package/dist/framework/license/index.js +124 -0
  71. package/dist/framework/license/loader.d.ts +26 -0
  72. package/dist/framework/license/loader.d.ts.map +1 -0
  73. package/dist/framework/license/loader.js +137 -0
  74. package/dist/framework/license/types.d.ts +67 -0
  75. package/dist/framework/license/types.d.ts.map +1 -0
  76. package/dist/framework/license/types.js +18 -0
  77. package/dist/framework/loading/components/SkeletonGroup.d.ts +44 -0
  78. package/dist/framework/loading/components/SkeletonGroup.d.ts.map +1 -0
  79. package/dist/framework/loading/components/SkeletonGroup.js +34 -0
  80. package/dist/framework/loading/components/SuspenseWrapper.d.ts +58 -0
  81. package/dist/framework/loading/components/SuspenseWrapper.d.ts.map +1 -0
  82. package/dist/framework/loading/components/SuspenseWrapper.js +40 -0
  83. package/dist/framework/loading/hoc/withSuspense.d.ts +46 -0
  84. package/dist/framework/loading/hoc/withSuspense.d.ts.map +1 -0
  85. package/dist/framework/loading/hoc/withSuspense.js +54 -0
  86. package/dist/framework/loading/hooks/useDelayedLoading.d.ts +56 -0
  87. package/dist/framework/loading/hooks/useDelayedLoading.d.ts.map +1 -0
  88. package/dist/framework/loading/hooks/useDelayedLoading.js +97 -0
  89. package/dist/framework/loading/hooks/useLoadingState.d.ts +69 -0
  90. package/dist/framework/loading/hooks/useLoadingState.d.ts.map +1 -0
  91. package/dist/framework/loading/hooks/useLoadingState.js +59 -0
  92. package/dist/framework/loading/index.d.ts +16 -0
  93. package/dist/framework/loading/index.d.ts.map +1 -0
  94. package/dist/framework/loading/index.js +13 -0
  95. package/dist/framework/middleware/i18n.d.ts +90 -0
  96. package/dist/framework/middleware/i18n.d.ts.map +1 -0
  97. package/dist/framework/middleware/i18n.js +99 -0
  98. package/dist/framework/plugins/index.d.ts +8 -0
  99. package/dist/framework/plugins/index.d.ts.map +1 -0
  100. package/dist/framework/plugins/index.js +6 -0
  101. package/dist/framework/plugins/registry.d.ts +95 -0
  102. package/dist/framework/plugins/registry.d.ts.map +1 -0
  103. package/dist/framework/plugins/registry.js +160 -0
  104. package/dist/framework/plugins/types.d.ts +97 -0
  105. package/dist/framework/plugins/types.d.ts.map +1 -0
  106. package/dist/framework/plugins/types.js +6 -0
  107. package/dist/framework/seo/geo/examples.d.ts +87 -0
  108. package/dist/framework/seo/geo/examples.d.ts.map +1 -0
  109. package/dist/framework/seo/geo/examples.js +295 -0
  110. package/dist/framework/seo/geo/generateGEOMetadata.d.ts +107 -0
  111. package/dist/framework/seo/geo/generateGEOMetadata.d.ts.map +1 -0
  112. package/dist/framework/seo/geo/generateGEOMetadata.js +404 -0
  113. package/dist/framework/seo/geo/index.d.ts +19 -0
  114. package/dist/framework/seo/geo/index.d.ts.map +1 -0
  115. package/dist/framework/seo/geo/index.js +21 -0
  116. package/dist/framework/seo/geo/presets.d.ts +52 -0
  117. package/dist/framework/seo/geo/presets.d.ts.map +1 -0
  118. package/dist/framework/seo/geo/presets.js +47 -0
  119. package/dist/framework/seo/geo/structuredData.d.ts +187 -0
  120. package/dist/framework/seo/geo/structuredData.d.ts.map +1 -0
  121. package/dist/framework/seo/geo/structuredData.js +354 -0
  122. package/dist/framework/seo/geo/test-utils.d.ts +78 -0
  123. package/dist/framework/seo/geo/test-utils.d.ts.map +1 -0
  124. package/dist/framework/seo/geo/test-utils.js +139 -0
  125. package/dist/framework/seo/geo/types.d.ts +225 -0
  126. package/dist/framework/seo/geo/types.d.ts.map +1 -0
  127. package/dist/framework/seo/geo/types.js +51 -0
  128. package/dist/framework/types/index.d.ts +577 -0
  129. package/dist/framework/types/index.d.ts.map +1 -0
  130. package/dist/framework/types/index.js +6 -0
  131. package/dist/framework/utils/data-fetching.d.ts +45 -0
  132. package/dist/framework/utils/data-fetching.d.ts.map +1 -0
  133. package/dist/framework/utils/data-fetching.js +74 -0
  134. package/dist/framework/utils/file-structure.d.ts +29 -0
  135. package/dist/framework/utils/file-structure.d.ts.map +1 -0
  136. package/dist/framework/utils/file-structure.js +72 -0
  137. package/dist/framework/utils/metadata.d.ts +109 -0
  138. package/dist/framework/utils/metadata.d.ts.map +1 -0
  139. package/dist/framework/utils/metadata.js +105 -0
  140. package/dist/index.d.ts +15 -0
  141. package/dist/index.d.ts.map +1 -0
  142. package/dist/index.js +21 -0
  143. package/dist/presets/index.d.ts +8 -0
  144. package/dist/presets/index.d.ts.map +1 -0
  145. package/dist/presets/index.js +7 -0
  146. package/dist/presets/marketing.d.ts +41 -0
  147. package/dist/presets/marketing.d.ts.map +1 -0
  148. package/dist/presets/marketing.js +81 -0
  149. package/dist/presets/product.d.ts +41 -0
  150. package/dist/presets/product.d.ts.map +1 -0
  151. package/dist/presets/product.js +74 -0
  152. package/package.json +91 -0
  153. package/src/framework/README.md +329 -0
  154. package/src/framework/__tests__/branding/css-vars.test.ts +147 -0
  155. package/src/framework/__tests__/components/ErrorBoundary.test.tsx +146 -0
  156. package/src/framework/__tests__/config/defineConfig.test.ts +138 -0
  157. package/src/framework/__tests__/hooks/useMotion.test.ts +105 -0
  158. package/src/framework/__tests__/seo/geo/generateGEOMetadata.test.ts +207 -0
  159. package/src/framework/__tests__/seo/geo/structuredData.test.ts +262 -0
  160. package/src/framework/a11y/components/LiveRegion.tsx +89 -0
  161. package/src/framework/a11y/components/SkipToContent.tsx +103 -0
  162. package/src/framework/a11y/hooks/useFocusManagement.ts +125 -0
  163. package/src/framework/a11y/hooks/useFocusTrap.ts +239 -0
  164. package/src/framework/a11y/hooks/useLiveRegion.ts +95 -0
  165. package/src/framework/a11y/index.ts +17 -0
  166. package/src/framework/branding/context.tsx +135 -0
  167. package/src/framework/branding/css-vars.ts +110 -0
  168. package/src/framework/branding/tailwind-config.ts +90 -0
  169. package/src/framework/components/BrandedButton.tsx +94 -0
  170. package/src/framework/components/BrandedCard.tsx +87 -0
  171. package/src/framework/components/ErrorBoundary.tsx +215 -0
  172. package/src/framework/components/HuaUxLayout.tsx +36 -0
  173. package/src/framework/components/HuaUxPage.tsx +138 -0
  174. package/src/framework/components/Providers.tsx +98 -0
  175. package/src/framework/components/WelcomePage.tsx +207 -0
  176. package/src/framework/config/index.ts +349 -0
  177. package/src/framework/config/merge.ts +190 -0
  178. package/src/framework/config/schema.ts +140 -0
  179. package/src/framework/hooks/useMotion.ts +57 -0
  180. package/src/framework/index.ts +122 -0
  181. package/src/framework/license/errors.ts +63 -0
  182. package/src/framework/license/index.ts +137 -0
  183. package/src/framework/license/loader.ts +158 -0
  184. package/src/framework/license/types.ts +95 -0
  185. package/src/framework/loading/components/SkeletonGroup.tsx +70 -0
  186. package/src/framework/loading/components/SuspenseWrapper.tsx +88 -0
  187. package/src/framework/loading/hoc/withSuspense.tsx +96 -0
  188. package/src/framework/loading/hooks/useDelayedLoading.ts +127 -0
  189. package/src/framework/loading/hooks/useLoadingState.ts +103 -0
  190. package/src/framework/loading/index.ts +19 -0
  191. package/src/framework/middleware/i18n.ts +161 -0
  192. package/src/framework/middleware/index.ts +7 -0
  193. package/src/framework/plugins/index.ts +13 -0
  194. package/src/framework/plugins/registry.ts +186 -0
  195. package/src/framework/plugins/types.ts +106 -0
  196. package/src/framework/seo/geo/examples.tsx +415 -0
  197. package/src/framework/seo/geo/generateGEOMetadata.ts +441 -0
  198. package/src/framework/seo/geo/index.ts +61 -0
  199. package/src/framework/seo/geo/presets.ts +58 -0
  200. package/src/framework/seo/geo/structuredData.ts +422 -0
  201. package/src/framework/seo/geo/test-utils.ts +179 -0
  202. package/src/framework/seo/geo/types.ts +315 -0
  203. package/src/framework/types/index.ts +623 -0
  204. package/src/framework/utils/data-fetching.ts +95 -0
  205. package/src/framework/utils/file-structure.ts +88 -0
  206. package/src/framework/utils/metadata.ts +152 -0
  207. package/src/index.ts +31 -0
  208. package/src/presets/index.ts +8 -0
  209. package/src/presets/marketing.ts +88 -0
  210. 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"}