@jbpark/ui-kit 3.8.0 → 4.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (126) hide show
  1. package/dist/components/atoms/float-button/back-top.d.mts.map +1 -1
  2. package/dist/components/atoms/float-button/back-top.mjs +3 -1
  3. package/dist/components/atoms/float-button/back-top.mjs.map +1 -1
  4. package/dist/components/atoms/input/search.d.mts.map +1 -1
  5. package/dist/components/atoms/input/search.mjs +3 -1
  6. package/dist/components/atoms/input/search.mjs.map +1 -1
  7. package/dist/components/atoms/skeleton/skeleton.d.mts.map +1 -1
  8. package/dist/components/atoms/skeleton/skeleton.mjs +5 -1
  9. package/dist/components/atoms/skeleton/skeleton.mjs.map +1 -1
  10. package/dist/components/atoms/spin.d.mts.map +1 -1
  11. package/dist/components/atoms/spin.mjs +7 -2
  12. package/dist/components/atoms/spin.mjs.map +1 -1
  13. package/dist/components/organisms/drawer.d.mts.map +1 -1
  14. package/dist/components/organisms/drawer.mjs +3 -1
  15. package/dist/components/organisms/drawer.mjs.map +1 -1
  16. package/dist/components/organisms/imperative-stack.mjs +106 -0
  17. package/dist/components/organisms/imperative-stack.mjs.map +1 -0
  18. package/dist/components/organisms/index.d.mts +3 -1
  19. package/dist/components/organisms/list/index.d.mts +1 -1
  20. package/dist/components/organisms/list/index.mjs.map +1 -1
  21. package/dist/components/organisms/list/list.d.mts +2 -2
  22. package/dist/components/organisms/list/list.d.mts.map +1 -1
  23. package/dist/components/organisms/list/list.mjs +20 -11
  24. package/dist/components/organisms/list/list.mjs.map +1 -1
  25. package/dist/components/organisms/modal.d.mts +2 -2
  26. package/dist/components/organisms/modal.d.mts.map +1 -1
  27. package/dist/components/organisms/modal.mjs +21 -101
  28. package/dist/components/organisms/modal.mjs.map +1 -1
  29. package/dist/components/organisms/swiper/index.d.mts +1 -1
  30. package/dist/components/organisms/swiper/index.mjs.map +1 -1
  31. package/dist/components/organisms/swiper/swiper.d.mts +2 -1
  32. package/dist/components/organisms/swiper/swiper.d.mts.map +1 -1
  33. package/dist/components/organisms/swiper/swiper.mjs +5 -3
  34. package/dist/components/organisms/swiper/swiper.mjs.map +1 -1
  35. package/dist/components/organisms/toast.d.mts +1 -1
  36. package/dist/components/organisms/toast.d.mts.map +1 -1
  37. package/dist/components/organisms/toast.mjs +35 -111
  38. package/dist/components/organisms/toast.mjs.map +1 -1
  39. package/dist/components/templates/container.d.mts +19 -0
  40. package/dist/components/templates/container.d.mts.map +1 -0
  41. package/dist/components/templates/container.mjs +32 -0
  42. package/dist/components/templates/container.mjs.map +1 -0
  43. package/dist/components/templates/empty.d.mts +20 -0
  44. package/dist/components/templates/empty.d.mts.map +1 -0
  45. package/dist/components/templates/empty.mjs +34 -0
  46. package/dist/components/templates/empty.mjs.map +1 -0
  47. package/dist/components/templates/grid/col.d.mts +35 -0
  48. package/dist/components/templates/grid/col.d.mts.map +1 -0
  49. package/dist/components/templates/grid/col.mjs +55 -0
  50. package/dist/components/templates/grid/col.mjs.map +1 -0
  51. package/dist/components/templates/grid/index.d.mts +2 -0
  52. package/dist/components/templates/grid/row-context.mjs +13 -0
  53. package/dist/components/templates/grid/row-context.mjs.map +1 -0
  54. package/dist/components/templates/grid/row.d.mts +36 -0
  55. package/dist/components/templates/grid/row.d.mts.map +1 -0
  56. package/dist/components/templates/grid/row.mjs +54 -0
  57. package/dist/components/templates/grid/row.mjs.map +1 -0
  58. package/dist/components/templates/index.d.mts +13 -1
  59. package/dist/components/templates/layout/content.d.mts +4 -1
  60. package/dist/components/templates/layout/content.d.mts.map +1 -1
  61. package/dist/components/templates/layout/content.mjs +3 -2
  62. package/dist/components/templates/layout/content.mjs.map +1 -1
  63. package/dist/components/templates/layout/footer.d.mts +1 -1
  64. package/dist/components/templates/layout/footer.d.mts.map +1 -1
  65. package/dist/components/templates/layout/footer.mjs.map +1 -1
  66. package/dist/components/templates/layout/header.d.mts +4 -1
  67. package/dist/components/templates/layout/header.d.mts.map +1 -1
  68. package/dist/components/templates/layout/header.mjs +2 -2
  69. package/dist/components/templates/layout/header.mjs.map +1 -1
  70. package/dist/components/templates/layout/layout.d.mts +1 -1
  71. package/dist/components/templates/layout/layout.d.mts.map +1 -1
  72. package/dist/components/templates/layout/layout.mjs.map +1 -1
  73. package/dist/components/templates/layout/sider.d.mts +9 -2
  74. package/dist/components/templates/layout/sider.d.mts.map +1 -1
  75. package/dist/components/templates/layout/sider.mjs +40 -13
  76. package/dist/components/templates/layout/sider.mjs.map +1 -1
  77. package/dist/components/templates/page-header.d.mts +30 -0
  78. package/dist/components/templates/page-header.d.mts.map +1 -0
  79. package/dist/components/templates/page-header.mjs +45 -0
  80. package/dist/components/templates/page-header.mjs.map +1 -0
  81. package/dist/components/templates/result.d.mts +24 -0
  82. package/dist/components/templates/result.d.mts.map +1 -0
  83. package/dist/components/templates/result.mjs +46 -0
  84. package/dist/components/templates/result.mjs.map +1 -0
  85. package/dist/core/badge.d.mts +1 -1
  86. package/dist/core/button.d.mts +1 -1
  87. package/dist/core/dialog.d.mts.map +1 -1
  88. package/dist/core/dialog.mjs +4 -1
  89. package/dist/core/dialog.mjs.map +1 -1
  90. package/dist/core/drawer.d.mts +1 -0
  91. package/dist/core/drawer.d.mts.map +1 -1
  92. package/dist/core/drawer.mjs +4 -1
  93. package/dist/core/drawer.mjs.map +1 -1
  94. package/dist/core/popover.d.mts +4 -1
  95. package/dist/core/popover.d.mts.map +1 -1
  96. package/dist/core/popover.mjs +13 -8
  97. package/dist/core/popover.mjs.map +1 -1
  98. package/dist/core/select.d.mts +4 -1
  99. package/dist/core/select.d.mts.map +1 -1
  100. package/dist/core/select.mjs +21 -16
  101. package/dist/core/select.mjs.map +1 -1
  102. package/dist/index.d.mts +28 -15
  103. package/dist/index.mjs +9 -3
  104. package/dist/providers/{Config/index.d.mts → config/config.d.mts} +8 -4
  105. package/dist/providers/config/config.d.mts.map +1 -0
  106. package/dist/providers/{Config/index.mjs → config/config.mjs} +34 -7
  107. package/dist/providers/config/config.mjs.map +1 -0
  108. package/dist/providers/config/context.d.mts +9 -0
  109. package/dist/providers/config/context.d.mts.map +1 -0
  110. package/dist/providers/config/context.mjs +23 -0
  111. package/dist/providers/config/context.mjs.map +1 -0
  112. package/dist/providers/config/index.d.mts +3 -0
  113. package/dist/providers/{Config → config}/types.d.mts +12 -2
  114. package/dist/providers/config/types.d.mts.map +1 -0
  115. package/dist/providers.d.mts +5 -0
  116. package/dist/providers.mjs +4 -0
  117. package/dist/style.css +114 -0
  118. package/package.json +3 -3
  119. package/dist/providers/Config/context.d.mts +0 -8
  120. package/dist/providers/Config/context.d.mts.map +0 -1
  121. package/dist/providers/Config/context.mjs +0 -11
  122. package/dist/providers/Config/context.mjs.map +0 -1
  123. package/dist/providers/Config/index.d.mts.map +0 -1
  124. package/dist/providers/Config/index.mjs.map +0 -1
  125. package/dist/providers/Config/types.d.mts.map +0 -1
  126. package/dist/providers/index.d.mts +0 -3
