@adminui-dev/layout 1.0.1 → 1.0.2

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.
@@ -0,0 +1,11 @@
1
+ import type { LayoutPros, LayoutConfig } from './typings';
2
+ /**
3
+ * Base layout
4
+ * @param props layout properites
5
+ * @returns
6
+ */
7
+ declare function BaseLayout(props: LayoutPros): import("react/jsx-runtime").JSX.Element;
8
+ declare function defineConfig(config: LayoutConfig): LayoutConfig;
9
+ declare const defaultConfig: LayoutConfig;
10
+ export { defineConfig, defaultConfig };
11
+ export default BaseLayout;
@@ -1,5 +1,7 @@
1
+ import { LAYOUT_ASIDE_KEY } from "./LayoutContext";
1
2
  declare function LayoutAside(props: React.HTMLAttributes<HTMLDivElement>): import("react/jsx-runtime").JSX.Element;
2
3
  declare namespace LayoutAside {
3
4
  var displayName: string;
5
+ var role: typeof LAYOUT_ASIDE_KEY;
4
6
  }
5
7
  export default LayoutAside;
@@ -1,5 +1,7 @@
1
+ import { LAYOUT_CONTENT_KEY } from './LayoutContext';
1
2
  declare function LayoutContent(props: React.HTMLAttributes<HTMLDivElement>): import("react/jsx-runtime").JSX.Element;
2
3
  declare namespace LayoutContent {
3
4
  var displayName: string;
5
+ var role: typeof LAYOUT_CONTENT_KEY;
4
6
  }
5
7
  export default LayoutContent;
@@ -1,3 +1,12 @@
1
- import type { ConfigDispatcher } from "./typings";
2
- export declare const createConfigContext: () => import("react").Context<ConfigDispatcher>;
3
- export declare const useConfigContext: () => ConfigDispatcher;
1
+ import type { LayoutConfig, ThemeSkin, ConfigActionDispatcher, ConfigStateDispatcher } from "./typings";
2
+ export declare function defineConfig(config: LayoutConfig): LayoutConfig;
3
+ export declare const LAYOUT_ASIDE_KEY: unique symbol;
4
+ export declare const LAYOUT_CONTENT_KEY: unique symbol;
5
+ export declare const LAYOUT_HEADER_KEY: unique symbol;
6
+ export declare const defaultSkinData: ThemeSkin;
7
+ export declare const defaultConfig: LayoutConfig;
8
+ export declare const createConfigActionContext: () => import("react").Context<ConfigActionDispatcher>;
9
+ export declare const createConfigStateContext: () => import("react").Context<ConfigStateDispatcher>;
10
+ export declare const useConfigState: () => ConfigStateDispatcher;
11
+ export declare const useConfigAction: () => ConfigActionDispatcher;
12
+ export declare const useTheme: () => import("./typings").Theme;
@@ -1,5 +1,7 @@
1
+ import { LAYOUT_HEADER_KEY } from "./LayoutContext";
1
2
  declare function LayoutHeader(props: React.HTMLAttributes<HTMLDivElement>): import("react/jsx-runtime").JSX.Element;
2
3
  declare namespace LayoutHeader {
3
4
  var displayName: string;
5
+ var role: typeof LAYOUT_HEADER_KEY;
4
6
  }
5
7
  export default LayoutHeader;
@@ -0,0 +1,16 @@
1
+ import { LayoutTheme, Theme } from "./typings";
2
+ declare function getAvatarInitials(name: string): string;
3
+ declare const hexToRgba: (hex: string) => {
4
+ r: number;
5
+ g: number;
6
+ b: number;
7
+ a: string | number;
8
+ };
9
+ declare const hexToRgb: (color: string) => {
10
+ r: number;
11
+ g: number;
12
+ b: number;
13
+ };
14
+ declare const hexToRgbaString: (color: string, alpha?: number) => string;
15
+ declare const getLayoutTheme: (theme: Theme) => LayoutTheme;
16
+ export { getAvatarInitials, hexToRgb, hexToRgba, hexToRgbaString, getLayoutTheme };
@@ -0,0 +1,6 @@
1
+ type ReturnType<T> = [React.RefObject<T | null>, {
2
+ width: number;
3
+ height: number;
4
+ }];
5
+ declare function useLayoutSize<T extends HTMLElement = HTMLDivElement>(): ReturnType<T>;
6
+ export { useLayoutSize };
@@ -1,6 +1,6 @@
1
- import Layout from "./Layout";
1
+ import { BaseLayout } from "./Layout";
2
2
  import FullScreenButton from "./FullScreenButton";
3
3
  import LayoutBackground from "./LayoutBackground";
4
- import ThemeProvider, { useTheme } from "./ThemeProvider";
5
- import { createConfigContext, useConfigContext } from "./LayoutContext";
6
- export { Layout, LayoutBackground, FullScreenButton, useConfigContext, createConfigContext, ThemeProvider, useTheme };
4
+ import { createConfigActionContext, createConfigStateContext, useConfigState, useConfigAction, useTheme, defaultConfig, defineConfig, defaultSkinData } from "./LayoutContext";
5
+ import { getAvatarInitials, hexToRgb, hexToRgbaString, getLayoutTheme } from "./common";
6
+ export { BaseLayout, LayoutBackground, FullScreenButton, createConfigActionContext, createConfigStateContext, useConfigState, useConfigAction, useTheme, getAvatarInitials, hexToRgb, hexToRgbaString, defaultConfig, defaultSkinData, getLayoutTheme, defineConfig };
@@ -1,15 +1,13 @@
1
- import type { LayoutPros, LayoutConfig } from './typings';
1
+ import type { BaseLayoutProps } from './typings';
2
2
  /**
3
3
  * Base layout
4
4
  * @param props layout properites
5
5
  * @returns
6
6
  */
