@jbpark/ui-kit 3.8.0 → 4.0.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 (101) 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/index.d.mts +28 -15
  86. package/dist/index.mjs +9 -3
  87. package/dist/providers/Config/context.d.mts +3 -2
  88. package/dist/providers/Config/context.d.mts.map +1 -1
  89. package/dist/providers/Config/context.mjs +13 -2
  90. package/dist/providers/Config/context.mjs.map +1 -1
  91. package/dist/providers/Config/index.d.mts +4 -2
  92. package/dist/providers/Config/index.d.mts.map +1 -1
  93. package/dist/providers/Config/index.mjs +14 -4
  94. package/dist/providers/Config/index.mjs.map +1 -1
  95. package/dist/providers/Config/types.d.mts +10 -1
  96. package/dist/providers/Config/types.d.mts.map +1 -1
  97. package/dist/providers.d.mts +4 -0
  98. package/dist/providers.mjs +4 -0
  99. package/dist/style.css +114 -0
  100. package/package.json +3 -3
  101. package/dist/providers/index.d.mts +0 -3
@@ -0,0 +1,20 @@
1
+ import * as react_jsx_runtime0 from "react/jsx-runtime";
2
+
3
+ //#region src/components/templates/empty.d.ts
4
+ interface Props extends Omit<React.ComponentProps<'div'>, 'title'> {
5
+ icon?: React.ReactNode;
6
+ title?: React.ReactNode;
7
+ description?: React.ReactNode;
8
+ action?: React.ReactNode;
9
+ }
10
+ declare const Empty: ({
11
+ icon,
12
+ title,
13
+ description,
14
+ action,
15
+ className,
16
+ ...props
17
+ }: Props) => react_jsx_runtime0.JSX.Element;
18
+ //#endregion
19
+ export { Empty, Props };
20
+ //# sourceMappingURL=empty.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"empty.d.mts","names":[],"sources":["../../../src/components/templates/empty.tsx"],"mappings":";;;UAIiB,KAAA,SAAc,IAAA,CAAK,KAAA,CAAM,cAAA;EACxC,IAAA,GAAO,KAAA,CAAM,SAAA;EACb,KAAA,GAAQ,KAAA,CAAM,SAAA;EACd,WAAA,GAAc,KAAA,CAAM,SAAA;EACpB,MAAA,GAAS,KAAA,CAAM,SAAA;AAAA;AAAA,cAQX,KAAA;EAAS,IAAA;EAAA,KAAA;EAAA,WAAA;EAAA,MAAA;EAAA,SAAA;EAAA,GAAA;AAAA,GAOZ,KAAA,KAAK,kBAAA,CAAA,GAAA,CAAA,OAAA"}
@@ -0,0 +1,34 @@
1
+ import { cn } from "../../utils.mjs";
2
+ import { Inbox } from "lucide-react";
3
+ import { jsx, jsxs } from "react/jsx-runtime";
4
+
5
+ //#region src/components/templates/empty.tsx
6
+ const Empty = ({ icon, title, description = "No data", action, className, ...props }) => {
7
+ return /* @__PURE__ */ jsxs("div", {
8
+ role: "status",
9
+ className: cn("flex flex-col items-center justify-center gap-3 py-12 text-center", className),
10
+ ...props,
11
+ children: [
12
+ /* @__PURE__ */ jsx("div", {
13
+ className: "text-muted-foreground [&_svg]:size-12",
14
+ children: icon ?? /* @__PURE__ */ jsx(Inbox, {})
15
+ }),
16
+ title && /* @__PURE__ */ jsx("p", {
17
+ className: "text-sm font-medium",
18
+ children: title
19
+ }),
20
+ description && /* @__PURE__ */ jsx("p", {
21
+ className: "text-muted-foreground text-sm",
22
+ children: description
23
+ }),
24
+ action && /* @__PURE__ */ jsx("div", {
25
+ className: "mt-1",
26
+ children: action
27
+ })
28
+ ]
29
+ });
30
+ };
31
+
32
+ //#endregion
33
+ export { Empty as default };
34
+ //# sourceMappingURL=empty.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"empty.mjs","names":[],"sources":["../../../src/components/templates/empty.tsx"],"sourcesContent":["import { Inbox } from 'lucide-react';\n\nimport { cn } from '@repo/ui/utils';\n\nexport interface Props extends Omit<React.ComponentProps<'div'>, 'title'> {\n icon?: React.ReactNode;\n title?: React.ReactNode;\n description?: React.ReactNode;\n action?: React.ReactNode;\n}\n\n// The counterpart List's `empty` prop was asking for — List/Upload/Swiper\n// each render arbitrary content for their empty state today with nothing\n// in the library actually meant to go there. Pairs with Skeleton the same\n// way Skeleton pairs with real content: one placeholder for \"nothing\n// loaded yet\", one for \"loaded, and there's nothing\".\nconst Empty = ({\n icon,\n title,\n description = 'No data',\n action,\n className,\n ...props\n}: Props) => {\n return (\n <div\n role=\"status\"\n className={cn(\n 'flex flex-col items-center justify-center gap-3 py-12 text-center',\n className,\n //\n )}\n {...props}\n >\n <div className=\"text-muted-foreground [&_svg]:size-12\">\n {icon ?? <Inbox />}\n </div>\n {title && <p className=\"text-sm font-medium\">{title}</p>}\n {description && (\n <p className=\"text-muted-foreground text-sm\">{description}</p>\n )}\n {action && <div className=\"mt-1\">{action}</div>}\n </div>\n );\n};\n\nexport default Empty;\n"],"mappings":";;;;;AAgBA,MAAM,SAAS,EACb,MACA,OACA,cAAc,WACd,QACA,WACA,GAAG,YACQ;AACX,QACE,qBAAC;EACC,MAAK;EACL,WAAW,GACT,qEACA,UAED;EACD,GAAI;;GAEJ,oBAAC;IAAI,WAAU;cACZ,QAAQ,oBAAC,UAAQ;KACd;GACL,SAAS,oBAAC;IAAE,WAAU;cAAuB;KAAU;GACvD,eACC,oBAAC;IAAE,WAAU;cAAiC;KAAgB;GAE/D,UAAU,oBAAC;IAAI,WAAU;cAAQ;KAAa;;GAC3C"}
@@ -0,0 +1,35 @@
1
+ import * as react_jsx_runtime0 from "react/jsx-runtime";
2
+
3
+ //#region src/components/templates/grid/col.d.ts
4
+ interface ResponsiveColSpan {
5
+ span?: number;
6
+ offset?: number;
7
+ }
8
+ type ColSpanProp = number | ResponsiveColSpan;
9
+ interface Props extends React.ComponentProps<'div'> {
10
+ span?: number;
11
+ offset?: number;
12
+ xs?: ColSpanProp;
13
+ sm?: ColSpanProp;
14
+ md?: ColSpanProp;
15
+ lg?: ColSpanProp;
16
+ xl?: ColSpanProp;
17
+ '2xl'?: ColSpanProp;
18
+ }
19
+ declare const Col: ({
20
+ span,
21
+ offset,
22
+ xs,
23
+ sm,
24
+ md,
25
+ lg,
26
+ xl,
27
+ "2xl": xxl,
28
+ className,
29
+ style,
30
+ children,
31
+ ...props
32
+ }: Props) => react_jsx_runtime0.JSX.Element;
33
+ //#endregion
34
+ export { Col, Props };
35
+ //# sourceMappingURL=col.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"col.d.mts","names":[],"sources":["../../../../src/components/templates/grid/col.tsx"],"mappings":";;;UAUU,iBAAA;EACR,IAAA;EACA,MAAA;AAAA;AAAA,KAGG,WAAA,YAAuB,iBAAA;AAAA,UAEX,KAAA,SAAc,KAAA,CAAM,cAAA;EACnC,IAAA;EACA,MAAA;EACA,EAAA,GAAK,WAAA;EACL,EAAA,GAAK,WAAA;EACL,EAAA,GAAK,WAAA;EACL,EAAA,GAAK,WAAA;EACL,EAAA,GAAK,WAAA;EACL,KAAA,GAAQ,WAAA;AAAA;AAAA,cAaJ,GAAA;EAAO,IAAA;EAAA,MAAA;EAAA,EAAA;EAAA,EAAA;EAAA,EAAA;EAAA,EAAA;EAAA,EAAA;EAAA,OAAA,GAAA;EAAA,SAAA;EAAA,KAAA;EAAA,QAAA;EAAA,GAAA;AAAA,GAaV,KAAA,KAAK,kBAAA,CAAA,GAAA,CAAA,OAAA"}
@@ -0,0 +1,55 @@
1
+ 'use client';
2
+
3
+ import { cn } from "../../../utils.mjs";
4
+ import { useRowContext } from "./row-context.mjs";
5
+ import { jsx } from "react/jsx-runtime";
6
+
7
+ //#region src/components/templates/grid/col.tsx
8
+ const TOTAL_COLUMNS = 24;
9
+ const BREAKPOINT_ORDER = [
10
+ "xs",
11
+ "sm",
12
+ "md",
13
+ "lg",
14
+ "xl",
15
+ "2xl"
16
+ ];
17
+ const resolveColSpan = (value) => typeof value === "number" ? { span: value } : value;
18
+ const Col = ({ span = TOTAL_COLUMNS, offset = 0, xs, sm, md, lg, xl, "2xl": xxl, className, style, children, ...props }) => {
19
+ const { gutterX, breakpoint } = useRowContext();
20
+ const responsiveProps = {
21
+ xs,
22
+ sm,
23
+ md,
24
+ lg,
25
+ xl,
26
+ "2xl": xxl
27
+ };
28
+ let effectiveSpan = span;
29
+ let effectiveOffset = offset;
30
+ for (const bp of BREAKPOINT_ORDER) {
31
+ if (BREAKPOINT_ORDER.indexOf(bp) > BREAKPOINT_ORDER.indexOf(breakpoint)) break;
32
+ const resolved = resolveColSpan(responsiveProps[bp]);
33
+ if (resolved?.span !== void 0) effectiveSpan = resolved.span;
34
+ if (resolved?.offset !== void 0) effectiveOffset = resolved.offset;
35
+ }
36
+ const widthPercent = effectiveSpan / TOTAL_COLUMNS * 100;
37
+ const offsetPercent = effectiveOffset / TOTAL_COLUMNS * 100;
38
+ return /* @__PURE__ */ jsx("div", {
39
+ className: cn("box-border shrink-0 grow-0", className),
40
+ style: {
41
+ flexBasis: `${widthPercent}%`,
42
+ maxWidth: `${widthPercent}%`,
43
+ marginLeft: offsetPercent ? `${offsetPercent}%` : void 0,
44
+ paddingLeft: gutterX ? gutterX / 2 : void 0,
45
+ paddingRight: gutterX ? gutterX / 2 : void 0,
46
+ ...style
47
+ },
48
+ ...props,
49
+ children
50
+ });
51
+ };
52
+
53
+ //#endregion
54
+ export { Col as default };
55
+ //# sourceMappingURL=col.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"col.mjs","names":[],"sources":["../../../../src/components/templates/grid/col.tsx"],"sourcesContent":["'use client';\n\nimport { cn } from '@repo/ui/utils';\n\nimport { type Breakpoint, useRowContext } from './row-context';\n\nconst TOTAL_COLUMNS = 24;\n\nconst BREAKPOINT_ORDER: Breakpoint[] = ['xs', 'sm', 'md', 'lg', 'xl', '2xl'];\n\ninterface ResponsiveColSpan {\n span?: number;\n offset?: number;\n}\n\ntype ColSpanProp = number | ResponsiveColSpan;\n\nexport interface Props extends React.ComponentProps<'div'> {\n span?: number;\n offset?: number;\n xs?: ColSpanProp;\n sm?: ColSpanProp;\n md?: ColSpanProp;\n lg?: ColSpanProp;\n xl?: ColSpanProp;\n '2xl'?: ColSpanProp;\n}\n\nconst resolveColSpan = (value: ColSpanProp | undefined) =>\n typeof value === 'number' ? { span: value } : value;\n\n// 24-column system (matches Ant Design's Row/Col, a familiar mental model\n// for anyone coming from it) implemented with plain percentage widths\n// rather than Tailwind's col-span-* utilities — those utilities need a\n// literal, statically-scannable class per (breakpoint, span) combination,\n// and 6 breakpoints x 24 spans is 144 combinations, most of which would\n// never be used. Percentage math scales to any span/breakpoint\n// combination with one code path instead.\nconst Col = ({\n span = TOTAL_COLUMNS,\n offset = 0,\n xs,\n sm,\n md,\n lg,\n xl,\n '2xl': xxl,\n className,\n style,\n children,\n ...props\n}: Props) => {\n const { gutterX, breakpoint } = useRowContext();\n\n const responsiveProps: Partial<Record<Breakpoint, ColSpanProp | undefined>> =\n { xs, sm, md, lg, xl, '2xl': xxl };\n\n let effectiveSpan = span;\n let effectiveOffset = offset;\n\n // Mobile-first cascade: walk breakpoints up to (and including) the\n // current one, letting each defined prop override the last — so\n // `<Col span={24} md={12} />` is 24 below md and 12 from md upward, with\n // no need to also specify lg/xl/2xl for the value to keep applying.\n for (const bp of BREAKPOINT_ORDER) {\n if (BREAKPOINT_ORDER.indexOf(bp) > BREAKPOINT_ORDER.indexOf(breakpoint)) {\n break;\n }\n\n const resolved = resolveColSpan(responsiveProps[bp]);\n\n if (resolved?.span !== undefined) {\n effectiveSpan = resolved.span;\n }\n if (resolved?.offset !== undefined) {\n effectiveOffset = resolved.offset;\n }\n }\n\n const widthPercent = (effectiveSpan / TOTAL_COLUMNS) * 100;\n const offsetPercent = (effectiveOffset / TOTAL_COLUMNS) * 100;\n\n return (\n <div\n className={cn('box-border shrink-0 grow-0', className)}\n style={{\n flexBasis: `${widthPercent}%`,\n maxWidth: `${widthPercent}%`,\n marginLeft: offsetPercent ? `${offsetPercent}%` : undefined,\n paddingLeft: gutterX ? gutterX / 2 : undefined,\n paddingRight: gutterX ? gutterX / 2 : undefined,\n ...style,\n }}\n {...props}\n >\n {children}\n </div>\n );\n};\n\nexport default Col;\n"],"mappings":";;;;;;;AAMA,MAAM,gBAAgB;AAEtB,MAAM,mBAAiC;CAAC;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;AAoB5E,MAAM,kBAAkB,UACtB,OAAO,UAAU,WAAW,EAAE,MAAM,OAAO,GAAG;AAShD,MAAM,OAAO,EACX,OAAO,eACP,SAAS,GACT,IACA,IACA,IACA,IACA,IACA,OAAO,KACP,WACA,OACA,UACA,GAAG,YACQ;CACX,MAAM,EAAE,SAAS,eAAe,eAAe;CAE/C,MAAM,kBACJ;EAAE;EAAI;EAAI;EAAI;EAAI;EAAI,OAAO;EAAK;CAEpC,IAAI,gBAAgB;CACpB,IAAI,kBAAkB;AAMtB,MAAK,MAAM,MAAM,kBAAkB;AACjC,MAAI,iBAAiB,QAAQ,GAAG,GAAG,iBAAiB,QAAQ,WAAW,CACrE;EAGF,MAAM,WAAW,eAAe,gBAAgB,IAAI;AAEpD,MAAI,UAAU,SAAS,OACrB,iBAAgB,SAAS;AAE3B,MAAI,UAAU,WAAW,OACvB,mBAAkB,SAAS;;CAI/B,MAAM,eAAgB,gBAAgB,gBAAiB;CACvD,MAAM,gBAAiB,kBAAkB,gBAAiB;AAE1D,QACE,oBAAC;EACC,WAAW,GAAG,8BAA8B,UAAU;EACtD,OAAO;GACL,WAAW,GAAG,aAAa;GAC3B,UAAU,GAAG,aAAa;GAC1B,YAAY,gBAAgB,GAAG,cAAc,KAAK;GAClD,aAAa,UAAU,UAAU,IAAI;GACrC,cAAc,UAAU,UAAU,IAAI;GACtC,GAAG;GACJ;EACD,GAAI;EAEH;GACG"}
@@ -0,0 +1,2 @@
1
+ import { Props, Row } from "./row.mjs";
2
+ import { Col, Props as Props$1 } from "./col.mjs";
@@ -0,0 +1,13 @@
1
+ import { createContext, useContext } from "react";
2
+
3
+ //#region src/components/templates/grid/row-context.ts
4
+ const RowContext = createContext({
5
+ gutterX: 0,
6
+ gutterY: 0,
7
+ breakpoint: "xs"
8
+ });
9
+ const useRowContext = () => useContext(RowContext);
10
+
11
+ //#endregion
12
+ export { RowContext, useRowContext };
13
+ //# sourceMappingURL=row-context.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"row-context.mjs","names":[],"sources":["../../../../src/components/templates/grid/row-context.ts"],"sourcesContent":["import { createContext, useContext } from 'react';\n\nexport type Breakpoint = 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl';\n\nexport interface RowContextValue {\n gutterX: number;\n gutterY: number;\n breakpoint: Breakpoint;\n}\n\n// Defaults assume Col is used without a Row (not the intended usage, but\n// shouldn't crash) — 'xs' matches useResponsiveSize's own SSR-safe initial\n// guess (measures 0 width before mount), same mobile-first default Sider's\n// breakpoint feature already relies on.\nexport const RowContext = createContext<RowContextValue>({\n gutterX: 0,\n gutterY: 0,\n breakpoint: 'xs',\n});\n\nexport const useRowContext = () => useContext(RowContext);\n"],"mappings":";;;AAcA,MAAa,aAAa,cAA+B;CACvD,SAAS;CACT,SAAS;CACT,YAAY;CACb,CAAC;AAEF,MAAa,sBAAsB,WAAW,WAAW"}
@@ -0,0 +1,36 @@
1
+ import * as react_jsx_runtime0 from "react/jsx-runtime";
2
+
3
+ //#region src/components/templates/grid/row.d.ts
4
+ declare const ALIGN_CLASSES: {
5
+ top: string;
6
+ middle: string;
7
+ bottom: string;
8
+ stretch: string;
9
+ };
10
+ declare const JUSTIFY_CLASSES: {
11
+ start: string;
12
+ end: string;
13
+ center: string;
14
+ 'space-around': string;
15
+ 'space-between': string;
16
+ 'space-evenly': string;
17
+ };
18
+ interface Props extends React.ComponentProps<'div'> {
19
+ gutter?: number | [number, number];
20
+ align?: keyof typeof ALIGN_CLASSES;
21
+ justify?: keyof typeof JUSTIFY_CLASSES;
22
+ wrap?: boolean;
23
+ }
24
+ declare const Row: ({
25
+ gutter,
26
+ align,
27
+ justify,
28
+ wrap,
29
+ className,
30
+ style,
31
+ children,
32
+ ...props
33
+ }: Props) => react_jsx_runtime0.JSX.Element;
34
+ //#endregion
35
+ export { Props, Row };
36
+ //# sourceMappingURL=row.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"row.d.mts","names":[],"sources":["../../../../src/components/templates/grid/row.tsx"],"mappings":";;;cAUM,aAAA;;;;;;cAOA,eAAA;;;;;;;;UASW,KAAA,SAAc,KAAA,CAAM,cAAA;EACnC,MAAA;EACA,KAAA,gBAAqB,aAAA;EACrB,OAAA,gBAAuB,eAAA;EACvB,IAAA;AAAA;AAAA,cAMI,GAAA;EAAO,MAAA;EAAA,KAAA;EAAA,OAAA;EAAA,IAAA;EAAA,SAAA;EAAA,KAAA;EAAA,QAAA;EAAA,GAAA;AAAA,GASV,KAAA,KAAK,kBAAA,CAAA,GAAA,CAAA,OAAA"}
@@ -0,0 +1,54 @@
1
+ 'use client';
2
+
3
+ import { cn } from "../../../utils.mjs";
4
+ import { RowContext } from "./row-context.mjs";
5
+ import { useMemo } from "react";
6
+ import { jsx } from "react/jsx-runtime";
7
+ import { useResponsiveSize } from "@jbpark/use-hooks";
8
+
9
+ //#region src/components/templates/grid/row.tsx
10
+ const ALIGN_CLASSES = {
11
+ top: "items-start",
12
+ middle: "items-center",
13
+ bottom: "items-end",
14
+ stretch: "items-stretch"
15
+ };
16
+ const JUSTIFY_CLASSES = {
17
+ start: "justify-start",
18
+ end: "justify-end",
19
+ center: "justify-center",
20
+ "space-around": "justify-around",
21
+ "space-between": "justify-between",
22
+ "space-evenly": "justify-evenly"
23
+ };
24
+ const Row = ({ gutter = 0, align, justify, wrap = true, className, style, children, ...props }) => {
25
+ const [gutterX, gutterY] = Array.isArray(gutter) ? gutter : [gutter, 0];
26
+ const { breakpoint } = useResponsiveSize({ viewport: true });
27
+ const contextValue = useMemo(() => ({
28
+ gutterX,
29
+ gutterY,
30
+ breakpoint: breakpoint.current
31
+ }), [
32
+ gutterX,
33
+ gutterY,
34
+ breakpoint
35
+ ]);
36
+ return /* @__PURE__ */ jsx(RowContext.Provider, {
37
+ value: contextValue,
38
+ children: /* @__PURE__ */ jsx("div", {
39
+ className: cn("flex", wrap && "flex-wrap", align && ALIGN_CLASSES[align], justify && JUSTIFY_CLASSES[justify], className),
40
+ style: {
41
+ marginLeft: gutterX ? -gutterX / 2 : void 0,
42
+ marginRight: gutterX ? -gutterX / 2 : void 0,
43
+ rowGap: gutterY || void 0,
44
+ ...style
45
+ },
46
+ ...props,
47
+ children
48
+ })
49
+ });
50
+ };
51
+
52
+ //#endregion
53
+ export { Row as default };
54
+ //# sourceMappingURL=row.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"row.mjs","names":[],"sources":["../../../../src/components/templates/grid/row.tsx"],"sourcesContent":["'use client';\n\nimport { useMemo } from 'react';\n\nimport { useResponsiveSize } from '@jbpark/use-hooks';\n\nimport { cn } from '@repo/ui/utils';\n\nimport { RowContext } from './row-context';\n\nconst ALIGN_CLASSES = {\n top: 'items-start',\n middle: 'items-center',\n bottom: 'items-end',\n stretch: 'items-stretch',\n};\n\nconst JUSTIFY_CLASSES = {\n start: 'justify-start',\n end: 'justify-end',\n center: 'justify-center',\n 'space-around': 'justify-around',\n 'space-between': 'justify-between',\n 'space-evenly': 'justify-evenly',\n};\n\nexport interface Props extends React.ComponentProps<'div'> {\n gutter?: number | [number, number];\n align?: keyof typeof ALIGN_CLASSES;\n justify?: keyof typeof JUSTIFY_CLASSES;\n wrap?: boolean;\n}\n\n// The breakpoint tier is resolved once here (not per-Col) so N columns\n// share a single resize listener instead of each mounting its own via\n// useResponsiveSize — matters once a grid has more than a couple Cols.\nconst Row = ({\n gutter = 0,\n align,\n justify,\n wrap = true,\n className,\n style,\n children,\n ...props\n}: Props) => {\n const [gutterX, gutterY] = Array.isArray(gutter) ? gutter : [gutter, 0];\n const { breakpoint } = useResponsiveSize({ viewport: true });\n\n const contextValue = useMemo(\n () => ({ gutterX, gutterY, breakpoint: breakpoint.current }),\n [gutterX, gutterY, breakpoint],\n );\n\n return (\n <RowContext.Provider value={contextValue}>\n <div\n className={cn(\n 'flex',\n wrap && 'flex-wrap',\n align && ALIGN_CLASSES[align],\n justify && JUSTIFY_CLASSES[justify],\n className,\n //\n )}\n style={{\n // Negative margin + Col's matching padding is the classic\n // gutter technique — unlike a plain `gap`, it doesn't break the\n // percentage-width math when several Cols are meant to sum to\n // exactly 100% of the row. Vertical gutter has no such\n // constraint (it only affects spacing *between* wrapped rows),\n // so it uses native `row-gap` directly.\n marginLeft: gutterX ? -gutterX / 2 : undefined,\n marginRight: gutterX ? -gutterX / 2 : undefined,\n rowGap: gutterY || undefined,\n ...style,\n }}\n {...props}\n >\n {children}\n </div>\n </RowContext.Provider>\n );\n};\n\nexport default Row;\n"],"mappings":";;;;;;;;;AAUA,MAAM,gBAAgB;CACpB,KAAK;CACL,QAAQ;CACR,QAAQ;CACR,SAAS;CACV;AAED,MAAM,kBAAkB;CACtB,OAAO;CACP,KAAK;CACL,QAAQ;CACR,gBAAgB;CAChB,iBAAiB;CACjB,gBAAgB;CACjB;AAYD,MAAM,OAAO,EACX,SAAS,GACT,OACA,SACA,OAAO,MACP,WACA,OACA,UACA,GAAG,YACQ;CACX,MAAM,CAAC,SAAS,WAAW,MAAM,QAAQ,OAAO,GAAG,SAAS,CAAC,QAAQ,EAAE;CACvE,MAAM,EAAE,eAAe,kBAAkB,EAAE,UAAU,MAAM,CAAC;CAE5D,MAAM,eAAe,eACZ;EAAE;EAAS;EAAS,YAAY,WAAW;EAAS,GAC3D;EAAC;EAAS;EAAS;EAAW,CAC/B;AAED,QACE,oBAAC,WAAW;EAAS,OAAO;YAC1B,oBAAC;GACC,WAAW,GACT,QACA,QAAQ,aACR,SAAS,cAAc,QACvB,WAAW,gBAAgB,UAC3B,UAED;GACD,OAAO;IAOL,YAAY,UAAU,CAAC,UAAU,IAAI;IACrC,aAAa,UAAU,CAAC,UAAU,IAAI;IACtC,QAAQ,WAAW;IACnB,GAAG;IACJ;GACD,GAAI;GAEH;IACG;GACc"}
@@ -1 +1,13 @@
1
- import Layout from "../../Layout.mjs";
1
+ import { Props } from "./layout/content.mjs";
2
+ import { Props as Props$1 } from "./layout/footer.mjs";
3
+ import { Props as Props$2 } from "./layout/header.mjs";
4
+ import { Props as Props$3 } from "./layout/layout.mjs";
5
+ import { Props as Props$4 } from "./layout/sider.mjs";
6
+ import Layout from "../../Layout.mjs";
7
+ import { Container, Props as Props$5 } from "./container.mjs";
8
+ import { Empty, Props as Props$6 } from "./empty.mjs";
9
+ import { Props as Props$7, Result } from "./result.mjs";
10
+ import { PageHeader, Props as Props$8 } from "./page-header.mjs";
11
+ import { Props as Props$9, Row } from "./grid/row.mjs";
12
+ import { Col, Props as Props$10 } from "./grid/col.mjs";
13
+ import "./grid/index.mjs";
@@ -1,10 +1,13 @@
1
1
  import * as react_jsx_runtime0 from "react/jsx-runtime";