package/dist/index.d.mts CHANGED
@@ -2,10 +2,15 @@ import Button from "./Button.mjs";
2
2
  import Tag from "./Tag.mjs";
3
3
  import Typography from "./Typography.mjs";
4
4
  import Card, { Props } from "./Card.mjs";
5
- import { Menu, Props as Props$6 } from "./components/molecules/menu/menu.mjs";
6
- import { Props as Props$7 } from "./components/molecules/reveals/reveals.mjs";
5
+ import { Menu, Props as Props$14 } from "./components/molecules/menu/menu.mjs";
6
+ import { Props as Props$18 } from "./components/molecules/reveals/reveals.mjs";
7
7
  import Reveals from "./Reveals.mjs";
8
- import Space, { Props as Props$8 } from "./Space.mjs";
8
+ import Space, { Props as Props$21 } from "./Space.mjs";
9
+ import { Props as Props$5 } from "./components/templates/layout/content.mjs";
10
+ import { Props as Props$9 } from "./components/templates/layout/footer.mjs";
11
+ import { Props as Props$10 } from "./components/templates/layout/header.mjs";
12
+ import { Props as Props$11 } from "./components/templates/layout/layout.mjs";
13
+ import { Props as Props$20 } from "./components/templates/layout/sider.mjs";
9
14
  import Layout from "./Layout.mjs";
10
15
  import { Checkbox } from "./components/atoms/checkbox/index.mjs";
11
16
  import { ColorPicker } from "./components/atoms/color-picker.mjs";
@@ -20,23 +25,31 @@ import { Skeleton } from "./components/atoms/skeleton/index.mjs";
20
25
  import { Spin } from "./components/atoms/spin.mjs";
21
26
  import { Switch } from "./components/atoms/switch.mjs";
22
27
  import "./components/atoms/index.mjs";
23
- import { Collapse, Props as Props$1 } from "./components/molecules/collapse.mjs";
24
- import { Dropdown, Props as Props$4 } from "./components/molecules/dropdown.mjs";
25
- import { Props as Props$5 } from "./components/molecules/marquees/marquees.mjs";
28
+ import { Collapse, Props as Props$2 } from "./components/molecules/collapse.mjs";
29
+ import { Dropdown, Props as Props$7 } from "./components/molecules/dropdown.mjs";
30
+ import { Props as Props$13 } from "./components/molecules/marquees/marquees.mjs";
26
31
  import { Marquees } from "./components/molecules/marquees/index.mjs";
27
- import { Props as Props$9 } from "./components/molecules/splitter/splitter.mjs";
32
+ import { Props as Props$22 } from "./components/molecules/splitter/splitter.mjs";
28
33
  import { Splitter } from "./components/molecules/splitter/index.mjs";
29
- import { Props as Props$10, Upload, UploadFile } from "./components/molecules/upload.mjs";
34
+ import { Props as Props$24, Upload, UploadFile } from "./components/molecules/upload.mjs";
30
35
  import "./components/molecules/index.mjs";
31
- import { Drawer, Props as Props$3 } from "./components/organisms/drawer.mjs";
36
+ import { Drawer, Props as Props$6 } from "./components/organisms/drawer.mjs";
37
+ import { Props as Props$12 } from "./components/organisms/list/list.mjs";
32
38
  import { List } from "./components/organisms/list/index.mjs";
33
- import { Modal } from "./components/organisms/modal.mjs";
39
+ import { Modal, Props as Props$15 } from "./components/organisms/modal.mjs";
40
+ import { Props as Props$23 } from "./components/organisms/swiper/swiper.mjs";
34
41
  import { Swiper } from "./components/organisms/swiper/index.mjs";
35
42
  import { StaticProps, Toast } from "./components/organisms/toast.mjs";
36
43
  import "./components/organisms/index.mjs";
44
+ import { Container, Props as Props$4 } from "./components/templates/container.mjs";
45
+ import { Empty, Props as Props$8 } from "./components/templates/empty.mjs";
46
+ import { Props as Props$17, Result } from "./components/templates/result.mjs";
47
+ import { PageHeader, Props as Props$16 } from "./components/templates/page-header.mjs";
48
+ import { Props as Props$19, Row } from "./components/templates/grid/row.mjs";
49
+ import { Col, Props as Props$1 } from "./components/templates/grid/col.mjs";
37
50
  import "./components/templates/index.mjs";