7
- declare function Layout(props: LayoutPros): import("react/jsx-runtime").JSX.Element;
8
- declare namespace Layout {
7
+ declare function BaseLayout(props: BaseLayoutProps): import("react/jsx-runtime").JSX.Element;
8
+ declare namespace BaseLayout {
9
9
  var Aside: typeof import("./LayoutAside").default;
10
10
  var Content: typeof import("./LayoutContent").default;
11
11
  var Header: typeof import("./LayoutHeader").default;
12
12
  }
13
- declare function defineConfig(config: LayoutConfig): LayoutConfig;
14
- export { defineConfig };
15
- export default Layout;
13
+ export { BaseLayout };
@@ -1,14 +1,26 @@
1
1
  type Theme = 'light' | 'dark' | 'system';
2
2
  type LayoutType = 'headMenu' | 'leftMenu';
3
- type LayoutTheme = 'light' | 'dark' | 'system';
3
+ type LayoutTheme = 'light' | 'dark';
4
4
  type ContainerMode = 'inline' | 'box' | 'panel';
5
- type ContainerStretch = 'inline' | 'auto' | 'full';
6
- type ConfigDispatcher = {
5
+ type ContainerStretch = 'inline' | 'auto' | 'fill';
6
+ type SkinType = 'tidy' | 'rich';
7
+ type ConfigStateDispatcher = {
7
8
  layoutConfig: LayoutConfig;
8
- setLayoutConfig: (config: LayoutConfig) => void;
9
9
  locale: string;
10
+ theme: Theme;
11
+ themeSkin: ThemeSkin;
12
+ themeSkinMap: Record<SkinType, ThemeSkin[]>;
13
+ languages: Language[];
14
+ };
15
+ type ConfigActionDispatcher = {
16
+ setTheme: (theme: Theme) => void;
10
17
  setLocale: (locale: string) => void;
11
- getLanguages: () => Language[];
18
+ setLayoutConfig: (config: LayoutConfig) => void;
19
+ };
20
+ type OutletContainer = {
21
+ title: string;
22
+ breadcrumbData: any[];
23
+ footer?: React.ReactNode;
12
24
  };
13
25
  interface LayoutConfig {
14
26
  layoutType?: LayoutType;
@@ -17,9 +29,35 @@ interface LayoutConfig {
17
29
  asideCollapsedWidth?: number;
18
30
  theme?: Theme;
19
31
  locale?: string;
32
+ disabledLocale?: boolean;
33
+ skinName?: string;
34
+ primaryColor?: string;
35
+ highlight?: boolean;
36
+ flated?: boolean;
37
+ menuIconSize?: number;
38
+ compact?: boolean;
39
+ splitMenu?: boolean;
40
+ hideBorder?: boolean;
41
+ hideTitle?: boolean;
42
+ hideFooter?: boolean;
43
+ hideBreadcrumb?: boolean;
44
+ containerTransparent?: boolean;
20
45
  userInfo?: UserInfo;
21
46
  brandInfo?: BrandInfo;
22
47
  }
48
+ interface ThemeSkin {
49
+ name: string;
50
+ icon: string;
51
+ label?: string;
52
+ theme: LayoutTheme[];
53
+ themeType: SkinType;
54
+ asideWidth?: number;
55
+ primaryColor?: string;
56
+ asideCollapsedWidth?: number;
57
+ layoutBorderColor?: string;
58
+ headerStyle?: React.CSSProperties;
59
+ asideStyle?: React.CSSProperties;
60
+ }
23
61
  interface Language {
24
62
  name: string;
25
63
  locale: string;
@@ -43,19 +81,32 @@ interface BrandInfo {
43
81
  title: string;
44
82
  logo?: React.ReactNode;
45
83
  }
46
- export interface LayoutPros extends React.HTMLAttributes<HTMLDivElement> {
84
+ interface MenuData {
85
+ id?: string;
86
+ name: string;
87
+ label?: string;
88
+ icon?: React.ReactNode;
89
+ path?: string;
90
+ extra?: React.ReactNode;
91
+ originalPath?: string;
92
+ params?: Record<string, string>;
93
+ children?: MenuData[];
94
+ }
95
+ interface LayoutProps extends React.HTMLAttributes<HTMLDivElement> {
47
96
  }
48
- export interface RootLayoutProps extends React.HTMLAttributes<HTMLDivElement> {
97
+ interface BaseLayoutProps extends LayoutProps {
98
+ headerHeight: number;
99
+ ref?: React.Ref<HTMLDivElement>;
100
+ }
101
+ interface RootLayoutProps<T> extends LayoutProps {
49
102
  layoutConfig?: LayoutConfig;
103
+ menuData?: MenuData[];
50
104
  theme?: Theme;
51
105
  locale?: string;
52
- localeMessageData?: Record<string, LocaleMessageData>;
53
- }
54
- export interface MainLayoutProps extends React.HTMLAttributes<HTMLDivElement> {
55
- header?: React.ReactNode;
56
- aside?: React.ReactNode;
106
+ localeMessages?: Record<string, T>;
107
+ themeSkins?: ThemeSkin[];
57
108
  }
58
- export interface ContainerProps {
109
+ interface ContainerProps extends LayoutProps {
59
110
  mode?: ContainerMode;
60
111
  stretch?: ContainerStretch;
61
112
  bordered?: boolean;
@@ -65,4 +116,4 @@ export interface ContainerProps {
65
116
  transparent?: boolean;
66
117
  children?: React.ReactNode;
67
118
  }
68
- export type { Theme, LayoutTheme, LayoutType, LayoutConfig, Language, LocaleMessageData, UserInfo, BrandInfo, ConfigDispatcher };
119
+ export type { LayoutProps, BaseLayoutProps, RootLayoutProps, ContainerProps, ContainerMode, ContainerStretch, Theme, LayoutTheme, LayoutType, LayoutConfig, Language, LocaleMessageData, UserInfo, BrandInfo, ConfigStateDispatcher, ConfigActionDispatcher, SkinType, ThemeSkin, MenuData, OutletContainer };
package/dist/index.cjs.js CHANGED
@@ -1 +1 @@
1
- "use strict";var e=require("react/jsx-runtime"),t=require("react");function n(){return e.jsx("div",{style:{boxSizing:"border-box",pointerEvents:"none",overflow:"hidden",insetBlockStart:"0",insetInlineStart:"0",zIndex:"0",height:"100%",width:"100%"}})}function o(t){return e.jsx("div",{style:{boxSizing:"border-box",display:"flex",flex:"auto",position:"relative",flexDirection:"column",minHeight:"0"},children:t.children})}function r(t){return e.jsx(e.Fragment,{children:t.children})}o.displayName="LayoutContent",r.displayName="LayoutAside";const i=t.createContext({layoutConfig:{},setLayoutConfig:()=>{},locale:"en-US",setLocale:()=>{},getLanguages:()=>[]}),s=()=>t.useContext(i);function d(t){const n=s(),{layoutConfig:o}=n;let r={boxSizing:"border-box",position:"sticky",width:"100%",zIndex:"100",top:"0",paddingBlock:"0",paddingInline:"0",transition:"background-color .3s cubic-bezier(.645, .045, .355, 1)"};return o.headerHeight&&(r={...r,height:o.headerHeight+"px",minHeight:o.headerHeight+"px"}),e.jsx("header",{style:r,children:t.children})}d.displayName="LayoutHeader";var a="layout-module_rootBox__Y8bEx",l="layout-module_rootLayout__TePvr",u="layout-module_mainLayout__a8Tb9";function c(o){let r=null,i=null,s=null;return t.Children.forEach(o.children,e=>{const t=e.type.displayName;"LayoutHeader"===t?r=e:"LayoutContent"===t?i=e:"LayoutAside"===t&&(s=e)}),e.jsxs("div",{className:a,children:[e.jsx(n,{}),e.jsxs("div",{className:l,children:[s,e.jsxs("div",{className:u,children:[r,i]})]})]})}!function(e,t){void 0===t&&(t={});var n=t.insertAt;if("undefined"!=typeof document){var o=document.head||document.getElementsByTagName("head")[0],r=document.createElement("style");r.type="text/css","top"===n&&o.firstChild?o.insertBefore(r,o.firstChild):o.appendChild(r),r.styleSheet?r.styleSheet.cssText=e:r.appendChild(document.createTextNode(e))}}('@layer base {\r\n html, body {\r\n padding: 0;\r\n margin: 0;\r\n border: 0;\r\n width: 100%;\r\n height: 100%;\r\n }\r\n}\r\n.layout-module_rootBox__Y8bEx {\r\n box-sizing: border-box; \r\n position: relative;\r\n width: 100%;\r\n height:100%;\r\n overflow: hidden;\r\n background-color: transparent;\r\n}\r\n.layout-module_rootLayout__TePvr {\r\n box-sizing: border-box; \r\n inset: 0;\r\n display: flex;\r\n flex-flow: row;\r\n position: absolute;\r\n background-color: transparent;\r\n}\r\n.layout-module_mainLayout__a8Tb9 {\r\n box-sizing: border-box;\r\n display: flex;\r\n flex:auto; \r\n position: relative;\r\n flex-flow: column;\r\n min-height: 0px; \r\n}\r\n.layout-module_headerLayout__Jx8vy {\r\n box-sizing: border-box;\r\n position: sticky;\r\n width: 100%;\r\n z-index: 100;\r\n top: 0px;\r\n padding-block: 0px;\r\n padding-inline: 0px;\r\n transition: "background-color .3s cubic-bezier(.645, .045, .355, 1)"; \r\n}'),c.Aside=r,c.Content=o,c.Header=d;const m=t.createContext({theme:"system",setTheme:()=>{}});exports.FullScreenButton=function(n){const o=!!document.fullscreenElement,[r,i]=t.useState(o),s=()=>{i(!!document.fullscreenElement)},d=e=>{"F11"===e.code&&(e.preventDefault(),a())};t.useEffect(()=>(document.addEventListener("fullscreenchange",s),document.addEventListener("keydown",d,!0),()=>{document.removeEventListener("fullscreenchange",s),document.removeEventListener("keydown",d)}),[]);const a=()=>{r?document.exitFullscreen():document.documentElement.requestFullscreen()};if(!n.buttons||n.buttons.length<2)return e.jsx(e.Fragment,{});const[l,u]=n.buttons,c=r?l:u;return t.cloneElement(c,{onClick:e=>{console.log(e),a()}})},exports.Layout=c,exports.LayoutBackground=n,exports.ThemeProvider=function(n){const{children:o,storageKey:r="adminui-shadcn-theme"}=n,i=n.theme||localStorage.getItem(r)||n.defaultTheme||"system",[s,d]=t.useState(i);t.useEffect(()=>{const e=window.document.documentElement;if(e.classList.remove("light","dark"),"system"===s){const t=window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light";return void e.classList.add(t)}e.classList.add(s)},[s]);const a={theme:s,setTheme:e=>{localStorage.setItem(r,e),d(e)}};return e.jsx(m.Provider,{value:a,children:o})},exports.createConfigContext=()=>i,exports.useConfigContext=s,exports.useTheme=()=>{const e=t.useContext(m);if(void 0===e)throw new Error("useTheme must be used within a ThemeProvider");return e};
1
+ "use strict";var e=require("react/jsx-runtime"),r=require("react");function n(e,r){void 0===r&&(r={});var n=r.insertAt;if(e&&"undefined"!=typeof document){var t=document.head||document.getElementsByTagName("head")[0],o=document.createElement("style");o.type="text/css","top"===n&&t.firstChild?t.insertBefore(o,t.firstChild):t.appendChild(o),o.styleSheet?o.styleSheet.cssText=e:o.appendChild(document.createTextNode(e))}}var t="Layout-module_rootBackground__j3UVG",o="Layout-module_mainLayout__6W9W9";function i(){return e.jsx("div",{className:t,children:"55555"})}n('@layer base {\r\n html, body {\r\n padding: 0;\r\n margin: 0;\r\n border: 0;\r\n width: 100%;\r\n height: 100%;\r\n overflow: hidden;\r\n }\r\n #Layout-module_root__3x-pW { \r\n text-align: initial;\r\n width: 100%;\r\n height: 100%;\r\n } \r\n}\r\n.Layout-module_rootBox__3JHjy {\r\n box-sizing: border-box; \r\n width: 100%;\r\n height:100%; \r\n text-align: initial; \r\n display: grid;\r\n grid-template-areas: "root";\r\n background-color: transparent;\r\n}\r\n.Layout-module_rootBackground__j3UVG {\r\n box-sizing: border-box; \r\n pointer-events: none;\r\n overflow: hidden;\r\n inset-block-start:0;\r\n inset-inline-start:0; \r\n height:100%;\r\n width: 100%;\r\n z-index: 0;\r\n grid-area: root;\r\n}\r\n.Layout-module_rootLayout__jVEEF {\r\n box-sizing: border-box; \r\n width: 100%;\r\n height: 100%;\r\n display: grid;\r\n grid-area: root;\r\n grid-template-columns: auto 1fr;\r\n grid-template-rows: 50px 1fr; \r\n z-index: 1; \r\n overflow: auto;\r\n background-color: transparent; \r\n}\r\n.Layout-module_mainLayout__6W9W9 {\r\n box-sizing: border-box;\r\n grid-row: 2;\r\n grid-column: 2;\r\n display: flex;\r\n flex-flow: column; \r\n width: 100%;\r\n height: 100%;\r\n min-height: 0;\r\n}\r\n');const a=Symbol("LayoutAside"),l=Symbol("LayoutContent"),d=Symbol("LayoutHeader"),s={icon:"",name:"default",themeType:"tidy",theme:["light","dark"]},u={headerHeight:50,asideCollapsedWidth:52,asideWidth:260,layoutType:"leftMenu",theme:"system",primaryColor:"#417ffb",skinName:s.name},c=r.createContext({setTheme:()=>{},setLayoutConfig:()=>{},setLocale:()=>{}}),h=r.createContext({locale:"en-US",languages:[],theme:"system",layoutConfig:{},themeSkin:s,themeSkinMap:{tidy:[],rich:[]}}),m=()=>r.useContext(h);function g(r){return e.jsx("div",{className:o,...r,children:r.children})}function x(r){return e.jsx(e.Fragment,{children:r.children})}function y(r){return e.jsx(e.Fragment,{children:r.children})}g.displayName="LayoutContent",g.role=l,x.displayName="LayoutAside",x.role=a,y.displayName="LayoutHeader",y.role=d;var f="layout-module_rootBox__Y8bEx",p="layout-module_rootLayout__TePvr";function b(n){let t=null,o=null,s=null;r.Children.forEach(n.children,e=>{const r=e.type.role;r===d?t=e:r===l?o=e:r===a&&(s=e)});const u={gridTemplateRows:`${n.headerHeight}px 1fr`};return e.jsx(e.Fragment,{children:e.jsxs("div",{ref:n.ref,className:f,style:{...n.style},children:[e.jsx(i,{}),e.jsxs("div",{className:p,style:u,children:[s,t,o]})]})})}n('@layer base {\r\n html, body {\r\n padding: 0;\r\n margin: 0;\r\n border: 0;\r\n width: 100%;\r\n height: 100%;\r\n overflow: hidden;\r\n }\r\n #layout-module_root__0efzq { \r\n text-align: initial;\r\n width: 100%;\r\n height: 100%;\r\n } \r\n}\r\n.layout-module_rootBox__Y8bEx {\r\n box-sizing: border-box; \r\n width: 100%;\r\n height:100%; \r\n text-align: initial; \r\n display: grid;\r\n grid-template-areas: "root";\r\n background-color: transparent;\r\n}\r\n.layout-module_rootBackground__vEs6e {\r\n box-sizing: border-box; \r\n pointer-events: none;\r\n overflow: hidden;\r\n inset-block-start:0;\r\n inset-inline-start:0; \r\n height:100%;\r\n width: 100%;\r\n z-index: 0;\r\n grid-area: root;\r\n}\r\n.layout-module_rootLayout__TePvr {\r\n box-sizing: border-box; \r\n width: 100%;\r\n height: 100%;\r\n display: grid;\r\n grid-area: root;\r\n grid-template-columns: auto 1fr;\r\n grid-template-rows: 50px 1fr; \r\n z-index: 1; \r\n overflow: auto;\r\n background-color: transparent; \r\n}\r\n.layout-module_mainLayout__a8Tb9 {\r\n box-sizing: border-box;\r\n grid-row: 2;\r\n grid-column: 2;\r\n display: flex;\r\n flex-flow: column; \r\n width: 100%;\r\n height: 100%;\r\n min-height: 0;\r\n}\r\n'),b.Aside=x,b.Content=g,b.Header=y;const _=e=>({r:parseInt(e.slice(1,3),16),g:parseInt(e.slice(3,5),16),b:parseInt(e.slice(5,7),16),a:9===e.length?(parseInt(e.slice(7,9),16)/255).toFixed(2):1});exports.BaseLayout=b,exports.FullScreenButton=function(n){const t=!!document.fullscreenElement,[o,i]=r.useState(t),a=()=>{i(!!document.fullscreenElement)},l=e=>{"F11"===e.code&&(e.preventDefault(),d())};r.useEffect(()=>(document.addEventListener("fullscreenchange",a),document.addEventListener("keydown",l,!0),()=>{document.removeEventListener("fullscreenchange",a),document.removeEventListener("keydown",l)}),[]);const d=()=>{o?document.exitFullscreen():document.documentElement.requestFullscreen()};if(!n.buttons||n.buttons.length<2)return e.jsx(e.Fragment,{});const[s,u]=n.buttons,c=o?s:u;return r.cloneElement(c,{onClick:e=>{console.log(e),d()}})},exports.LayoutBackground=i,exports.createConfigActionContext=()=>c,exports.createConfigStateContext=()=>h,exports.defaultConfig=u,exports.defaultSkinData=s,exports.defineConfig=function(e){return e},exports.getAvatarInitials=function(e){if(!e)return"";const r=Array.from(e);if(0===r.length)return"";const n=r[0];return function(e){if(0===e.length)return!1;const r=e.codePointAt(0);return r>=19968&&r<=40959||r>=13312&&r<=19903||r>=12352&&r<=12543||r>=44032&&r<=55215||r>=65280&&r<=65519||r>=126976&&r<=129791||r>=127744&&r<=128511||r>=128640&&r<=128767||r>=129280&&r<=129535||r>=9728&&r<=9983||r>=9984&&r<=10175}(n)?n:r.slice(0,2).join("")},exports.getLayoutTheme=e=>{if("system"==e){return window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light"}return e},exports.hexToRgb=e=>{const{r:r,g:n,b:t}=_(e);return{r:r,g:n,b:t}},exports.hexToRgbaString=(e,r)=>{const{r:n,g:t,b:o,a:i}=_(e);return`rgba(${n}, ${t}, ${o}, ${r??i})`},exports.useConfigAction=()=>r.useContext(c),exports.useConfigState=m,exports.useTheme=()=>m().theme;
package/dist/index.d.ts CHANGED
@@ -1,33 +1,30 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import * as React$1 from 'react';
3
- import React__default from 'react';
4
-
5
- declare function LayoutHeader(props: React.HTMLAttributes<HTMLDivElement>): react_jsx_runtime.JSX.Element;
6
- declare namespace LayoutHeader {
7
- var displayName: string;
8
- }
9
-
10
- declare function LayoutContent(props: React.HTMLAttributes<HTMLDivElement>): react_jsx_runtime.JSX.Element;
11
- declare namespace LayoutContent {
12
- var displayName: string;
13
- }
14
-
15
- declare function LayoutAside(props: React.HTMLAttributes<HTMLDivElement>): react_jsx_runtime.JSX.Element;
16
- declare namespace LayoutAside {
17
- var displayName: string;
18
- }
2
+ import * as react from 'react';
3
+ import react__default from 'react';
19
4
 
20
5
  type Theme = 'light' | 'dark' | 'system';
21
6
  type LayoutType = 'headMenu' | 'leftMenu';
22
- type LayoutTheme = 'light' | 'dark' | 'system';
7
+ type LayoutTheme = 'light' | 'dark';
23
8
  type ContainerMode = 'inline' | 'box' | 'panel';
24
- type ContainerStretch = 'inline' | 'auto' | 'full';
25
- type ConfigDispatcher = {
9
+ type ContainerStretch = 'inline' | 'auto' | 'fill';
10
+ type SkinType = 'tidy' | 'rich';
11
+ type ConfigStateDispatcher = {
26
12
  layoutConfig: LayoutConfig;
27
- setLayoutConfig: (config: LayoutConfig) => void;
28
13
  locale: string;
14
+ theme: Theme;
15
+ themeSkin: ThemeSkin;
16
+ themeSkinMap: Record<SkinType, ThemeSkin[]>;
17
+ languages: Language[];
18
+ };
19
+ type ConfigActionDispatcher = {
20
+ setTheme: (theme: Theme) => void;
29
21
  setLocale: (locale: string) => void;
30
- getLanguages: () => Language[];
22
+ setLayoutConfig: (config: LayoutConfig) => void;
23
+ };
24
+ type OutletContainer = {
25
+ title: string;
26
+ breadcrumbData: any[];
27
+ footer?: React.ReactNode;
31
28
  };
32
29
  interface LayoutConfig {
33
30
  layoutType?: LayoutType;
@@ -36,9 +33,35 @@ interface LayoutConfig {
36
33
  asideCollapsedWidth?: number;
37
34
  theme?: Theme;
38
35
  locale?: string;
36
+ disabledLocale?: boolean;
37
+ skinName?: string;
38
+ primaryColor?: string;
39
+ highlight?: boolean;
40
+ flated?: boolean;
41
+ menuIconSize?: number;
42
+ compact?: boolean;
43
+ splitMenu?: boolean;
44
+ hideBorder?: boolean;
45
+ hideTitle?: boolean;
46
+ hideFooter?: boolean;
47
+ hideBreadcrumb?: boolean;
48
+ containerTransparent?: boolean;
39
49
  userInfo?: UserInfo;
40
50
  brandInfo?: BrandInfo;
41
51
  }
52
+ interface ThemeSkin {
53
+ name: string;
54
+ icon: string;
55
+ label?: string;
56
+ theme: LayoutTheme[];
57
+ themeType: SkinType;
58
+ asideWidth?: number;
59
+ primaryColor?: string;
60
+ asideCollapsedWidth?: number;
61
+ layoutBorderColor?: string;
62
+ headerStyle?: React.CSSProperties;
63
+ asideStyle?: React.CSSProperties;
64
+ }
42
65
  interface Language {
43
66
  name: string;
44
67
  locale: string;
@@ -62,19 +85,32 @@ interface BrandInfo {
62
85
  title: string;
63
86
  logo?: React.ReactNode;
64
87
  }
65
- interface LayoutPros extends React.HTMLAttributes<HTMLDivElement> {
88
+ interface MenuData {
89
+ id?: string;
90
+ name: string;
91
+ label?: string;
92
+ icon?: React.ReactNode;
93
+ path?: string;
94
+ extra?: React.ReactNode;
95
+ originalPath?: string;
96
+ params?: Record<string, string>;
97
+ children?: MenuData[];
98
+ }
99
+ interface LayoutProps extends React.HTMLAttributes<HTMLDivElement> {
66
100
  }
67
- interface RootLayoutProps extends React.HTMLAttributes<HTMLDivElement> {
101
+ interface BaseLayoutProps extends LayoutProps {
102
+ headerHeight: number;
103
+ ref?: React.Ref<HTMLDivElement>;
104
+ }
105
+ interface RootLayoutProps<T> extends LayoutProps {
68
106
  layoutConfig?: LayoutConfig;
107
+ menuData?: MenuData[];
69
108
  theme?: Theme;
70
109
  locale?: string;
71
- localeMessageData?: Record<string, LocaleMessageData>;
72
- }
73
- interface MainLayoutProps extends React.HTMLAttributes<HTMLDivElement> {
74
- header?: React.ReactNode;
75
- aside?: React.ReactNode;
110
+ localeMessages?: Record<string, T>;
111
+ themeSkins?: ThemeSkin[];
76
112
  }
77
- interface ContainerProps {
113
+ interface ContainerProps extends LayoutProps {
78
114
  mode?: ContainerMode;
79
115
  stretch?: ContainerStretch;
80
116
  bordered?: boolean;
@@ -85,13 +121,43 @@ interface ContainerProps {
85
121
  children?: React.ReactNode;
86
122
  }
87
123
 
124
+ declare function defineConfig(config: LayoutConfig): LayoutConfig;
125
+ declare const LAYOUT_ASIDE_KEY: unique symbol;
126
+ declare const LAYOUT_CONTENT_KEY: unique symbol;
127
+ declare const LAYOUT_HEADER_KEY: unique symbol;
128
+ declare const defaultSkinData: ThemeSkin;
129
+ declare const defaultConfig: LayoutConfig;
130
+ declare const createConfigActionContext: () => react.Context<ConfigActionDispatcher>;
131
+ declare const createConfigStateContext: () => react.Context<ConfigStateDispatcher>;
132
+ declare const useConfigState: () => ConfigStateDispatcher;
133
+ declare const useConfigAction: () => ConfigActionDispatcher;
134
+ declare const useTheme: () => Theme;
135
+
136
+ declare function LayoutHeader(props: React.HTMLAttributes<HTMLDivElement>): react_jsx_runtime.JSX.Element;
137
+ declare namespace LayoutHeader {
138
+ var displayName: string;
139
+ var role: typeof LAYOUT_HEADER_KEY;
140
+ }
141
+
142
+ declare function LayoutContent(props: React.HTMLAttributes<HTMLDivElement>): react_jsx_runtime.JSX.Element;
143
+ declare namespace LayoutContent {
144
+ var displayName: string;
145
+ var role: typeof LAYOUT_CONTENT_KEY;
146
+ }
147
+
148
+ declare function LayoutAside(props: React.HTMLAttributes<HTMLDivElement>): react_jsx_runtime.JSX.Element;
149
+ declare namespace LayoutAside {
150
+ var displayName: string;
151
+ var role: typeof LAYOUT_ASIDE_KEY;
152
+ }
153
+
88
154
  /**
89
155
  * Base layout
90
156
  * @param props layout properites
91
157
  * @returns
92
158
  */
93
- declare function Layout(props: LayoutPros): react_jsx_runtime.JSX.Element;
94
- declare namespace Layout {
159
+ declare function BaseLayout(props: BaseLayoutProps): react_jsx_runtime.JSX.Element;
160
+ declare namespace BaseLayout {
95
161
  var Aside: typeof LayoutAside;
96
162
  var Content: typeof LayoutContent;
97
163
  var Header: typeof LayoutHeader;
@@ -102,32 +168,20 @@ declare namespace Layout {
102
168
  * @param props max and min button icon
103
169
  * @returns
104
170
  */
105
- declare function export_default$2(props: {
106
- buttons: React__default.ReactElement[];
171
+ declare function export_default$1(props: {
172
+ buttons: react__default.ReactElement[];
107
173
  }): react_jsx_runtime.JSX.Element;
108
174
 
109
- declare function export_default$1(): react_jsx_runtime.JSX.Element;
175
+ declare function export_default(): react_jsx_runtime.JSX.Element;
110
176
 
111
- interface ThemeProviderProps {
112
- children: React.ReactNode;
113
- theme?: Theme;
114
- defaultTheme?: Theme;
115
- storageKey?: string;
116
- }
117
- type ThemeProviderState = {
118
- theme: Theme;
119
- setTheme: (theme: Theme) => void;
177
+ declare function getAvatarInitials(name: string): string;
178
+ declare const hexToRgb: (color: string) => {
179
+ r: number;
180
+ g: number;
181
+ b: number;
120
182
  };
121
- /**
122
- * Light dark mode context
123
- * @param props
124
- * @returns
125
- */
126
- declare function export_default(props: ThemeProviderProps): react_jsx_runtime.JSX.Element;
127
- declare const useTheme: () => ThemeProviderState;
128
-
129
- declare const createConfigContext: () => React$1.Context<ConfigDispatcher>;
130
- declare const useConfigContext: () => ConfigDispatcher;
183
+ declare const hexToRgbaString: (color: string, alpha?: number) => string;
184
+ declare const getLayoutTheme: (theme: Theme) => LayoutTheme;
131
185
 
132
- export { export_default$2 as FullScreenButton, Layout, export_default$1 as LayoutBackground, export_default as ThemeProvider, createConfigContext, useConfigContext, useTheme };
133
- export type { BrandInfo, ConfigDispatcher, ContainerProps, Language, LayoutConfig, LayoutPros, LayoutTheme, LayoutType, LocaleMessageData, MainLayoutProps, RootLayoutProps, Theme, UserInfo };
186
+ export { BaseLayout, export_default$1 as FullScreenButton, export_default as LayoutBackground, createConfigActionContext, createConfigStateContext, defaultConfig, defaultSkinData, defineConfig, getAvatarInitials, getLayoutTheme, hexToRgb, hexToRgbaString, useConfigAction, useConfigState, useTheme };
187
+ export type { BaseLayoutProps, BrandInfo, ConfigActionDispatcher, ConfigStateDispatcher, ContainerMode, ContainerProps, ContainerStretch, Language, LayoutConfig, LayoutProps, LayoutTheme, LayoutType, LocaleMessageData, MenuData, OutletContainer, RootLayoutProps, SkinType, Theme, ThemeSkin, UserInfo };
package/dist/index.esm.js CHANGED
@@ -1 +1 @@
1
- import{jsx as e,Fragment as n,jsxs as t}from"react/jsx-runtime";import o,{createContext as r,useContext as i,useState as d,useEffect as l}from"react";function a(){return e("div",{style:{boxSizing:"border-box",pointerEvents:"none",overflow:"hidden",insetBlockStart:"0",insetInlineStart:"0",zIndex:"0",height:"100%",width:"100%"}})}function s(n){return e("div",{style:{boxSizing:"border-box",display:"flex",flex:"auto",position:"relative",flexDirection:"column",minHeight:"0"},children:n.children})}function c(t){return e(n,{children:t.children})}s.displayName="LayoutContent",c.displayName="LayoutAside";const u=r({layoutConfig:{},setLayoutConfig:()=>{},locale:"en-US",setLocale:()=>{},getLanguages:()=>[]}),m=()=>u,h=()=>i(u);function y(n){const t=h(),{layoutConfig:o}=t;let r={boxSizing:"border-box",position:"sticky",width:"100%",zIndex:"100",top:"0",paddingBlock:"0",paddingInline:"0",transition:"background-color .3s cubic-bezier(.645, .045, .355, 1)"};return o.headerHeight&&(r={...r,height:o.headerHeight+"px",minHeight:o.headerHeight+"px"}),e("header",{style:r,children:n.children})}y.displayName="LayoutHeader";var g="layout-module_rootBox__Y8bEx",b="layout-module_rootLayout__TePvr",f="layout-module_mainLayout__a8Tb9";function p(n){let r=null,i=null,d=null;return o.Children.forEach(n.children,e=>{const n=e.type.displayName;"LayoutHeader"===n?r=e:"LayoutContent"===n?i=e:"LayoutAside"===n&&(d=e)}),t("div",{className:g,children:[e(a,{}),t("div",{className:b,children:[d,t("div",{className:f,children:[r,i]})]})]})}function x(t){const r=!!document.fullscreenElement,[i,a]=d(r),s=()=>{a(!!document.fullscreenElement)},c=e=>{"F11"===e.code&&(e.preventDefault(),u())};l(()=>(document.addEventListener("fullscreenchange",s),document.addEventListener("keydown",c,!0),()=>{document.removeEventListener("fullscreenchange",s),document.removeEventListener("keydown",c)}),[]);const u=()=>{i?document.exitFullscreen():document.documentElement.requestFullscreen()};if(!t.buttons||t.buttons.length<2)return e(n,{});const[m,h]=t.buttons,y=i?m:h;return o.cloneElement(y,{onClick:e=>{console.log(e),u()}})}!function(e,n){void 0===n&&(n={});var t=n.insertAt;if("undefined"!=typeof document){var o=document.head||document.getElementsByTagName("head")[0],r=document.createElement("style");r.type="text/css","top"===t&&o.firstChild?o.insertBefore(r,o.firstChild):o.appendChild(r),r.styleSheet?r.styleSheet.cssText=e:r.appendChild(document.createTextNode(e))}}('@layer base {\r\n html, body {\r\n padding: 0;\r\n margin: 0;\r\n border: 0;\r\n width: 100%;\r\n height: 100%;\r\n }\r\n}\r\n.layout-module_rootBox__Y8bEx {\r\n box-sizing: border-box; \r\n position: relative;\r\n width: 100%;\r\n height:100%;\r\n overflow: hidden;\r\n background-color: transparent;\r\n}\r\n.layout-module_rootLayout__TePvr {\r\n box-sizing: border-box; \r\n inset: 0;\r\n display: flex;\r\n flex-flow: row;\r\n position: absolute;\r\n background-color: transparent;\r\n}\r\n.layout-module_mainLayout__a8Tb9 {\r\n box-sizing: border-box;\r\n display: flex;\r\n flex:auto; \r\n position: relative;\r\n flex-flow: column;\r\n min-height: 0px; \r\n}\r\n.layout-module_headerLayout__Jx8vy {\r\n box-sizing: border-box;\r\n position: sticky;\r\n width: 100%;\r\n z-index: 100;\r\n top: 0px;\r\n padding-block: 0px;\r\n padding-inline: 0px;\r\n transition: "background-color .3s cubic-bezier(.645, .045, .355, 1)"; \r\n}'),p.Aside=c,p.Content=s,p.Header=y;const v=r({theme:"system",setTheme:()=>{}});function L(n){const{children:t,storageKey:o="adminui-shadcn-theme"}=n,r=n.theme||localStorage.getItem(o)||n.defaultTheme||"system",[i,a]=d(r);l(()=>{const e=window.document.documentElement;if(e.classList.remove("light","dark"),"system"===i){const n=window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light";return void e.classList.add(n)}e.classList.add(i)},[i]);const s={theme:i,setTheme:e=>{localStorage.setItem(o,e),a(e)}};return e(v.Provider,{value:s,children:t})}const _=()=>{const e=i(v);if(void 0===e)throw new Error("useTheme must be used within a ThemeProvider");return e};export{x as FullScreenButton,p as Layout,a as LayoutBackground,L as ThemeProvider,m as createConfigContext,h as useConfigContext,_ as useTheme};
1
+ import{jsx as r,Fragment as e,jsxs as n}from"react/jsx-runtime";import t,{createContext as o,useContext as i,useState as a,useEffect as d}from"react";function l(r,e){void 0===e&&(e={});var n=e.insertAt;if(r&&"undefined"!=typeof document){var t=document.head||document.getElementsByTagName("head")[0],o=document.createElement("style");o.type="text/css","top"===n&&t.firstChild?t.insertBefore(o,t.firstChild):t.appendChild(o),o.styleSheet?o.styleSheet.cssText=r:o.appendChild(document.createTextNode(r))}}var s="Layout-module_rootBackground__j3UVG",u="Layout-module_mainLayout__6W9W9";function c(){return r("div",{className:s,children:"55555"})}function h(r){return r}l('@layer base {\r\n html, body {\r\n padding: 0;\r\n margin: 0;\r\n border: 0;\r\n width: 100%;\r\n height: 100%;\r\n overflow: hidden;\r\n }\r\n #Layout-module_root__3x-pW { \r\n text-align: initial;\r\n width: 100%;\r\n height: 100%;\r\n } \r\n}\r\n.Layout-module_rootBox__3JHjy {\r\n box-sizing: border-box; \r\n width: 100%;\r\n height:100%; \r\n text-align: initial; \r\n display: grid;\r\n grid-template-areas: "root";\r\n background-color: transparent;\r\n}\r\n.Layout-module_rootBackground__j3UVG {\r\n box-sizing: border-box; \r\n pointer-events: none;\r\n overflow: hidden;\r\n inset-block-start:0;\r\n inset-inline-start:0; \r\n height:100%;\r\n width: 100%;\r\n z-index: 0;\r\n grid-area: root;\r\n}\r\n.Layout-module_rootLayout__jVEEF {\r\n box-sizing: border-box; \r\n width: 100%;\r\n height: 100%;\r\n display: grid;\r\n grid-area: root;\r\n grid-template-columns: auto 1fr;\r\n grid-template-rows: 50px 1fr; \r\n z-index: 1; \r\n overflow: auto;\r\n background-color: transparent; \r\n}\r\n.Layout-module_mainLayout__6W9W9 {\r\n box-sizing: border-box;\r\n grid-row: 2;\r\n grid-column: 2;\r\n display: flex;\r\n flex-flow: column; \r\n width: 100%;\r\n height: 100%;\r\n min-height: 0;\r\n}\r\n');const m=Symbol("LayoutAside"),g=Symbol("LayoutContent"),y=Symbol("LayoutHeader"),f={icon:"",name:"default",themeType:"tidy",theme:["light","dark"]},b={headerHeight:50,asideCollapsedWidth:52,asideWidth:260,layoutType:"leftMenu",theme:"system",primaryColor:"#417ffb",skinName:f.name},p=o({setTheme:()=>{},setLayoutConfig:()=>{},setLocale:()=>{}}),x=o({locale:"en-US",languages:[],theme:"system",layoutConfig:{},themeSkin:f,themeSkinMap:{tidy:[],rich:[]}}),_=()=>p,w=()=>x,v=()=>i(x),L=()=>i(p),k=()=>v().theme;function E(e){return r("div",{className:u,...e,children:e.children})}function z(n){return r(e,{children:n.children})}function C(n){return r(e,{children:n.children})}E.displayName="LayoutContent",E.role=g,z.displayName="LayoutAside",z.role=m,C.displayName="LayoutHeader",C.role=y;var N="layout-module_rootBox__Y8bEx",T="layout-module_rootLayout__TePvr";function B(o){let i=null,a=null,d=null;t.Children.forEach(o.children,r=>{const e=r.type.role;e===y?i=r:e===g?a=r:e===m&&(d=r)});const l={gridTemplateRows:`${o.headerHeight}px 1fr`};return r(e,{children:n("div",{ref:o.ref,className:N,style:{...o.style},children:[r(c,{}),n("div",{className:T,style:l,children:[d,i,a]})]})})}function S(n){const o=!!document.fullscreenElement,[i,l]=a(o),s=()=>{l(!!document.fullscreenElement)},u=r=>{"F11"===r.code&&(r.preventDefault(),c())};d(()=>(document.addEventListener("fullscreenchange",s),document.addEventListener("keydown",u,!0),()=>{document.removeEventListener("fullscreenchange",s),document.removeEventListener("keydown",u)}),[]);const c=()=>{i?document.exitFullscreen():document.documentElement.requestFullscreen()};if(!n.buttons||n.buttons.length<2)return r(e,{});const[h,m]=n.buttons,g=i?h:m;return t.cloneElement(g,{onClick:r=>{console.log(r),c()}})}function W(r){if(!r)return"";const e=Array.from(r);if(0===e.length)return"";const n=e[0];return function(r){if(0===r.length)return!1;const e=r.codePointAt(0);return e>=19968&&e<=40959||e>=13312&&e<=19903||e>=12352&&e<=12543||e>=44032&&e<=55215||e>=65280&&e<=65519||e>=126976&&e<=129791||e>=127744&&e<=128511||e>=128640&&e<=128767||e>=129280&&e<=129535||e>=9728&&e<=9983||e>=9984&&e<=10175}(n)?n:e.slice(0,2).join("")}l('@layer base {\r\n html, body {\r\n padding: 0;\r\n margin: 0;\r\n border: 0;\r\n width: 100%;\r\n height: 100%;\r\n overflow: hidden;\r\n }\r\n #layout-module_root__0efzq { \r\n text-align: initial;\r\n width: 100%;\r\n height: 100%;\r\n } \r\n}\r\n.layout-module_rootBox__Y8bEx {\r\n box-sizing: border-box; \r\n width: 100%;\r\n height:100%; \r\n text-align: initial; \r\n display: grid;\r\n grid-template-areas: "root";\r\n background-color: transparent;\r\n}\r\n.layout-module_rootBackground__vEs6e {\r\n box-sizing: border-box; \r\n pointer-events: none;\r\n overflow: hidden;\r\n inset-block-start:0;\r\n inset-inline-start:0; \r\n height:100%;\r\n width: 100%;\r\n z-index: 0;\r\n grid-area: root;\r\n}\r\n.layout-module_rootLayout__TePvr {\r\n box-sizing: border-box; \r\n width: 100%;\r\n height: 100%;\r\n display: grid;\r\n grid-area: root;\r\n grid-template-columns: auto 1fr;\r\n grid-template-rows: 50px 1fr; \r\n z-index: 1; \r\n overflow: auto;\r\n background-color: transparent; \r\n}\r\n.layout-module_mainLayout__a8Tb9 {\r\n box-sizing: border-box;\r\n grid-row: 2;\r\n grid-column: 2;\r\n display: flex;\r\n flex-flow: column; \r\n width: 100%;\r\n height: 100%;\r\n min-height: 0;\r\n}\r\n'),B.Aside=z,B.Content=E,B.Header=C;const j=r=>({r:parseInt(r.slice(1,3),16),g:parseInt(r.slice(3,5),16),b:parseInt(r.slice(5,7),16),a:9===r.length?(parseInt(r.slice(7,9),16)/255).toFixed(2):1}),A=r=>{const{r:e,g:n,b:t}=j(r);return{r:e,g:n,b:t}},H=(r,e)=>{const{r:n,g:t,b:o,a:i}=j(r);return`rgba(${n}, ${t}, ${o}, ${e??i})`},F=r=>{if("system"==r){return window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light"}return r};export{B as BaseLayout,S as FullScreenButton,c as LayoutBackground,_ as createConfigActionContext,w as createConfigStateContext,b as defaultConfig,f as defaultSkinData,h as defineConfig,W as getAvatarInitials,F as getLayoutTheme,A as hexToRgb,H as hexToRgbaString,L as useConfigAction,v as useConfigState,k as useTheme};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adminui-dev/layout",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "description": "adminui.dev's layout",
5
5
  "keywords": [
6
6
  "layout",
@@ -45,8 +45,8 @@
45
45
  "@rollup/plugin-node-resolve": "^15.0.0",
46
46
  "@rollup/plugin-typescript": "^11.0.0",
47
47
  "@types/commander": "^2.12.5",
48
- "@types/react": "^18.0.0",
49
- "@types/react-dom": "^18.0.0",
48
+ "@types/react": "^19.2.0",
49
+ "@types/react-dom": "^19.2.0",
50
50
  "postcss": "^8.5.6",
51
51
  "postcss-modules": "^6.0.1",
52
52
  "rollup": "^4.0.0",
@@ -56,7 +56,7 @@
56
56
  "typescript": "^5.0.3"
57
57
  },
58
58
  "peerDependencies": {
59
- "react": "^19.2.0",
60
- "react-dom": "^19.2.0"
59
+ "react": ">=19.2.0",
60
+ "react-dom": ">=19.2.0"
61
61
  }
62
62
  }