2
2
 
3
3
  //#region src/components/templates/layout/content.d.ts
4
- interface Props extends React.ComponentPropsWithoutRef<'main'> {}
4
+ interface Props extends React.ComponentProps<'main'> {
5
+ asChild?: boolean;
6
+ }
5
7
  declare const Content: ({
6
8
  children,
7
9
  className,
10
+ asChild,
8
11
  ...props
9
12
  }: Props) => react_jsx_runtime0.JSX.Element;
10
13
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"content.d.mts","names":[],"sources":["../../../../src/components/templates/layout/content.tsx"],"mappings":";;;UAEiB,KAAA,SAAc,KAAA,CAAM,wBAAA;AAAA,cAE/B,OAAA;EAAW,QAAA;EAAA,SAAA;EAAA,GAAA;AAAA,GAAmC,KAAA,KAAK,kBAAA,CAAA,GAAA,CAAA,OAAA"}
1
+ {"version":3,"file":"content.d.mts","names":[],"sources":["../../../../src/components/templates/layout/content.tsx"],"mappings":";;;UAIiB,KAAA,SAAc,KAAA,CAAM,cAAA;EACnC,OAAA;AAAA;AAAA,cAGI,OAAA;EAAW,QAAA;EAAA,SAAA;EAAA,OAAA;EAAA,GAAA;AAAA,GAAoD,KAAA,KAAK,kBAAA,CAAA,GAAA,CAAA,OAAA"}
@@ -1,9 +1,10 @@
1
1
  import { cn } from "../../../utils.mjs";