38
- import { ThemeConfig, ThemeToken } from "./providers/Config/types.mjs";
39
- import { useConfig } from "./providers/Config/context.mjs";
40
- import { Config, Props as Props$2 } from "./providers/Config/index.mjs";
41
- import "./providers/index.mjs";
42
- export { Button, Card, Props as CardProps, Checkbox, Collapse, Props$1 as CollapseProps, ColorPicker, Config, Props$2 as ConfigProps, DatePicker, Drawer, Props$3 as DrawerProps, Dropdown, Props$4 as DropdownProps, FloatButton, Input, Layout, List, Marquees, Props$5 as MarqueesProps, Menu, Props$6 as MenuProps, Modal, Popover, Progress, Radio, Reveals, Props$7 as RevealsProps, Select, Skeleton, Space, Props$8 as SpaceProps, Spin, Splitter, Props$9 as SplitterProps, Swiper, Switch, Tag, ThemeConfig, ThemeToken, Toast, StaticProps as ToastOptions, Typography, Upload, UploadFile, Props$10 as UploadProps, useConfig };
51
+ import { Locale, ThemeConfig, ThemeToken } from "./providers/config/types.mjs";
52
+ import { DEFAULT_LOCALE, useConfig } from "./providers/config/context.mjs";
53
+ import { Config, Props as Props$3 } from "./providers/config/config.mjs";
54
+ import "./providers.mjs";
55
+ export { Button, Card, Props as CardProps, Checkbox, Col, Props$1 as ColProps, Collapse, Props$2 as CollapseProps, ColorPicker, Config, Props$3 as ConfigProps, Container, Props$4 as ContainerProps, Props$5 as ContentProps, DEFAULT_LOCALE, DatePicker, Drawer, Props$6 as DrawerProps, Dropdown, Props$7 as DropdownProps, Empty, Props$8 as EmptyProps, FloatButton, Props$9 as FooterProps, Props$10 as HeaderProps, Input, Layout, Props$11 as LayoutProps, List, Props$12 as ListProps, Locale, Marquees, Props$13 as MarqueesProps, Menu, Props$14 as MenuProps, Modal, Props$15 as ModalProps, PageHeader, Props$16 as PageHeaderProps, Popover, Progress, Radio, Result, Props$17 as ResultProps, Reveals, Props$18 as RevealsProps, Row, Props$19 as RowProps, Select, Props$20 as SiderProps, Skeleton, Space, Props$21 as SpaceProps, Spin, Splitter, Props$22 as SplitterProps, Swiper, Props$23 as SwiperProps, Switch, Tag, ThemeConfig, ThemeToken, Toast, StaticProps as ToastOptions, Typography, Upload, UploadFile, Props$24 as UploadProps, useConfig };
package/dist/index.mjs CHANGED
@@ -1,4 +1,6 @@
1
1
  import "./style.mjs";
2
+ import { DEFAULT_LOCALE, useConfig } from "./providers/config/context.mjs";
3
+ import Config from "./providers/config/config.mjs";
2
4
  import Button from "./Button.mjs";
3
5
  import Checkbox from "./components/atoms/checkbox/index.mjs";
4
6
  import Typography from "./Typography.mjs";
@@ -29,7 +31,11 @@ import Modal from "./components/organisms/modal.mjs";
29
31
  import Swiper from "./components/organisms/swiper/index.mjs";
30
32
  import Toast from "./components/organisms/toast.mjs";
31
33
  import Layout from "./Layout.mjs";
32
- import { useConfig } from "./providers/Config/context.mjs";
33
- import Config from "./providers/Config/index.mjs";
34
+ import Container from "./components/templates/container.mjs";
35
+ import Empty from "./components/templates/empty.mjs";
36
+ import Result from "./components/templates/result.mjs";
37
+ import PageHeader from "./components/templates/page-header.mjs";
38
+ import Row from "./components/templates/grid/row.mjs";
39
+ import Col from "./components/templates/grid/col.mjs";
34
40
 
35
- export { Button, Card, Checkbox, Collapse, ColorPicker, Config, DatePicker, Drawer, Dropdown, FloatButton, Input, Layout, List, Marquees, Menu, Modal, Popover, Progress, Radio, Reveals, Select, Skeleton, Space, Spin, Splitter, Swiper, Switch, Tag, Toast, Typography, Upload, useConfig };
41
+ export { Button, Card, Checkbox, Col, Collapse, ColorPicker, Config, Container, DEFAULT_LOCALE, DatePicker, Drawer, Dropdown, Empty, FloatButton, Input, Layout, List, Marquees, Menu, Modal, PageHeader, Popover, Progress, Radio, Result, Reveals, Row, Select, Skeleton, Space, Spin, Splitter, Swiper, Switch, Tag, Toast, Typography, Upload, useConfig };
@@ -1,18 +1,22 @@
1
- import { ThemeConfig, ThemeToken } from "./types.mjs";
2
- import { useConfig } from "./context.mjs";
1
+ import { Locale, ThemeConfig, ThemeToken } from "./types.mjs";
2
+ import { DEFAULT_LOCALE, useConfig } from "./context.mjs";
3
3
  import * as react_jsx_runtime0 from "react/jsx-runtime";
4
4
 
5
- //#region src/providers/Config/index.d.ts
5
+ //#region src/providers/config/config.d.ts
6
6
  interface Props {
7
7
  theme?: ThemeConfig;
8
+ locale?: Locale;
9
+ getContainer?: () => HTMLElement;
8
10
  className?: string;
9
11
  children: React.ReactNode;
10
12
  }
11
13
  declare const Config: ({
12
14
  theme,
15
+ locale,
16
+ getContainer,
13
17
  className,
14
18
  children
15
19
  }: Props) => react_jsx_runtime0.JSX.Element;
16
20
  //#endregion
17
21
  export { Config, type Props };
18
- //# sourceMappingURL=index.d.mts.map
22
+ //# sourceMappingURL=config.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.mts","names":[],"sources":["../../../src/providers/config/config.tsx"],"mappings":";;;;;UAmDU,KAAA;EACR,KAAA,GAAQ,WAAA;EACR,MAAA,GAAS,MAAA;EACT,YAAA,SAAqB,WAAA;EACrB,SAAA;EACA,QAAA,EAAU,KAAA,CAAM,SAAA;AAAA;AAAA,cAGZ,MAAA;EAAU,KAAA;EAAA,MAAA;EAAA,YAAA;EAAA,SAAA;EAAA;AAAA,GAMb,KAAA,KAAK,kBAAA,CAAA,GAAA,CAAA,OAAA"}
@@ -1,11 +1,11 @@
1
1
  'use client';
2
2
 
3
3
  import { cn } from "../../utils.mjs";
4
- import { Context, useConfig } from "./context.mjs";
5
- import { useMemo } from "react";
4
+ import { Context, DEFAULT_LOCALE, useConfig } from "./context.mjs";
5
+ import { useCallback, useMemo, useState } from "react";
6
6
  import { jsx } from "react/jsx-runtime";
7
7
 
8
- //#region src/providers/Config/index.tsx
8
+ //#region src/providers/config/config.tsx
9
9
  const tokenToCssVar = {
10
10
  colorPrimary: "--primary",
11
11
  colorPrimaryForeground: "--primary-foreground",
@@ -37,9 +37,13 @@ const buildCssVars = (token) => {
37
37
  }
38
38
  return vars;
39
39
  };
40
- const Config = ({ theme = {}, className, children }) => {
40
+ const Config = ({ theme = {}, locale = {}, getContainer, className, children }) => {
41
41
  const parent = useConfig();
42
+ const [wrapperEl, setWrapperEl] = useState(null);
42
43
  const themeKey = JSON.stringify(theme);
44
+ const parentThemeKey = JSON.stringify(parent.theme);
45
+ const localeKey = JSON.stringify(locale);
46
+ const parentLocaleKey = JSON.stringify(parent.locale);
43
47
  const mergedTheme = useMemo(() => ({
44
48
  ...parent.theme,
45
49
  ...theme,
@@ -47,15 +51,38 @@ const Config = ({ theme = {}, className, children }) => {
47
51
  ...parent.theme.token,
48
52
  ...theme.token
49
53
  }
50
- }), [JSON.stringify(parent.theme), themeKey]);
51
- const contextValue = useMemo(() => ({ theme: mergedTheme }), [mergedTheme]);
54
+ }), [parentThemeKey, themeKey]);
55
+ const mergedLocale = useMemo(() => ({
56
+ ...parent.locale,
57
+ ...locale
58
+ }), [parentLocaleKey, localeKey]);
52
59
  const cssVars = useMemo(() => buildCssVars(mergedTheme.token), [mergedTheme.token]);
53
60
  const hasCssVars = Object.keys(cssVars).length > 0;
54
61
  const hasDarkMode = mergedTheme.dark !== void 0;
55
62
  const needsWrapper = hasCssVars || hasDarkMode || className;
63
+ const resolvedGetContainer = useCallback(() => {
64
+ if (getContainer) return getContainer();
65
+ if (needsWrapper && wrapperEl) return wrapperEl;
66
+ return parent.getContainer();
67
+ }, [
68
+ getContainer,
69
+ needsWrapper,
70
+ wrapperEl,
71
+ parent
72
+ ]);
73
+ const contextValue = useMemo(() => ({
74
+ theme: mergedTheme,
75
+ locale: mergedLocale,
76
+ getContainer: resolvedGetContainer
77
+ }), [
78
+ mergedTheme,
79
+ mergedLocale,
80
+ resolvedGetContainer
81
+ ]);
56
82
  return /* @__PURE__ */ jsx(Context.Provider, {
57
83
  value: contextValue,
58
84
  children: needsWrapper ? /* @__PURE__ */ jsx("div", {
85
+ ref: setWrapperEl,
59
86
  className: cn(mergedTheme.dark && "dark", className),
60
87
  style: {
61
88
  ...hasCssVars ? cssVars : void 0,
@@ -68,4 +95,4 @@ const Config = ({ theme = {}, className, children }) => {
68
95
 
69
96
  //#endregion
70
97
  export { Config as default };
71
- //# sourceMappingURL=index.mjs.map
98
+ //# sourceMappingURL=config.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.mjs","names":[],"sources":["../../../src/providers/config/config.tsx"],"sourcesContent":["'use client';\n\nimport { useCallback, useMemo, useState } from 'react';\n\nimport { cn } from '@repo/ui/utils';\n\nimport { Context, DEFAULT_LOCALE, useConfig } from './context';\nimport type { Locale, ThemeConfig, ThemeToken } from './types';\n\nconst tokenToCssVar: Record<keyof ThemeToken, string> = {\n colorPrimary: '--primary',\n colorPrimaryForeground: '--primary-foreground',\n colorBackground: '--background',\n colorForeground: '--foreground',\n colorCard: '--card',\n colorCardForeground: '--card-foreground',\n colorPopover: '--popover',\n colorPopoverForeground: '--popover-foreground',\n colorSecondary: '--secondary',\n colorSecondaryForeground: '--secondary-foreground',\n colorMuted: '--muted',\n colorMutedForeground: '--muted-foreground',\n colorAccent: '--accent',\n colorAccentForeground: '--accent-foreground',\n colorDestructive: '--destructive',\n colorBorder: '--border',\n colorInput: '--input',\n colorRing: '--ring',\n borderRadius: '--radius',\n};\n\nconst buildCssVars = (token?: ThemeToken): React.CSSProperties => {\n if (!token) {\n return {};\n }\n\n const vars: Record<string, string> = {};\n\n for (const [key, value] of Object.entries(token)) {\n if (value === undefined) {\n continue;\n }\n const cssVar = tokenToCssVar[key as keyof ThemeToken];\n if (cssVar) {\n vars[cssVar] = value;\n }\n }\n\n return vars as React.CSSProperties;\n};\n\ninterface Props {\n theme?: ThemeConfig;\n locale?: Locale;\n getContainer?: () => HTMLElement;\n className?: string;\n children: React.ReactNode;\n}\n\nconst Config = ({\n theme = {},\n locale = {},\n getContainer,\n className,\n children,\n}: Props) => {\n const parent = useConfig();\n const [wrapperEl, setWrapperEl] = useState<HTMLDivElement | null>(null);\n\n // `theme` is typically a fresh inline object literal at the call site\n // (and `parent.theme` inherits the same problem from its own Config\n // ancestor), so depending on them directly meant mergedTheme/contextValue\n // got a new identity on every render regardless of whether the actual\n // values changed — every useConfig() consumer in the tree re-rendered on\n // every render of whatever's above this Config, which for the common\n // app-root usage is everything. Depend on a serialized key instead so\n // the memo only invalidates when the content actually changes; these\n // are small, string/boolean-only objects, so JSON.stringify is cheap.\n const themeKey = JSON.stringify(theme);\n const parentThemeKey = JSON.stringify(parent.theme);\n const localeKey = JSON.stringify(locale);\n const parentLocaleKey = JSON.stringify(parent.locale);\n\n const mergedTheme = useMemo<ThemeConfig>(\n () => ({\n ...parent.theme,\n ...theme,\n token: {\n ...parent.theme.token,\n ...theme.token,\n },\n }),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [parentThemeKey, themeKey],\n );\n\n const mergedLocale = useMemo<Locale>(\n () => ({\n ...parent.locale,\n ...locale,\n }),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [parentLocaleKey, localeKey],\n );\n\n const cssVars = useMemo(\n () => buildCssVars(mergedTheme.token),\n [mergedTheme.token],\n );\n\n const hasCssVars = Object.keys(cssVars).length > 0;\n const hasDarkMode = mergedTheme.dark !== undefined;\n const needsWrapper = hasCssVars || hasDarkMode || className;\n\n // Resolution order: an explicit `getContainer` prop on this Config wins;\n // otherwise, if this Config renders its own themed wrapper below, that's\n // the default (portaled content appended into it still inherits its CSS\n // custom properties and matches the `.dark` selector — `display:\n // contents` only removes the element from the layout box tree, not from\n // the DOM/cascade); otherwise defer to the parent Config's resolution,\n // so an inner Config that only sets e.g. `locale` doesn't shadow an\n // outer one's theme container.\n const resolvedGetContainer = useCallback((): HTMLElement | undefined => {\n if (getContainer) {\n return getContainer();\n }\n if (needsWrapper && wrapperEl) {\n return wrapperEl;\n }\n return parent.getContainer();\n }, [getContainer, needsWrapper, wrapperEl, parent]);\n\n const contextValue = useMemo(\n () => ({\n theme: mergedTheme,\n locale: mergedLocale,\n getContainer: resolvedGetContainer,\n }),\n [mergedTheme, mergedLocale, resolvedGetContainer],\n );\n\n return (\n <Context.Provider value={contextValue}>\n {needsWrapper ? (\n <div\n ref={setWrapperEl}\n className={cn(mergedTheme.dark && 'dark', className)}\n style={{\n ...(hasCssVars ? cssVars : undefined),\n // Keeps this element out of the layout box tree — so it\n // doesn't intercept flex/grid child relationships or break\n // height chains like min-h-screen — while custom properties\n // and the `dark` class selector still cascade to children\n // normally (inheritance and box generation are separate\n // mechanisms in CSS). Note this means className shouldn't be\n // used here for anything that needs a real box (padding,\n // background, borders); Config's className is meant for\n // theming hooks (the `dark` class, arbitrary selector hooks),\n // not layout.\n display: 'contents',\n }}\n >\n {children}\n </div>\n ) : (\n children\n )}\n </Context.Provider>\n );\n};\n\nexport default Config;\nexport { useConfig, DEFAULT_LOCALE };\nexport type { Props, Locale, ThemeConfig, ThemeToken };\n"],"mappings":";;;;;;;;AASA,MAAM,gBAAkD;CACtD,cAAc;CACd,wBAAwB;CACxB,iBAAiB;CACjB,iBAAiB;CACjB,WAAW;CACX,qBAAqB;CACrB,cAAc;CACd,wBAAwB;CACxB,gBAAgB;CAChB,0BAA0B;CAC1B,YAAY;CACZ,sBAAsB;CACtB,aAAa;CACb,uBAAuB;CACvB,kBAAkB;CAClB,aAAa;CACb,YAAY;CACZ,WAAW;CACX,cAAc;CACf;AAED,MAAM,gBAAgB,UAA4C;AAChE,KAAI,CAAC,MACH,QAAO,EAAE;CAGX,MAAM,OAA+B,EAAE;AAEvC,MAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,MAAM,EAAE;AAChD,MAAI,UAAU,OACZ;EAEF,MAAM,SAAS,cAAc;AAC7B,MAAI,OACF,MAAK,UAAU;;AAInB,QAAO;;AAWT,MAAM,UAAU,EACd,QAAQ,EAAE,EACV,SAAS,EAAE,EACX,cACA,WACA,eACW;CACX,MAAM,SAAS,WAAW;CAC1B,MAAM,CAAC,WAAW,gBAAgB,SAAgC,KAAK;CAWvE,MAAM,WAAW,KAAK,UAAU,MAAM;CACtC,MAAM,iBAAiB,KAAK,UAAU,OAAO,MAAM;CACnD,MAAM,YAAY,KAAK,UAAU,OAAO;CACxC,MAAM,kBAAkB,KAAK,UAAU,OAAO,OAAO;CAErD,MAAM,cAAc,eACX;EACL,GAAG,OAAO;EACV,GAAG;EACH,OAAO;GACL,GAAG,OAAO,MAAM;GAChB,GAAG,MAAM;GACV;EACF,GAED,CAAC,gBAAgB,SAAS,CAC3B;CAED,MAAM,eAAe,eACZ;EACL,GAAG,OAAO;EACV,GAAG;EACJ,GAED,CAAC,iBAAiB,UAAU,CAC7B;CAED,MAAM,UAAU,cACR,aAAa,YAAY,MAAM,EACrC,CAAC,YAAY,MAAM,CACpB;CAED,MAAM,aAAa,OAAO,KAAK,QAAQ,CAAC,SAAS;CACjD,MAAM,cAAc,YAAY,SAAS;CACzC,MAAM,eAAe,cAAc,eAAe;CAUlD,MAAM,uBAAuB,kBAA2C;AACtE,MAAI,aACF,QAAO,cAAc;AAEvB,MAAI,gBAAgB,UAClB,QAAO;AAET,SAAO,OAAO,cAAc;IAC3B;EAAC;EAAc;EAAc;EAAW;EAAO,CAAC;CAEnD,MAAM,eAAe,eACZ;EACL,OAAO;EACP,QAAQ;EACR,cAAc;EACf,GACD;EAAC;EAAa;EAAc;EAAqB,CAClD;AAED,QACE,oBAAC,QAAQ;EAAS,OAAO;YACtB,eACC,oBAAC;GACC,KAAK;GACL,WAAW,GAAG,YAAY,QAAQ,QAAQ,UAAU;GACpD,OAAO;IACL,GAAI,aAAa,UAAU;IAW3B,SAAS;IACV;GAEA;IACG,GAEN;GAEe"}
@@ -0,0 +1,9 @@
1
+ import { ContextValue, Locale } from "./types.mjs";
2
+ import "react";
3
+
4
+ //#region src/providers/config/context.d.ts
5
+ declare const DEFAULT_LOCALE: Required<Locale>;
6
+ declare const useConfig: () => ContextValue;
7
+ //#endregion
8
+ export { DEFAULT_LOCALE, useConfig };
9
+ //# sourceMappingURL=context.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.d.mts","names":[],"sources":["../../../src/providers/config/context.ts"],"mappings":";;;;cAMa,cAAA,EAAgB,QAAA,CAAS,MAAA;AAAA,cAezB,SAAA,QAAS,YAAA"}
@@ -0,0 +1,23 @@
1
+ 'use client';
2
+
3
+ import { createContext, useContext } from "react";
4
+
5
+ //#region src/providers/config/context.ts
6
+ const DEFAULT_LOCALE = {
7
+ close: "닫기",
8
+ clear: "지우기",
9
+ backToTop: "맨 위로",
10
+ loading: "로딩 중",
11
+ expand: "펼치기",
12
+ collapse: "접기"
13
+ };
14
+ const Context = createContext({
15
+ theme: {},
16
+ locale: DEFAULT_LOCALE,
17
+ getContainer: () => void 0
18
+ });
19
+ const useConfig = () => useContext(Context);
20
+
21
+ //#endregion
22
+ export { Context, DEFAULT_LOCALE, useConfig };
23
+ //# sourceMappingURL=context.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.mjs","names":[],"sources":["../../../src/providers/config/context.ts"],"sourcesContent":["'use client';\n\nimport { createContext, useContext } from 'react';\n\nimport type { ContextValue, Locale } from './types';\n\nexport const DEFAULT_LOCALE: Required<Locale> = {\n close: '닫기',\n clear: '지우기',\n backToTop: '맨 위로',\n loading: '로딩 중',\n expand: '펼치기',\n collapse: '접기',\n};\n\nexport const Context = createContext<ContextValue>({\n theme: {},\n locale: DEFAULT_LOCALE,\n getContainer: () => undefined,\n});\n\nexport const useConfig = () => useContext(Context);\n"],"mappings":";;;;;AAMA,MAAa,iBAAmC;CAC9C,OAAO;CACP,OAAO;CACP,WAAW;CACX,SAAS;CACT,QAAQ;CACR,UAAU;CACX;AAED,MAAa,UAAU,cAA4B;CACjD,OAAO,EAAE;CACT,QAAQ;CACR,oBAAoB;CACrB,CAAC;AAEF,MAAa,kBAAkB,WAAW,QAAQ"}
@@ -0,0 +1,3 @@
1
+ import { Locale, ThemeConfig, ThemeToken } from "./types.mjs";
2
+ import { DEFAULT_LOCALE, useConfig } from "./context.mjs";
3
+ import { Config, Props } from "./config.mjs";
@@ -1,4 +1,4 @@
1
- //#region src/providers/Config/types.d.ts
1
+ //#region src/providers/config/types.d.ts
2
2
  interface ThemeToken {
3
3
  colorPrimary?: string;
4
4
  colorPrimaryForeground?: string;
@@ -24,9 +24,19 @@ interface ThemeConfig {
24
24
  token?: ThemeToken;
25
25
  dark?: boolean;
26
26
  }
27
+ interface Locale {
28
+ close?: string;
29
+ clear?: string;
30
+ backToTop?: string;
31
+ loading?: string;
32
+ expand?: string;
33
+ collapse?: string;
34
+ }
27
35
  interface ContextValue {
28
36
  theme: ThemeConfig;
37
+ locale: Locale;
38
+ getContainer: () => HTMLElement | undefined;
29
39
  }
30
40
  //#endregion
31
- export { ContextValue, ThemeConfig, ThemeToken };
41
+ export { ContextValue, Locale, ThemeConfig, ThemeToken };
32
42
  //# sourceMappingURL=types.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.mts","names":[],"sources":["../../../src/providers/config/types.ts"],"mappings":";UAAiB,UAAA;EAEf,YAAA;EACA,sBAAA;EACA,eAAA;EACA,eAAA;EACA,SAAA;EACA,mBAAA;EACA,YAAA;EACA,sBAAA;EACA,cAAA;EACA,wBAAA;EACA,UAAA;EACA,oBAAA;EACA,WAAA;EACA,qBAAA;EACA,gBAAA;EACA,WAAA;EACA,UAAA;EACA,SAAA;EAGA,YAAA;AAAA;AAAA,UAGe,WAAA;EACf,KAAA,GAAQ,UAAA;EACR,IAAA;AAAA;AAAA,UAQe,MAAA;EACf,KAAA;EACA,KAAA;EACA,SAAA;EACA,OAAA;EACA,MAAA;EACA,QAAA;AAAA;AAAA,UAGe,YAAA;EACf,KAAA,EAAO,WAAA;EACP,MAAA,EAAQ,MAAA;EAUR,YAAA,QAAoB,WAAA;AAAA"}
@@ -0,0 +1,5 @@
1
+ import { Locale, ThemeConfig, ThemeToken } from "./providers/config/types.mjs";
2
+ import { DEFAULT_LOCALE, useConfig } from "./providers/config/context.mjs";
3
+ import { Config, Props } from "./providers/config/config.mjs";
4
+ import "./providers/config/index.mjs";
5
+ export { Config, type Props as ConfigProps, DEFAULT_LOCALE, type Locale, type ThemeConfig, type ThemeToken, useConfig };
@@ -0,0 +1,4 @@
1
+ import { DEFAULT_LOCALE, useConfig } from "./providers/config/context.mjs";
2
+ import Config from "./providers/config/config.mjs";
3
+
4
+ export { Config, DEFAULT_LOCALE, useConfig };
package/dist/style.css CHANGED
@@ -14,8 +14,19 @@
14
14
  --color-black: #000;
15
15
  --color-white: #fff;
16
16
  --spacing: 0.25rem;
17
+ --container-3xs: 16rem;
18
+ --container-2xs: 18rem;
19
+ --container-xs: 20rem;
17
20
  --container-sm: 24rem;
21
+ --container-md: 28rem;
18
22
  --container-lg: 32rem;
23
+ --container-xl: 36rem;
24
+ --container-2xl: 42rem;
25
+ --container-3xl: 48rem;
26
+ --container-4xl: 56rem;
27
+ --container-5xl: 64rem;
28
+ --container-6xl: 72rem;
29
+ --container-7xl: 80rem;
19
30
  --text-xs: 0.75rem;
20
31
  --text-xs--line-height: calc(1 / 0.75);
21
32
  --text-sm: 0.875rem;
@@ -210,6 +221,9 @@
210
221
  .pointer-events-none {
211
222
  pointer-events: none;
212
223
  }
224
+ .collapse {
225
+ visibility: collapse;
226
+ }
213
227
  .invisible {
214
228
  visibility: hidden;
215
229
  }
@@ -311,6 +325,9 @@
311
325
  .z-10000 {
312
326
  z-index: 10000;
313
327
  }
328
+ .order-last {
329
+ order: 9999;
330
+ }
314
331
  .col-span-2 {
315
332
  grid-column: span 2 / span 2;
316
333
  }
@@ -356,6 +373,9 @@
356
373
  .mt-0\.5 {
357
374
  margin-top: calc(var(--spacing) * 0.5);
358
375
  }
376
+ .mt-1 {
377
+ margin-top: calc(var(--spacing) * 1);
378
+ }
359
379
  .mt-2 {
360
380
  margin-top: calc(var(--spacing) * 2);
361
381
  }
@@ -383,6 +403,9 @@
383
403
  .mr-7 {
384
404
  margin-right: calc(var(--spacing) * 7);
385
405
  }
406
+ .mb-2 {
407
+ margin-bottom: calc(var(--spacing) * 2);
408
+ }
386
409
  .mb-3 {
387
410
  margin-bottom: calc(var(--spacing) * 3);
388
411
  }
@@ -404,6 +427,9 @@
404
427
  .ml-7 {
405
428
  margin-left: calc(var(--spacing) * 7);
406
429
  }
430
+ .box-border {
431
+ box-sizing: border-box;
432
+ }
407
433
  .box-content {
408
434
  box-sizing: content-box;
409
435
  }
@@ -610,12 +636,57 @@
610
636
  .w-px {
611
637
  width: 1px;
612
638
  }
639
+ .max-w-2xl {
640
+ max-width: var(--container-2xl);
641
+ }
642
+ .max-w-2xs {
643
+ max-width: var(--container-2xs);
644
+ }
645
+ .max-w-3xl {
646
+ max-width: var(--container-3xl);
647
+ }
648
+ .max-w-3xs {
649
+ max-width: var(--container-3xs);
650
+ }
651
+ .max-w-4xl {
652
+ max-width: var(--container-4xl);
653
+ }
654
+ .max-w-5xl {
655
+ max-width: var(--container-5xl);
656
+ }
657
+ .max-w-6xl {
658
+ max-width: var(--container-6xl);
659
+ }
660
+ .max-w-7xl {
661
+ max-width: var(--container-7xl);
662
+ }
613
663
  .max-w-48 {
614
664
  max-width: calc(var(--spacing) * 48);
615
665
  }
616
666
  .max-w-\[calc\(100\%-2rem\)\] {
617
667
  max-width: calc(100% - 2rem);
618
668
  }
669
+ .max-w-full {
670
+ max-width: 100%;
671
+ }
672
+ .max-w-lg {
673
+ max-width: var(--container-lg);
674
+ }
675
+ .max-w-md {
676
+ max-width: var(--container-md);
677
+ }
678
+ .max-w-none {
679
+ max-width: none;
680
+ }
681
+ .max-w-sm {
682
+ max-width: var(--container-sm);
683
+ }
684
+ .max-w-xl {
685
+ max-width: var(--container-xl);
686
+ }
687
+ .max-w-xs {
688
+ max-width: var(--container-xs);
689
+ }
619
690
  .min-w-\(--cell-size\) {
620
691
  min-width: var(--cell-size);
621
692
  }
@@ -652,6 +723,9 @@
652
723
  .grow {
653
724
  flex-grow: 1;
654
725
  }
726
+ .grow-0 {
727
+ flex-grow: 0;
728
+ }
655
729
  .basis-auto {
656
730
  flex-basis: auto;
657
731
  }
@@ -729,6 +803,9 @@
729
803
  .cursor-pointer {
730
804
  cursor: pointer;
731
805
  }
806
+ .resize {
807
+ resize: both;
808
+ }
732
809
  .scroll-my-1 {
733
810
  scroll-margin-block: calc(var(--spacing) * 1);
734
811
  }
@@ -771,6 +848,12 @@
771
848
  .items-start {
772
849
  align-items: flex-start;
773
850
  }
851
+ .items-stretch {
852
+ align-items: stretch;
853
+ }
854
+ .justify-around {
855
+ justify-content: space-around;
856
+ }
774
857
  .justify-between {
775
858
  justify-content: space-between;
776
859
  }
@@ -780,6 +863,9 @@
780
863
  .justify-end {
781
864
  justify-content: flex-end;
782
865
  }
866
+ .justify-evenly {
867
+ justify-content: space-evenly;
868
+ }
783
869
  .justify-start {
784
870
  justify-content: flex-start;
785
871
  }
@@ -1156,6 +1242,12 @@
1156
1242
  .py-4 {
1157
1243
  padding-block: calc(var(--spacing) * 4);
1158
1244
  }
1245
+ .py-12 {
1246
+ padding-block: calc(var(--spacing) * 12);
1247
+ }
1248
+ .py-16 {
1249
+ padding-block: calc(var(--spacing) * 16);
1250
+ }
1159
1251
  .pt-0 {
1160
1252
  padding-top: calc(var(--spacing) * 0);
1161
1253
  }
@@ -2794,6 +2886,11 @@
2794
2886
  justify-content: flex-end;
2795
2887
  }
2796
2888
  }
2889
+ .sm\:px-6 {
2890
+ @media (width >= 40rem) {
2891
+ padding-inline: calc(var(--spacing) * 6);
2892
+ }
2893
+ }
2797
2894
  .sm\:text-left {
2798
2895
  @media (width >= 40rem) {
2799
2896
  text-align: left;
@@ -2870,6 +2967,11 @@
2870
2967
  line-height: var(--tw-leading, var(--text-sm--line-height));
2871
2968
  }
2872
2969
  }
2970
+ .lg\:px-8 {
2971
+ @media (width >= 64rem) {
2972
+ padding-inline: calc(var(--spacing) * 8);
2973
+ }
2974
+ }
2873
2975
  .lg\:text-2xl {
2874
2976
  @media (width >= 64rem) {
2875
2977
  font-size: var(--text-2xl);
@@ -3050,6 +3152,18 @@
3050
3152
  height: calc(var(--spacing) * 5);
3051
3153
  }
3052
3154
  }
3155
+ .\[\&_svg\]\:size-12 {
3156
+ & svg {
3157
+ width: calc(var(--spacing) * 12);
3158
+ height: calc(var(--spacing) * 12);
3159
+ }
3160
+ }
3161
+ .\[\&_svg\]\:size-16 {
3162
+ & svg {
3163
+ width: calc(var(--spacing) * 16);
3164
+ height: calc(var(--spacing) * 16);
3165
+ }
3166
+ }
3053
3167
  .\[\&_svg\]\:shrink-0 {
3054
3168
  & svg {
3055
3169
  flex-shrink: 0;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jbpark/ui-kit",
3
- "version": "3.8.0",
3
+ "version": "4.1.0",
4
4
  "description": "Modern React UI component library built with TypeScript, Tailwind CSS, and Radix UI. Featuring atoms, molecules, organisms and layout templates for building beautiful interfaces.",
5
5
  "keywords": [
6
6
  "react",
@@ -154,7 +154,7 @@
154
154
  "vaul": "^1.1.2"
155
155
  },
156
156
  "peerDependencies": {
157
- "react": "^18.0.0 || ^19.0.0",
158
- "react-dom": "^18.0.0 || ^19.0.0"
157
+ "react": "^19.0.0",
158
+ "react-dom": "^19.0.0"
159
159
  }
160
160
  }
@@ -1,8 +0,0 @@
1
- import { ContextValue } from "./types.mjs";
2
- import "react";
3
-
4
- //#region src/providers/Config/context.d.ts
5
- declare const useConfig: () => ContextValue;
6
- //#endregion
7
- export { useConfig };
8
- //# sourceMappingURL=context.d.mts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"context.d.mts","names":[],"sources":["../../../src/providers/Config/context.ts"],"mappings":";;;;cAUa,SAAA,QAAS,YAAA"}
@@ -1,11 +0,0 @@
1
- 'use client';
2
-
3
- import { createContext, useContext } from "react";
4
-
5
- //#region src/providers/Config/context.ts
6
- const Context = createContext({ theme: {} });
7
- const useConfig = () => useContext(Context);
8
-
9
- //#endregion
10
- export { Context, useConfig };
11
- //# sourceMappingURL=context.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"context.mjs","names":[],"sources":["../../../src/providers/Config/context.ts"],"sourcesContent":["'use client';\n\nimport { createContext, useContext } from 'react';\n\nimport type { ContextValue } from './types';\n\nexport const Context = createContext<ContextValue>({\n theme: {},\n});\n\nexport const useConfig = () => useContext(Context);\n"],"mappings":";;;;;AAMA,MAAa,UAAU,cAA4B,EACjD,OAAO,EAAE,EACV,CAAC;AAEF,MAAa,kBAAkB,WAAW,QAAQ"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../../../src/providers/Config/index.tsx"],"mappings":";;;;;UAmDU,KAAA;EACR,KAAA,GAAQ,WAAA;EACR,SAAA;EACA,QAAA,EAAU,KAAA,CAAM,SAAA;AAAA;AAAA,cAGZ,MAAA;EAAU,KAAA;EAAA,SAAA;EAAA;AAAA,GAAqC,KAAA,KAAK,kBAAA,CAAA,GAAA,CAAA,OAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../../src/providers/Config/index.tsx"],"sourcesContent":["'use client';\n\nimport { useMemo } from 'react';\n\nimport { cn } from '@repo/ui/utils';\n\nimport { Context, useConfig } from './context';\nimport type { ThemeConfig, ThemeToken } from './types';\n\nconst tokenToCssVar: Record<keyof ThemeToken, string> = {\n colorPrimary: '--primary',\n colorPrimaryForeground: '--primary-foreground',\n colorBackground: '--background',\n colorForeground: '--foreground',\n colorCard: '--card',\n colorCardForeground: '--card-foreground',\n colorPopover: '--popover',\n colorPopoverForeground: '--popover-foreground',\n colorSecondary: '--secondary',\n colorSecondaryForeground: '--secondary-foreground',\n colorMuted: '--muted',\n colorMutedForeground: '--muted-foreground',\n colorAccent: '--accent',\n colorAccentForeground: '--accent-foreground',\n colorDestructive: '--destructive',\n colorBorder: '--border',\n colorInput: '--input',\n colorRing: '--ring',\n borderRadius: '--radius',\n};\n\nconst buildCssVars = (token?: ThemeToken): React.CSSProperties => {\n if (!token) {\n return {};\n }\n\n const vars: Record<string, string> = {};\n\n for (const [key, value] of Object.entries(token)) {\n if (value === undefined) {\n continue;\n }\n const cssVar = tokenToCssVar[key as keyof ThemeToken];\n if (cssVar) {\n vars[cssVar] = value;\n }\n }\n\n return vars as React.CSSProperties;\n};\n\ninterface Props {\n theme?: ThemeConfig;\n className?: string;\n children: React.ReactNode;\n}\n\nconst Config = ({ theme = {}, className, children }: Props) => {\n const parent = useConfig();\n\n // `theme` is typically a fresh inline object literal at the call site\n // (and `parent.theme` inherits the same problem from its own Config\n // ancestor), so depending on them directly meant mergedTheme/contextValue\n // got a new identity on every render regardless of whether the actual\n // values changed — every useConfig() consumer in the tree re-rendered on\n // every render of whatever's above this Config, which for the common\n // app-root usage is everything. Depend on a serialized key instead so\n // the memo only invalidates when the content actually changes; these\n // are small, string/boolean-only objects, so JSON.stringify is cheap.\n const themeKey = JSON.stringify(theme);\n const parentThemeKey = JSON.stringify(parent.theme);\n\n const mergedTheme = useMemo<ThemeConfig>(\n () => ({\n ...parent.theme,\n ...theme,\n token: {\n ...parent.theme.token,\n ...theme.token,\n },\n }),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [parentThemeKey, themeKey],\n );\n\n const contextValue = useMemo(() => ({ theme: mergedTheme }), [mergedTheme]);\n\n const cssVars = useMemo(\n () => buildCssVars(mergedTheme.token),\n [mergedTheme.token],\n );\n\n const hasCssVars = Object.keys(cssVars).length > 0;\n const hasDarkMode = mergedTheme.dark !== undefined;\n const needsWrapper = hasCssVars || hasDarkMode || className;\n\n return (\n <Context.Provider value={contextValue}>\n {needsWrapper ? (\n <div\n className={cn(mergedTheme.dark && 'dark', className)}\n style={{\n ...(hasCssVars ? cssVars : undefined),\n // Keeps this element out of the layout box tree — so it\n // doesn't intercept flex/grid child relationships or break\n // height chains like min-h-screen — while custom properties\n // and the `dark` class selector still cascade to children\n // normally (inheritance and box generation are separate\n // mechanisms in CSS). Note this means className shouldn't be\n // used here for anything that needs a real box (padding,\n // background, borders); Config's className is meant for\n // theming hooks (the `dark` class, arbitrary selector hooks),\n // not layout.\n display: 'contents',\n }}\n >\n {children}\n </div>\n ) : (\n children\n )}\n </Context.Provider>\n );\n};\n\nexport default Config;\nexport { useConfig };\nexport type { Props, ThemeConfig, ThemeToken };\n"],"mappings":";;;;;;;;AASA,MAAM,gBAAkD;CACtD,cAAc;CACd,wBAAwB;CACxB,iBAAiB;CACjB,iBAAiB;CACjB,WAAW;CACX,qBAAqB;CACrB,cAAc;CACd,wBAAwB;CACxB,gBAAgB;CAChB,0BAA0B;CAC1B,YAAY;CACZ,sBAAsB;CACtB,aAAa;CACb,uBAAuB;CACvB,kBAAkB;CAClB,aAAa;CACb,YAAY;CACZ,WAAW;CACX,cAAc;CACf;AAED,MAAM,gBAAgB,UAA4C;AAChE,KAAI,CAAC,MACH,QAAO,EAAE;CAGX,MAAM,OAA+B,EAAE;AAEvC,MAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,MAAM,EAAE;AAChD,MAAI,UAAU,OACZ;EAEF,MAAM,SAAS,cAAc;AAC7B,MAAI,OACF,MAAK,UAAU;;AAInB,QAAO;;AAST,MAAM,UAAU,EAAE,QAAQ,EAAE,EAAE,WAAW,eAAsB;CAC7D,MAAM,SAAS,WAAW;CAW1B,MAAM,WAAW,KAAK,UAAU,MAAM;CAGtC,MAAM,cAAc,eACX;EACL,GAAG,OAAO;EACV,GAAG;EACH,OAAO;GACL,GAAG,OAAO,MAAM;GAChB,GAAG,MAAM;GACV;EACF,GAED,CAZqB,KAAK,UAAU,OAAO,MAAM,EAYhC,SAAS,CAC3B;CAED,MAAM,eAAe,eAAe,EAAE,OAAO,aAAa,GAAG,CAAC,YAAY,CAAC;CAE3E,MAAM,UAAU,cACR,aAAa,YAAY,MAAM,EACrC,CAAC,YAAY,MAAM,CACpB;CAED,MAAM,aAAa,OAAO,KAAK,QAAQ,CAAC,SAAS;CACjD,MAAM,cAAc,YAAY,SAAS;CACzC,MAAM,eAAe,cAAc,eAAe;AAElD,QACE,oBAAC,QAAQ;EAAS,OAAO;YACtB,eACC,oBAAC;GACC,WAAW,GAAG,YAAY,QAAQ,QAAQ,UAAU;GACpD,OAAO;IACL,GAAI,aAAa,UAAU;IAW3B,SAAS;IACV;GAEA;IACG,GAEN;GAEe"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.d.mts","names":[],"sources":["../../../src/providers/Config/types.ts"],"mappings":";UAAiB,UAAA;EAEf,YAAA;EACA,sBAAA;EACA,eAAA;EACA,eAAA;EACA,SAAA;EACA,mBAAA;EACA,YAAA;EACA,sBAAA;EACA,cAAA;EACA,wBAAA;EACA,UAAA;EACA,oBAAA;EACA,WAAA;EACA,qBAAA;EACA,gBAAA;EACA,WAAA;EACA,UAAA;EACA,SAAA;EAGA,YAAA;AAAA;AAAA,UAGe,WAAA;EACf,KAAA,GAAQ,UAAA;EACR,IAAA;AAAA;AAAA,UAGe,YAAA;EACf,KAAA,EAAO,WAAA;AAAA"}
@@ -1,3 +0,0 @@
1
- import { ThemeConfig, ThemeToken } from "./Config/types.mjs";
2
- import { useConfig } from "./Config/context.mjs";
3
- import { Config, Props } from "./Config/index.mjs";