2
2
  import { jsx } from "react/jsx-runtime";
3
+ import { Slot } from "@radix-ui/react-slot";
3
4
 
4
5
  //#region src/components/templates/layout/content.tsx
5
- const Content = ({ children, className, ...props }) => {
6
- return /* @__PURE__ */ jsx("main", {
6
+ const Content = ({ children, className, asChild = false, ...props }) => {
7
+ return /* @__PURE__ */ jsx(asChild ? Slot : "main", {
7
8
  className: cn("min-w-0 shrink grow basis-auto", className),
8
9
  ...props,
9
10
  children
@@ -1 +1 @@
1
- {"version":3,"file":"content.mjs","names":[],"sources":["../../../../src/components/templates/layout/content.tsx"],"sourcesContent":["import { cn } from '@repo/ui/utils';\n\nexport interface Props extends React.ComponentPropsWithoutRef<'main'> {}\n\nconst Content = ({ children, className, ...props }: Props) => {\n return (\n <main\n className={cn(\n 'min-w-0 shrink grow basis-auto',\n // basis-auto (not basis-0) sizes Content from its actual content\n // height first, so flex-grow only adds extra space when content is\n // shorter than the viewport — when content is taller, Content\n // keeps its natural (larger) height instead of clipping to\n // available space and pushes Footer below it. min-h-0 is\n // intentionally omitted here: with basis-auto, the default\n // min-height:auto (content-based) is what makes that possible; on\n // the Sider row's cross axis it's harmless since min-height there\n // governs stretch, not main-axis growth.\n className,\n )}\n {...props}\n >\n {children}\n </main>\n );\n};\n\nexport default Content;\n"],"mappings":";;;;AAIA,MAAM,WAAW,EAAE,UAAU,WAAW,GAAG,YAAmB;AAC5D,QACE,oBAAC;EACC,WAAW,GACT,kCAUA,UACD;EACD,GAAI;EAEH;GACI"}
1
+ {"version":3,"file":"content.mjs","names":[],"sources":["../../../../src/components/templates/layout/content.tsx"],"sourcesContent":["import { Slot } from '@radix-ui/react-slot';\n\nimport { cn } from '@repo/ui/utils';\n\nexport interface Props extends React.ComponentProps<'main'> {\n asChild?: boolean;\n}\n\nconst Content = ({ children, className, asChild = false, ...props }: Props) => {\n // Only one <main> landmark should exist per page — a Layout nested\n // inside a page that already has its own <main> (or a Content nested\n // inside another Content) needs a way to opt out of rendering a second\n // one. asChild + Slot (same pattern as core/button.tsx and\n // core/badge.tsx) merges these props/classes onto the caller's own\n // element instead.\n const Comp = asChild ? Slot : 'main';\n\n return (\n <Comp\n className={cn(\n 'min-w-0 shrink grow basis-auto',\n // basis-auto (not basis-0) sizes Content from its actual content\n // height first, so flex-grow only adds extra space when content is\n // shorter than the viewport — when content is taller, Content\n // keeps its natural (larger) height instead of clipping to\n // available space and pushes Footer below it. min-h-0 is\n // intentionally omitted here: with basis-auto, the default\n // min-height:auto (content-based) is what makes that possible; on\n // the Sider row's cross axis it's harmless since min-height there\n // governs stretch, not main-axis growth.\n className,\n )}\n {...props}\n >\n {children}\n </Comp>\n );\n};\n\nexport default Content;\n"],"mappings":";;;;;AAQA,MAAM,WAAW,EAAE,UAAU,WAAW,UAAU,OAAO,GAAG,YAAmB;AAS7E,QACE,oBAHW,UAAU,OAAO;EAI1B,WAAW,GACT,kCAUA,UACD;EACD,GAAI;EAEH;GACI"}
@@ -1,7 +1,7 @@
1
1
  import * as react_jsx_runtime0 from "react/jsx-runtime";
2
2
 
3
3
  //#region src/components/templates/layout/footer.d.ts
4
- interface Props extends React.ComponentPropsWithoutRef<'footer'> {}
4
+ interface Props extends React.ComponentProps<'footer'> {}
5
5
  declare const Footer: ({
6
6
  children,
7
7
  className,
@@ -1 +1 @@
1
- {"version":3,"file":"footer.d.mts","names":[],"sources":["../../../../src/components/templates/layout/footer.tsx"],"mappings":";;;UAEiB,KAAA,SAAc,KAAA,CAAM,wBAAA;AAAA,cAE/B,MAAA;EAAU,QAAA;EAAA,SAAA;EAAA,GAAA;AAAA,GAAmC,KAAA,KAAK,kBAAA,CAAA,GAAA,CAAA,OAAA"}
1
+ {"version":3,"file":"footer.d.mts","names":[],"sources":["../../../../src/components/templates/layout/footer.tsx"],"mappings":";;;UAEiB,KAAA,SAAc,KAAA,CAAM,cAAA;AAAA,cAE/B,MAAA;EAAU,QAAA;EAAA,SAAA;EAAA,GAAA;AAAA,GAAmC,KAAA,KAAK,kBAAA,CAAA,GAAA,CAAA,OAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"footer.mjs","names":[],"sources":["../../../../src/components/templates/layout/footer.tsx"],"sourcesContent":["import { cn } from '@repo/ui/utils';\n\nexport interface Props extends React.ComponentPropsWithoutRef<'footer'> {}\n\nconst Footer = ({ children, className, ...props }: Props) => {\n return (\n <footer className={cn('w-full', className)} {...props}>\n {children}\n </footer>\n );\n};\n\nexport default Footer;\n"],"mappings":";;;;AAIA,MAAM,UAAU,EAAE,UAAU,WAAW,GAAG,YAAmB;AAC3D,QACE,oBAAC;EAAO,WAAW,GAAG,UAAU,UAAU;EAAE,GAAI;EAC7C;GACM"}
1
+ {"version":3,"file":"footer.mjs","names":[],"sources":["../../../../src/components/templates/layout/footer.tsx"],"sourcesContent":["import { cn } from '@repo/ui/utils';\n\nexport interface Props extends React.ComponentProps<'footer'> {}\n\nconst Footer = ({ children, className, ...props }: Props) => {\n return (\n <footer className={cn('w-full', className)} {...props}>\n {children}\n </footer>\n );\n};\n\nexport default Footer;\n"],"mappings":";;;;AAIA,MAAM,UAAU,EAAE,UAAU,WAAW,GAAG,YAAmB;AAC3D,QACE,oBAAC;EAAO,WAAW,GAAG,UAAU,UAAU;EAAE,GAAI;EAC7C;GACM"}
@@ -1,10 +1,13 @@
1
1
  import * as react_jsx_runtime0 from "react/jsx-runtime";
2
2
 
3
3
  //#region src/components/templates/layout/header.d.ts
4
- interface Props extends React.ComponentPropsWithoutRef<'header'> {}
4
+ interface Props extends React.ComponentProps<'header'> {
5
+ position?: 'sticky' | 'static' | 'fixed';
6
+ }
5
7
  declare const Header: ({
6
8
  children,
7
9
  className,
10
+ position,
8
11
  ...props
9
12
  }: Props) => react_jsx_runtime0.JSX.Element;
10
13
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"header.d.mts","names":[],"sources":["../../../../src/components/templates/layout/header.tsx"],"mappings":";;;UAEiB,KAAA,SAAc,KAAA,CAAM,wBAAA;AAAA,cAE/B,MAAA;EAAU,QAAA;EAAA,SAAA;EAAA,GAAA;AAAA,GAAmC,KAAA,KAAK,kBAAA,CAAA,GAAA,CAAA,OAAA"}
1
+ {"version":3,"file":"header.d.mts","names":[],"sources":["../../../../src/components/templates/layout/header.tsx"],"mappings":";;;UAEiB,KAAA,SAAc,KAAA,CAAM,cAAA;EACnC,QAAA;AAAA;AAAA,cAGI,MAAA;EAAU,QAAA;EAAA,SAAA;EAAA,QAAA;EAAA,GAAA;AAAA,GAKb,KAAA,KAAK,kBAAA,CAAA,GAAA,CAAA,OAAA"}
@@ -2,9 +2,9 @@ import { cn } from "../../../utils.mjs";
2
2
  import { jsx } from "react/jsx-runtime";
3
3
 
4
4
  //#region src/components/templates/layout/header.tsx
5
- const Header = ({ children, className, ...props }) => {
5
+ const Header = ({ children, className, position = "sticky", ...props }) => {
6
6
  return /* @__PURE__ */ jsx("header", {
7
- className: cn("sticky top-0 z-50", "bg-background", "flex h-16 w-full items-center px-5", className),
7
+ className: cn(position === "sticky" && "sticky top-0 z-50", position === "fixed" && "fixed inset-x-0 top-0 z-50", "bg-background", "flex h-16 w-full items-center px-5", className),
8
8
  ...props,
9
9
  children
10
10
  });
@@ -1 +1 @@
1
- {"version":3,"file":"header.mjs","names":[],"sources":["../../../../src/components/templates/layout/header.tsx"],"sourcesContent":["import { cn } from '@repo/ui/utils';\n\nexport interface Props extends React.ComponentPropsWithoutRef<'header'> {}\n\nconst Header = ({ children, className, ...props }: Props) => {\n return (\n <header\n className={cn(\n 'sticky top-0 z-50',\n 'bg-background',\n 'flex h-16 w-full items-center px-5',\n className,\n //\n )}\n {...props}\n >\n {children}\n </header>\n );\n};\n\nexport default Header;\n"],"mappings":";;;;AAIA,MAAM,UAAU,EAAE,UAAU,WAAW,GAAG,YAAmB;AAC3D,QACE,oBAAC;EACC,WAAW,GACT,qBACA,iBACA,sCACA,UAED;EACD,GAAI;EAEH;GACM"}
1
+ {"version":3,"file":"header.mjs","names":[],"sources":["../../../../src/components/templates/layout/header.tsx"],"sourcesContent":["import { cn } from '@repo/ui/utils';\n\nexport interface Props extends React.ComponentProps<'header'> {\n position?: 'sticky' | 'static' | 'fixed';\n}\n\nconst Header = ({\n children,\n className,\n position = 'sticky',\n ...props\n}: Props) => {\n return (\n <header\n className={cn(\n position === 'sticky' && 'sticky top-0 z-50',\n position === 'fixed' && 'fixed inset-x-0 top-0 z-50',\n 'bg-background',\n 'flex h-16 w-full items-center px-5',\n className,\n //\n )}\n {...props}\n >\n {children}\n </header>\n );\n};\n\nexport default Header;\n"],"mappings":";;;;AAMA,MAAM,UAAU,EACd,UACA,WACA,WAAW,UACX,GAAG,YACQ;AACX,QACE,oBAAC;EACC,WAAW,GACT,aAAa,YAAY,qBACzB,aAAa,WAAW,8BACxB,iBACA,sCACA,UAED;EACD,GAAI;EAEH;GACM"}
@@ -1,7 +1,7 @@
1
1
  import * as react_jsx_runtime0 from "react/jsx-runtime";
2
2
 
3
3
  //#region src/components/templates/layout/layout.d.ts
4
- interface Props extends React.ComponentPropsWithoutRef<'div'> {}
4
+ interface Props extends React.ComponentProps<'div'> {}
5
5
  declare const Layout: ({
6
6
  children,
7
7
  className,
@@ -1 +1 @@
1
- {"version":3,"file":"layout.d.mts","names":[],"sources":["../../../../src/components/templates/layout/layout.tsx"],"mappings":";;;UAciB,KAAA,SAAc,KAAA,CAAM,wBAAA;AAAA,cAgB/B,MAAA;EAAU,QAAA;EAAA,SAAA;EAAA,GAAA;AAAA,GAAmC,KAAA,KAAK,kBAAA,CAAA,GAAA,CAAA,OAAA"}
1
+ {"version":3,"file":"layout.d.mts","names":[],"sources":["../../../../src/components/templates/layout/layout.tsx"],"mappings":";;;UAciB,KAAA,SAAc,KAAA,CAAM,cAAA;AAAA,cAgB/B,MAAA;EAAU,QAAA;EAAA,SAAA;EAAA,GAAA;AAAA,GAAmC,KAAA,KAAK,kBAAA,CAAA,GAAA,CAAA,OAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"layout.mjs","names":[],"sources":["../../../../src/components/templates/layout/layout.tsx"],"sourcesContent":["import {\n Children,\n createContext,\n isValidElement,\n useContext,\n useMemo,\n useState,\n} from 'react';\n\nimport { cn } from '@repo/ui/utils';\n\nimport Sider from './sider';\nimport { SiderRegistryContext } from './sider-context';\n\nexport interface Props extends React.ComponentPropsWithoutRef<'div'> {}\n\nconst LayoutNestedContext = createContext(false);\n\n// Effects (including the registry-based detection in sider-context.ts)\n// never run during SSR, so registry state alone would render flex-col on\n// the server and every first paint, then flip to flex-row after hydration\n// for even the common, non-wrapped case. This direct-children check seeds\n// the correct initial guess for that common case so it's right immediately;\n// the registry then stays authoritative for Fragment-wrapped/custom-wrapped\n// Siders it can't see, correcting the guess after mount if needed.\nconst hasDirectSiderChild = (children: React.ReactNode) =>\n Children.toArray(children).some(\n child => isValidElement(child) && child.type === Sider,\n );\n\nconst Layout = ({ children, className, ...props }: Props) => {\n const isNested = useContext(LayoutNestedContext);\n const [siderIds] = useState(() => new Set<object>());\n const [siderCount, setSiderCount] = useState(() =>\n hasDirectSiderChild(children) ? 1 : 0,\n );\n\n const registry = useMemo(\n () => ({\n registerSider: (id: object) => {\n siderIds.add(id);\n setSiderCount(siderIds.size);\n },\n unregisterSider: (id: object) => {\n siderIds.delete(id);\n setSiderCount(siderIds.size);\n },\n }),\n [siderIds],\n );\n\n const isRow = siderCount > 0;\n\n return (\n <LayoutNestedContext.Provider value>\n <SiderRegistryContext.Provider value={registry}>\n <div\n className={cn(\n 'flex w-full flex-1',\n // A nested Layout (the Sider row wrapper) must stay free to\n // shrink/grow inside its parent's flex column, so it keeps\n // min-h-0. The outermost Layout has no ancestor to size against,\n // so it needs its own height anchor or flex-1/grow are no-ops\n // and Content collapses under Footer.\n isNested ? 'min-h-0' : 'min-h-screen',\n isRow ? 'flex-row' : 'flex-col',\n className,\n )}\n {...props}\n >\n {children}\n </div>\n </SiderRegistryContext.Provider>\n </LayoutNestedContext.Provider>\n );\n};\n\nexport default Layout;\n"],"mappings":";;;;;;;AAgBA,MAAM,sBAAsB,cAAc,MAAM;AAShD,MAAM,uBAAuB,aAC3B,SAAS,QAAQ,SAAS,CAAC,MACzB,UAAS,eAAe,MAAM,IAAI,MAAM,SAAS,MAClD;AAEH,MAAM,UAAU,EAAE,UAAU,WAAW,GAAG,YAAmB;CAC3D,MAAM,WAAW,WAAW,oBAAoB;CAChD,MAAM,CAAC,YAAY,+BAAe,IAAI,KAAa,CAAC;CACpD,MAAM,CAAC,YAAY,iBAAiB,eAClC,oBAAoB,SAAS,GAAG,IAAI,EACrC;CAED,MAAM,WAAW,eACR;EACL,gBAAgB,OAAe;AAC7B,YAAS,IAAI,GAAG;AAChB,iBAAc,SAAS,KAAK;;EAE9B,kBAAkB,OAAe;AAC/B,YAAS,OAAO,GAAG;AACnB,iBAAc,SAAS,KAAK;;EAE/B,GACD,CAAC,SAAS,CACX;CAED,MAAM,QAAQ,aAAa;AAE3B,QACE,oBAAC,oBAAoB;EAAS;YAC5B,oBAAC,qBAAqB;GAAS,OAAO;aACpC,oBAAC;IACC,WAAW,GACT,sBAMA,WAAW,YAAY,gBACvB,QAAQ,aAAa,YACrB,UACD;IACD,GAAI;IAEH;KACG;IACwB;GACH"}
1
+ {"version":3,"file":"layout.mjs","names":[],"sources":["../../../../src/components/templates/layout/layout.tsx"],"sourcesContent":["import {\n Children,\n createContext,\n isValidElement,\n useContext,\n useMemo,\n useState,\n} from 'react';\n\nimport { cn } from '@repo/ui/utils';\n\nimport Sider from './sider';\nimport { SiderRegistryContext } from './sider-context';\n\nexport interface Props extends React.ComponentProps<'div'> {}\n\nconst LayoutNestedContext = createContext(false);\n\n// Effects (including the registry-based detection in sider-context.ts)\n// never run during SSR, so registry state alone would render flex-col on\n// the server and every first paint, then flip to flex-row after hydration\n// for even the common, non-wrapped case. This direct-children check seeds\n// the correct initial guess for that common case so it's right immediately;\n// the registry then stays authoritative for Fragment-wrapped/custom-wrapped\n// Siders it can't see, correcting the guess after mount if needed.\nconst hasDirectSiderChild = (children: React.ReactNode) =>\n Children.toArray(children).some(\n child => isValidElement(child) && child.type === Sider,\n );\n\nconst Layout = ({ children, className, ...props }: Props) => {\n const isNested = useContext(LayoutNestedContext);\n const [siderIds] = useState(() => new Set<object>());\n const [siderCount, setSiderCount] = useState(() =>\n hasDirectSiderChild(children) ? 1 : 0,\n );\n\n const registry = useMemo(\n () => ({\n registerSider: (id: object) => {\n siderIds.add(id);\n setSiderCount(siderIds.size);\n },\n unregisterSider: (id: object) => {\n siderIds.delete(id);\n setSiderCount(siderIds.size);\n },\n }),\n [siderIds],\n );\n\n const isRow = siderCount > 0;\n\n return (\n <LayoutNestedContext.Provider value>\n <SiderRegistryContext.Provider value={registry}>\n <div\n className={cn(\n 'flex w-full flex-1',\n // A nested Layout (the Sider row wrapper) must stay free to\n // shrink/grow inside its parent's flex column, so it keeps\n // min-h-0. The outermost Layout has no ancestor to size against,\n // so it needs its own height anchor or flex-1/grow are no-ops\n // and Content collapses under Footer.\n isNested ? 'min-h-0' : 'min-h-screen',\n isRow ? 'flex-row' : 'flex-col',\n className,\n )}\n {...props}\n >\n {children}\n </div>\n </SiderRegistryContext.Provider>\n </LayoutNestedContext.Provider>\n );\n};\n\nexport default Layout;\n"],"mappings":";;;;;;;AAgBA,MAAM,sBAAsB,cAAc,MAAM;AAShD,MAAM,uBAAuB,aAC3B,SAAS,QAAQ,SAAS,CAAC,MACzB,UAAS,eAAe,MAAM,IAAI,MAAM,SAAS,MAClD;AAEH,MAAM,UAAU,EAAE,UAAU,WAAW,GAAG,YAAmB;CAC3D,MAAM,WAAW,WAAW,oBAAoB;CAChD,MAAM,CAAC,YAAY,+BAAe,IAAI,KAAa,CAAC;CACpD,MAAM,CAAC,YAAY,iBAAiB,eAClC,oBAAoB,SAAS,GAAG,IAAI,EACrC;CAED,MAAM,WAAW,eACR;EACL,gBAAgB,OAAe;AAC7B,YAAS,IAAI,GAAG;AAChB,iBAAc,SAAS,KAAK;;EAE9B,kBAAkB,OAAe;AAC/B,YAAS,OAAO,GAAG;AACnB,iBAAc,SAAS,KAAK;;EAE/B,GACD,CAAC,SAAS,CACX;CAED,MAAM,QAAQ,aAAa;AAE3B,QACE,oBAAC,oBAAoB;EAAS;YAC5B,oBAAC,qBAAqB;GAAS,OAAO;aACpC,oBAAC;IACC,WAAW,GACT,sBAMA,WAAW,YAAY,gBACvB,QAAQ,aAAa,YACrB,UACD;IACD,GAAI;IAEH;KACG;IACwB;GACH"}
@@ -1,18 +1,22 @@
1
1
  import * as react_jsx_runtime0 from "react/jsx-runtime";
2
2
 
3
3
  //#region src/components/templates/layout/sider.d.ts
4
- interface Props extends Omit<React.ComponentPropsWithoutRef<'aside'>, 'onCollapse'> {
4
+ type Breakpoint = 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl';
5
+ interface Props extends Omit<React.ComponentProps<'aside'>, 'onCollapse'> {
5
6
  width?: number | string;
6
7
  collapsedWidth?: number | string;
7
8
  collapsible?: boolean;
8
9
  defaultCollapsed?: boolean;
9
10
  collapsed?: boolean;
11
+ placement?: 'left' | 'right';
10
12
  reverseArrow?: boolean;
11
13
  trigger?: React.ReactNode;
12
14
  classNames?: {
13
15
  trigger?: string;
14
16
  };
17
+ breakpoint?: Breakpoint;
15
18
  onCollapse?: (collapsed: boolean) => void;
19
+ onBreakpoint?: (broken: boolean) => void;
16
20
  }
17
21
  declare const Sider: ({
18
22
  children,
@@ -24,9 +28,12 @@ declare const Sider: ({
24
28
  collapsible,
25
29
  defaultCollapsed,
26
30
  collapsed: _collapsed,
31
+ placement,
27
32
  reverseArrow,
28
33
  trigger,
29
- onCollapse: _onCollapse,
34
+ breakpoint,
35
+ onCollapse,
36
+ onBreakpoint,
30
37
  ...props
31
38
  }: Props) => react_jsx_runtime0.JSX.Element;
32
39
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"sider.d.mts","names":[],"sources":["../../../../src/components/templates/layout/sider.tsx"],"mappings":";;;UAUiB,KAAA,SAAc,IAAA,CAC7B,KAAA,CAAM,wBAAA;EAGN,KAAA;EACA,cAAA;EACA,WAAA;EACA,gBAAA;EACA,SAAA;EACA,YAAA;EACA,OAAA,GAAU,KAAA,CAAM,SAAA;EAChB,UAAA;IACE,OAAA;EAAA;EAEF,UAAA,IAAc,SAAA;AAAA;AAAA,cAMV,KAAA;EAAS,QAAA;EAAA,SAAA;EAAA,UAAA;EAAA,KAAA;EAAA,KAAA;EAAA,cAAA;EAAA,WAAA;EAAA,gBAAA;EAAA,SAAA,EAAA,UAAA;EAAA,YAAA;EAAA,OAAA;EAAA,UAAA,EAAA,WAAA;EAAA,GAAA;AAAA,GAcZ,KAAA,KAAK,kBAAA,CAAA,GAAA,CAAA,OAAA"}
1
+ {"version":3,"file":"sider.d.mts","names":[],"sources":["../../../../src/components/templates/layout/sider.tsx"],"mappings":";;;KAYK,UAAA;AAAA,UAQY,KAAA,SAAc,IAAA,CAC7B,KAAA,CAAM,cAAA;EAGN,KAAA;EACA,cAAA;EACA,WAAA;EACA,gBAAA;EACA,SAAA;EACA,SAAA;EACA,YAAA;EACA,OAAA,GAAU,KAAA,CAAM,SAAA;EAChB,UAAA;IACE,OAAA;EAAA;EAEF,UAAA,GAAa,UAAA;EACb,UAAA,IAAc,SAAA;EACd,YAAA,IAAgB,MAAA;AAAA;AAAA,cAMZ,KAAA;EAAS,QAAA;EAAA,SAAA;EAAA,UAAA;EAAA,KAAA;EAAA,KAAA;EAAA,cAAA;EAAA,WAAA;EAAA,gBAAA;EAAA,SAAA,EAAA,UAAA;EAAA,SAAA;EAAA,YAAA;EAAA,OAAA;EAAA,UAAA;EAAA,UAAA;EAAA,YAAA;EAAA,GAAA;AAAA,GAiBZ,KAAA,KAAK,kBAAA,CAAA,GAAA,CAAA,OAAA"}
@@ -1,38 +1,65 @@
1
1
  'use client';
2
2
 
3
3
  import { cn } from "../../../utils.mjs";
4
+ import { DEFAULT_LOCALE, useConfig } from "../../../providers/Config/context.mjs";
4
5
  import { useRegisterSider } from "./sider-context.mjs";
5
6
  import { PanelLeftClose, PanelLeftOpen } from "lucide-react";
6
- import { useState } from "react";
7
+ import { useId, useLayoutEffect } from "react";
7
8
  import { jsx, jsxs } from "react/jsx-runtime";
9
+ import { useControllableState, useResponsiveSize } from "@jbpark/use-hooks";
8
10
 
9
11
  //#region src/components/templates/layout/sider.tsx
12
+ const BREAKPOINT_ORDER = [
13
+ "xs",
14
+ "sm",
15
+ "md",
16
+ "lg",
17
+ "xl",
18
+ "2xl"
19
+ ];
10
20
  const toCssSize = (value) => typeof value === "number" ? `${value}px` : value;
11
- const Sider = ({ children, className, classNames, style, width = 200, collapsedWidth = 80, collapsible = false, defaultCollapsed = false, collapsed: _collapsed, reverseArrow = false, trigger, onCollapse: _onCollapse = () => {}, ...props }) => {
21
+ const Sider = ({ children, className, classNames, style, width = 200, collapsedWidth = 80, collapsible = false, defaultCollapsed = false, collapsed: _collapsed, placement = "left", reverseArrow = false, trigger, breakpoint, onCollapse, onBreakpoint, ...props }) => {
12
22
  useRegisterSider();
13
- const [uncontrolledCollapsed, setUncontrolledCollapsed] = useState(defaultCollapsed);
14
- const controlled = _collapsed !== void 0;
15
- const collapsed = controlled ? _collapsed : uncontrolledCollapsed;
16
- const onCollapse = () => {
17
- const next = !collapsed;
18
- if (!controlled) setUncontrolledCollapsed(next);
19
- _onCollapse(next);
23
+ const { locale } = useConfig();
24
+ const contentId = useId();
25
+ const [collapsed, setCollapsed] = useControllableState({
26
+ value: _collapsed,
27
+ defaultValue: defaultCollapsed,
28
+ onChange: onCollapse
29
+ });
30
+ const { breakpoint: viewportBreakpoint } = useResponsiveSize({ viewport: true });
31
+ const broken = breakpoint ? BREAKPOINT_ORDER.indexOf(viewportBreakpoint.current) < BREAKPOINT_ORDER.indexOf(breakpoint) : false;
32
+ useLayoutEffect(() => {
33
+ if (!breakpoint) return;
34
+ setCollapsed(broken);
35
+ onBreakpoint?.(broken);
36
+ }, [
37
+ broken,
38
+ breakpoint,
39
+ setCollapsed,
40
+ onBreakpoint
41
+ ]);
42
+ const onTriggerClick = () => {
43
+ setCollapsed(!collapsed);
20
44
  };
21
- const TriggerIcon = collapsed !== reverseArrow ? PanelLeftOpen : PanelLeftClose;
45
+ const TriggerIcon = collapsed !== (reverseArrow !== (placement === "right")) ? PanelLeftOpen : PanelLeftClose;
22
46
  return /* @__PURE__ */ jsxs("aside", {
23
- className: cn("z-10 flex h-full shrink-0 flex-col overflow-hidden", "transition-[width] duration-200", className),
47
+ className: cn("z-10 flex h-full shrink-0 flex-col overflow-hidden", "transition-[width] duration-200", placement === "right" && "order-last", className),
24
48
  style: {
25
49
  width: toCssSize(collapsed ? collapsedWidth : width),
26
50
  ...style
27
51
  },
28
52
  ...props,
29
53
  children: [/* @__PURE__ */ jsx("div", {
54
+ id: contentId,
30
55
  className: "min-h-0 flex-1 overflow-auto",
31
56
  children
32
57
  }), collapsible && /* @__PURE__ */ jsx("button", {
33
58
  type: "button",
34
- "aria-label": collapsed ? "펼치기" : "접기",
35
- onClick: onCollapse,
59
+ "aria-label": collapsed ? locale.expand ?? DEFAULT_LOCALE.expand : locale.collapse ?? DEFAULT_LOCALE.collapse,
60
+ "aria-expanded": !collapsed,
61
+ "aria-controls": contentId,
62
+ onClick: onTriggerClick,
36
63
  className: cn("flex w-full shrink-0 items-center justify-center py-2", "cursor-pointer transition-colors hover:bg-black/5", classNames?.trigger),
37
64
  children: trigger === void 0 ? /* @__PURE__ */ jsx(TriggerIcon, { className: "size-4" }) : trigger
38
65
  })]
@@ -1 +1 @@
1
- {"version":3,"file":"sider.mjs","names":[],"sources":["../../../../src/components/templates/layout/sider.tsx"],"sourcesContent":["'use client';\n\nimport { useState } from 'react';\n\nimport { PanelLeftClose, PanelLeftOpen } from 'lucide-react';\n\nimport { cn } from '@repo/ui/utils';\n\nimport { useRegisterSider } from './sider-context';\n\nexport interface Props extends Omit<\n React.ComponentPropsWithoutRef<'aside'>,\n 'onCollapse'\n> {\n width?: number | string;\n collapsedWidth?: number | string;\n collapsible?: boolean;\n defaultCollapsed?: boolean;\n collapsed?: boolean;\n reverseArrow?: boolean;\n trigger?: React.ReactNode;\n classNames?: {\n trigger?: string;\n };\n onCollapse?: (collapsed: boolean) => void;\n}\n\nconst toCssSize = (value: number | string) =>\n typeof value === 'number' ? `${value}px` : value;\n\nconst Sider = ({\n children,\n className,\n classNames,\n style,\n width = 200,\n collapsedWidth = 80,\n collapsible = false,\n defaultCollapsed = false,\n collapsed: _collapsed,\n reverseArrow = false,\n trigger,\n onCollapse: _onCollapse = () => {},\n ...props\n}: Props) => {\n useRegisterSider();\n\n const [uncontrolledCollapsed, setUncontrolledCollapsed] =\n useState(defaultCollapsed);\n\n const controlled = _collapsed !== undefined;\n const collapsed = controlled ? _collapsed : uncontrolledCollapsed;\n\n const onCollapse = () => {\n const next = !collapsed;\n\n if (!controlled) {\n setUncontrolledCollapsed(next);\n }\n _onCollapse(next);\n };\n\n const TriggerIcon =\n collapsed !== reverseArrow ? PanelLeftOpen : PanelLeftClose;\n\n return (\n <aside\n className={cn(\n // Below Header's z-50 (and every other floating/overlay primitive\n // in this library, which all use z-50) — Sider is a static layout\n // column, not floating chrome, and previously outranked Header\n // with an arbitrary z-100, covering it once Header stuck to the\n // viewport top on scroll.\n 'z-10 flex h-full shrink-0 flex-col overflow-hidden',\n 'transition-[width] duration-200',\n className,\n //\n )}\n style={{\n width: toCssSize(collapsed ? collapsedWidth : width),\n ...style,\n }}\n {...props}\n >\n <div className=\"min-h-0 flex-1 overflow-auto\">{children}</div>\n {collapsible && (\n <button\n type=\"button\"\n aria-label={collapsed ? '펼치기' : '접기'}\n onClick={onCollapse}\n className={cn(\n 'flex w-full shrink-0 items-center justify-center py-2',\n 'cursor-pointer transition-colors hover:bg-black/5',\n classNames?.trigger,\n //\n )}\n >\n {trigger === undefined ? <TriggerIcon className=\"size-4\" /> : trigger}\n </button>\n )}\n </aside>\n );\n};\n\nexport default Sider;\n"],"mappings":";;;;;;;;;AA2BA,MAAM,aAAa,UACjB,OAAO,UAAU,WAAW,GAAG,MAAM,MAAM;AAE7C,MAAM,SAAS,EACb,UACA,WACA,YACA,OACA,QAAQ,KACR,iBAAiB,IACjB,cAAc,OACd,mBAAmB,OACnB,WAAW,YACX,eAAe,OACf,SACA,YAAY,oBAAoB,IAChC,GAAG,YACQ;AACX,mBAAkB;CAElB,MAAM,CAAC,uBAAuB,4BAC5B,SAAS,iBAAiB;CAE5B,MAAM,aAAa,eAAe;CAClC,MAAM,YAAY,aAAa,aAAa;CAE5C,MAAM,mBAAmB;EACvB,MAAM,OAAO,CAAC;AAEd,MAAI,CAAC,WACH,0BAAyB,KAAK;AAEhC,cAAY,KAAK;;CAGnB,MAAM,cACJ,cAAc,eAAe,gBAAgB;AAE/C,QACE,qBAAC;EACC,WAAW,GAMT,sDACA,mCACA,UAED;EACD,OAAO;GACL,OAAO,UAAU,YAAY,iBAAiB,MAAM;GACpD,GAAG;GACJ;EACD,GAAI;aAEJ,oBAAC;GAAI,WAAU;GAAgC;IAAe,EAC7D,eACC,oBAAC;GACC,MAAK;GACL,cAAY,YAAY,QAAQ;GAChC,SAAS;GACT,WAAW,GACT,yDACA,qDACA,YAAY,QAEb;aAEA,YAAY,SAAY,oBAAC,eAAY,WAAU,WAAW,GAAG;IACvD;GAEL"}
1
+ {"version":3,"file":"sider.mjs","names":[],"sources":["../../../../src/components/templates/layout/sider.tsx"],"sourcesContent":["'use client';\n\nimport { useId, useLayoutEffect } from 'react';\n\nimport { useControllableState, useResponsiveSize } from '@jbpark/use-hooks';\nimport { PanelLeftClose, PanelLeftOpen } from 'lucide-react';\n\nimport { DEFAULT_LOCALE, useConfig } from '@repo/ui/providers';\nimport { cn } from '@repo/ui/utils';\n\nimport { useRegisterSider } from './sider-context';\n\ntype Breakpoint = 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl';\n\n// Order matters here, not the values — used to compare the current\n// viewport tier against the configured `breakpoint` ordinally, since\n// `useResponsiveSize` reports which named tier the viewport is currently\n// in rather than a raw pixel width.\nconst BREAKPOINT_ORDER: Breakpoint[] = ['xs', 'sm', 'md', 'lg', 'xl', '2xl'];\n\nexport interface Props extends Omit<\n React.ComponentProps<'aside'>,\n 'onCollapse'\n> {\n width?: number | string;\n collapsedWidth?: number | string;\n collapsible?: boolean;\n defaultCollapsed?: boolean;\n collapsed?: boolean;\n placement?: 'left' | 'right';\n reverseArrow?: boolean;\n trigger?: React.ReactNode;\n classNames?: {\n trigger?: string;\n };\n breakpoint?: Breakpoint;\n onCollapse?: (collapsed: boolean) => void;\n onBreakpoint?: (broken: boolean) => void;\n}\n\nconst toCssSize = (value: number | string) =>\n typeof value === 'number' ? `${value}px` : value;\n\nconst Sider = ({\n children,\n className,\n classNames,\n style,\n width = 200,\n collapsedWidth = 80,\n collapsible = false,\n defaultCollapsed = false,\n collapsed: _collapsed,\n placement = 'left',\n reverseArrow = false,\n trigger,\n breakpoint,\n onCollapse,\n onBreakpoint,\n ...props\n}: Props) => {\n useRegisterSider();\n\n const { locale } = useConfig();\n const contentId = useId();\n const [collapsed, setCollapsed] = useControllableState<boolean>({\n value: _collapsed,\n defaultValue: defaultCollapsed,\n onChange: onCollapse,\n });\n\n const { breakpoint: viewportBreakpoint } = useResponsiveSize({\n viewport: true,\n });\n const broken = breakpoint\n ? BREAKPOINT_ORDER.indexOf(viewportBreakpoint.current) <\n BREAKPOINT_ORDER.indexOf(breakpoint)\n : false;\n\n useLayoutEffect(() => {\n if (!breakpoint) {\n return;\n }\n\n setCollapsed(broken);\n onBreakpoint?.(broken);\n }, [broken, breakpoint, setCollapsed, onBreakpoint]);\n\n const onTriggerClick = () => {\n setCollapsed(!collapsed);\n };\n\n // A right-placed Sider's collapse icon should default to pointing the\n // opposite way from a left-placed one (it's opening/closing a panel on\n // the other side of the content), so `placement` flips the effective\n // direction on top of whatever `reverseArrow` already requests —\n // `reverseArrow` still layers on as a manual override either way.\n const effectiveReverseArrow = reverseArrow !== (placement === 'right');\n const TriggerIcon =\n collapsed !== effectiveReverseArrow ? PanelLeftOpen : PanelLeftClose;\n\n return (\n <aside\n className={cn(\n // Below Header's z-50 (and every other floating/overlay primitive\n // in this library, which all use z-50) — Sider is a static layout\n // column, not floating chrome, and previously outranked Header\n // with an arbitrary z-100, covering it once Header stuck to the\n // viewport top on scroll.\n 'z-10 flex h-full shrink-0 flex-col overflow-hidden',\n 'transition-[width] duration-200',\n // Lets a Sider visually sit on the right without needing to\n // reorder JSX/children — useful since Sider's presence is\n // detected via context (sider-context.ts) rather than requiring\n // it to be a specific direct child in a specific position.\n placement === 'right' && 'order-last',\n className,\n //\n )}\n style={{\n width: toCssSize(collapsed ? collapsedWidth : width),\n ...style,\n }}\n {...props}\n >\n <div id={contentId} className=\"min-h-0 flex-1 overflow-auto\">\n {children}\n </div>\n {collapsible && (\n <button\n type=\"button\"\n aria-label={\n collapsed\n ? (locale.expand ?? DEFAULT_LOCALE.expand)\n : (locale.collapse ?? DEFAULT_LOCALE.collapse)\n }\n aria-expanded={!collapsed}\n aria-controls={contentId}\n onClick={onTriggerClick}\n className={cn(\n 'flex w-full shrink-0 items-center justify-center py-2',\n 'cursor-pointer transition-colors hover:bg-black/5',\n classNames?.trigger,\n //\n )}\n >\n {trigger === undefined ? <TriggerIcon className=\"size-4\" /> : trigger}\n </button>\n )}\n </aside>\n );\n};\n\nexport default Sider;\n"],"mappings":";;;;;;;;;;;AAkBA,MAAM,mBAAiC;CAAC;CAAM;CAAM;CAAM;CAAM;CAAM;CAAM;AAsB5E,MAAM,aAAa,UACjB,OAAO,UAAU,WAAW,GAAG,MAAM,MAAM;AAE7C,MAAM,SAAS,EACb,UACA,WACA,YACA,OACA,QAAQ,KACR,iBAAiB,IACjB,cAAc,OACd,mBAAmB,OACnB,WAAW,YACX,YAAY,QACZ,eAAe,OACf,SACA,YACA,YACA,cACA,GAAG,YACQ;AACX,mBAAkB;CAElB,MAAM,EAAE,WAAW,WAAW;CAC9B,MAAM,YAAY,OAAO;CACzB,MAAM,CAAC,WAAW,gBAAgB,qBAA8B;EAC9D,OAAO;EACP,cAAc;EACd,UAAU;EACX,CAAC;CAEF,MAAM,EAAE,YAAY,uBAAuB,kBAAkB,EAC3D,UAAU,MACX,CAAC;CACF,MAAM,SAAS,aACX,iBAAiB,QAAQ,mBAAmB,QAAQ,GACpD,iBAAiB,QAAQ,WAAW,GACpC;AAEJ,uBAAsB;AACpB,MAAI,CAAC,WACH;AAGF,eAAa,OAAO;AACpB,iBAAe,OAAO;IACrB;EAAC;EAAQ;EAAY;EAAc;EAAa,CAAC;CAEpD,MAAM,uBAAuB;AAC3B,eAAa,CAAC,UAAU;;CAS1B,MAAM,cACJ,eAF4B,kBAAkB,cAAc,YAEtB,gBAAgB;AAExD,QACE,qBAAC;EACC,WAAW,GAMT,sDACA,mCAKA,cAAc,WAAW,cACzB,UAED;EACD,OAAO;GACL,OAAO,UAAU,YAAY,iBAAiB,MAAM;GACpD,GAAG;GACJ;EACD,GAAI;aAEJ,oBAAC;GAAI,IAAI;GAAW,WAAU;GAC3B;IACG,EACL,eACC,oBAAC;GACC,MAAK;GACL,cACE,YACK,OAAO,UAAU,eAAe,SAChC,OAAO,YAAY,eAAe;GAEzC,iBAAe,CAAC;GAChB,iBAAe;GACf,SAAS;GACT,WAAW,GACT,yDACA,qDACA,YAAY,QAEb;aAEA,YAAY,SAAY,oBAAC,eAAY,WAAU,WAAW,GAAG;IACvD;GAEL"}