@chayns-ui/layout 0.4.0 → 0.6.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.
- package/README.md +4 -2
- package/dist/app-layout.css +10 -1
- package/dist/components/app-layout/AppLayout.d.ts +12 -2
- package/dist/components/app-layout/AppLayout.d.ts.map +1 -1
- package/dist/components/app-layout/AppLayout.js +137 -67
- package/dist/components/app-layout/AppLayout.js.map +1 -1
- package/dist/components/app-layout/AppLayout.types.d.ts +16 -96
- package/dist/components/app-layout/AppLayout.types.d.ts.map +1 -1
- package/dist/components/app-layout/app-layout-icon/AppLayoutIcon.d.ts +2 -2
- package/dist/components/app-layout/app-layout-icon/AppLayoutIcon.d.ts.map +1 -1
- package/dist/components/tabs/Tabs.d.ts +7 -2
- package/dist/components/tabs/Tabs.d.ts.map +1 -1
- package/dist/components/tabs/Tabs.js +117 -91
- package/dist/components/tabs/Tabs.js.map +1 -1
- package/dist/components/tabs/Tabs.types.d.ts +14 -64
- package/dist/components/tabs/Tabs.types.d.ts.map +1 -1
- package/dist/components/tabs/tabs-icon/TabsIcon.d.ts +2 -2
- package/dist/components/tabs/tabs-icon/TabsIcon.d.ts.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/tabs.css +2 -1
- package/package.json +3 -3
- package/dist/components/app-layout/app-layout-icon/AppLayoutIcon.js +0 -17
- package/dist/components/app-layout/app-layout-icon/AppLayoutIcon.js.map +0 -1
- package/dist/components/app-layout/navigation-items/NavigationItems.d.ts +0 -13
- package/dist/components/app-layout/navigation-items/NavigationItems.d.ts.map +0 -1
- package/dist/components/app-layout/navigation-items/NavigationItems.js +0 -54
- package/dist/components/app-layout/navigation-items/NavigationItems.js.map +0 -1
- package/dist/components/tabs/tabs-icon/TabsIcon.js +0 -11
- package/dist/components/tabs/tabs-icon/TabsIcon.js.map +0 -1
package/README.md
CHANGED
|
@@ -20,8 +20,10 @@ import '@chayns-ui/layout/styles.css';
|
|
|
20
20
|
import { AppLayout } from '@chayns-ui/layout';
|
|
21
21
|
```
|
|
22
22
|
|
|
23
|
-
`AppLayout`
|
|
24
|
-
|
|
23
|
+
`AppLayout` wird über `Header`, `Logo`, `Navigation`, rekursive
|
|
24
|
+
`Navigation.Item`, `Content` und `CollapseToggle` komponiert. Der frühere
|
|
25
|
+
`items[]`-Vertrag wurde vor 1.0 entfernt. Tabs verwendet `Tabs.List`,
|
|
26
|
+
`Tabs.Tab value` und `Tabs.Panel value` statt `tabs[]`.
|
|
25
27
|
|
|
26
28
|
Alternatively, the component stylesheet is available as
|
|
27
29
|
`@chayns-ui/layout/app-layout.css` or
|
package/dist/app-layout.css
CHANGED
|
@@ -18,6 +18,15 @@
|
|
|
18
18
|
padding-inline: var(--sp-4);
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
+
.chayns-app-layout__header-content {
|
|
22
|
+
display: flex;
|
|
23
|
+
flex: 1 1 auto;
|
|
24
|
+
align-items: center;
|
|
25
|
+
justify-content: flex-end;
|
|
26
|
+
min-inline-size: 0;
|
|
27
|
+
margin-inline-start: var(--sp-4);
|
|
28
|
+
}
|
|
29
|
+
|
|
21
30
|
.chayns-app-layout__logo {
|
|
22
31
|
display: block;
|
|
23
32
|
max-block-size: calc(var(--k32) + var(--k8));
|
|
@@ -30,7 +39,7 @@
|
|
|
30
39
|
flex-direction: column;
|
|
31
40
|
min-inline-size: 0;
|
|
32
41
|
min-block-size: 0;
|
|
33
|
-
padding: var(--sp-2);
|
|
42
|
+
padding: 0 var(--sp-2) var(--sp-2);
|
|
34
43
|
}
|
|
35
44
|
|
|
36
45
|
.chayns-app-layout__navigation {
|
|
@@ -1,3 +1,13 @@
|
|
|
1
|
-
import type { AppLayoutProps } from './AppLayout.types.js';
|
|
2
|
-
|
|
1
|
+
import type { AppLayoutCollapseToggleProps, AppLayoutNavigationItemProps, AppLayoutProps } from './AppLayout.types.js';
|
|
2
|
+
declare function NavigationItem({ children, className, href, isActive, label, ...props }: AppLayoutNavigationItemProps): import("react").JSX.Element;
|
|
3
|
+
export declare const AppLayout: import("react").ForwardRefExoticComponent<Omit<AppLayoutProps, "ref"> & import("react").RefAttributes<HTMLDivElement>> & {
|
|
4
|
+
CollapseToggle: import("react").ForwardRefExoticComponent<Omit<AppLayoutCollapseToggleProps, "ref"> & import("react").RefAttributes<HTMLButtonElement>>;
|
|
5
|
+
Content: import("react").ForwardRefExoticComponent<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLElement>, HTMLElement>, "ref"> & import("react").RefAttributes<HTMLElement>>;
|
|
6
|
+
Header: import("react").ForwardRefExoticComponent<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLElement>, HTMLElement>, "ref"> & import("react").RefAttributes<HTMLElement>>;
|
|
7
|
+
Logo: import("react").ForwardRefExoticComponent<Omit<import("react").DetailedHTMLProps<import("react").ImgHTMLAttributes<HTMLImageElement>, HTMLImageElement>, "ref"> & import("react").RefAttributes<HTMLImageElement>>;
|
|
8
|
+
Navigation: import("react").ForwardRefExoticComponent<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLElement>, HTMLElement>, "ref"> & import("react").RefAttributes<HTMLElement>> & {
|
|
9
|
+
Item: typeof NavigationItem;
|
|
10
|
+
};
|
|
11
|
+
};
|
|
12
|
+
export {};
|
|
3
13
|
//# sourceMappingURL=AppLayout.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AppLayout.d.ts","sourceRoot":"","sources":["../../../src/components/app-layout/AppLayout.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"AppLayout.d.ts","sourceRoot":"","sources":["../../../src/components/app-layout/AppLayout.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,4BAA4B,EAI5B,4BAA4B,EAE5B,cAAc,EACf,MAAM,sBAAsB,CAAC;AA4D9B,iBAAS,cAAc,CAAC,EACtB,QAAQ,EACR,SAAS,EACT,IAAI,EACJ,QAAgB,EAChB,KAAK,EACL,GAAG,KAAK,EACT,EAAE,4BAA4B,+BA2D9B;AAgED,eAAO,MAAM,SAAS;;;;;;;;CAMpB,CAAC"}
|
|
@@ -1,77 +1,147 @@
|
|
|
1
|
-
import
|
|
2
|
-
import NavigationItems from "./navigation-items/NavigationItems.js";
|
|
3
|
-
import { forwardRef, useId, useState } from "react";
|
|
1
|
+
import { createContext, forwardRef, useContext, useState } from "react";
|
|
4
2
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
3
|
//#region src/components/app-layout/AppLayout.tsx
|
|
6
|
-
var
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
if (collapsed === void 0) setInternalCollapsed(nextCollapsed);
|
|
19
|
-
onCollapsedChange?.(nextCollapsed);
|
|
20
|
-
};
|
|
21
|
-
const handleToggle = (id) => {
|
|
22
|
-
setExpandedIds((current) => {
|
|
23
|
-
const next = new Set(current);
|
|
24
|
-
if (next.has(id)) next.delete(id);
|
|
25
|
-
else next.add(id);
|
|
26
|
-
return next;
|
|
27
|
-
});
|
|
28
|
-
};
|
|
29
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
30
|
-
...rootProps,
|
|
31
|
-
className: rootClassName,
|
|
4
|
+
var LayoutContext = createContext(null);
|
|
5
|
+
var NavigationContext = createContext(false);
|
|
6
|
+
function useLayout(part) {
|
|
7
|
+
const context = useContext(LayoutContext);
|
|
8
|
+
if (context === null) throw new Error(`AppLayout.${part} must be rendered within AppLayout.`);
|
|
9
|
+
return context;
|
|
10
|
+
}
|
|
11
|
+
var Header = forwardRef(function Header({ children, className, ...props }, ref) {
|
|
12
|
+
useLayout("Header");
|
|
13
|
+
return /* @__PURE__ */ jsx("header", {
|
|
14
|
+
...props,
|
|
15
|
+
className: ["chayns-app-layout__header", className].filter(Boolean).join(" "),
|
|
32
16
|
ref,
|
|
33
|
-
children
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
17
|
+
children
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
var Logo = forwardRef(function Logo({ alt = "", className, ...props }, ref) {
|
|
21
|
+
useLayout("Logo");
|
|
22
|
+
return /* @__PURE__ */ jsx("img", {
|
|
23
|
+
...props,
|
|
24
|
+
alt,
|
|
25
|
+
className: ["chayns-app-layout__logo", className].filter(Boolean).join(" "),
|
|
26
|
+
ref
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
var Navigation = forwardRef(function Navigation({ children, className, ...props }, ref) {
|
|
30
|
+
useLayout("Navigation");
|
|
31
|
+
return /* @__PURE__ */ jsx(NavigationContext.Provider, {
|
|
32
|
+
value: true,
|
|
33
|
+
children: /* @__PURE__ */ jsx("nav", {
|
|
34
|
+
...props,
|
|
35
|
+
className: ["chayns-app-layout__navigation", className].filter(Boolean).join(" "),
|
|
36
|
+
ref,
|
|
37
|
+
children: /* @__PURE__ */ jsx("ul", {
|
|
38
|
+
className: "chayns-app-layout__list",
|
|
39
|
+
children
|
|
40
|
+
})
|
|
41
|
+
})
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
function NavigationItem({ children, className, href, isActive = false, label, ...props }) {
|
|
45
|
+
if (!useContext(NavigationContext)) throw new Error("AppLayout.Navigation.Item must be rendered within AppLayout.Navigation.");
|
|
46
|
+
const { collapsed } = useLayout("Navigation.Item");
|
|
47
|
+
const [expanded, setExpanded] = useState(false);
|
|
48
|
+
const hasChildren = children !== void 0;
|
|
49
|
+
const content = /* @__PURE__ */ jsx("span", {
|
|
50
|
+
className: `chayns-app-layout__label${collapsed ? " chayns-app-layout__label--hidden" : ""}`,
|
|
51
|
+
children: label
|
|
52
|
+
});
|
|
53
|
+
const actionClass = ["chayns-app-layout__action", className].filter(Boolean).join(" ");
|
|
54
|
+
return /* @__PURE__ */ jsxs("li", {
|
|
55
|
+
className: `chayns-app-layout__item${isActive ? " chayns-app-layout__item--active" : ""}`,
|
|
56
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
57
|
+
className: "chayns-app-layout__row",
|
|
58
|
+
children: [href ? /* @__PURE__ */ jsx("a", {
|
|
59
|
+
...props,
|
|
60
|
+
"aria-current": isActive ? "page" : void 0,
|
|
61
|
+
className: actionClass,
|
|
62
|
+
href,
|
|
63
|
+
children: content
|
|
64
|
+
}) : /* @__PURE__ */ jsx("button", {
|
|
65
|
+
...props,
|
|
66
|
+
"aria-current": isActive ? "page" : void 0,
|
|
67
|
+
className: actionClass,
|
|
68
|
+
type: "button",
|
|
69
|
+
children: content
|
|
70
|
+
}), hasChildren && !collapsed ? /* @__PURE__ */ jsx("button", {
|
|
71
|
+
"aria-label": typeof label === "string" ? label : void 0,
|
|
72
|
+
"aria-expanded": expanded,
|
|
73
|
+
className: "chayns-app-layout__disclosure",
|
|
74
|
+
onClick: () => setExpanded((current) => !current),
|
|
75
|
+
type: "button",
|
|
76
|
+
children: "⌄"
|
|
77
|
+
}) : null]
|
|
78
|
+
}), hasChildren && !collapsed ? /* @__PURE__ */ jsx("div", {
|
|
79
|
+
"aria-hidden": !expanded,
|
|
80
|
+
className: `chayns-app-layout__children${expanded ? " chayns-app-layout__children--open" : ""}`,
|
|
81
|
+
inert: !expanded,
|
|
82
|
+
children: /* @__PURE__ */ jsx("ul", {
|
|
83
|
+
className: "chayns-app-layout__list",
|
|
69
84
|
children
|
|
70
85
|
})
|
|
71
|
-
]
|
|
86
|
+
}) : null]
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
var Content = forwardRef(function Content({ children, className, ...props }, ref) {
|
|
90
|
+
useLayout("Content");
|
|
91
|
+
return /* @__PURE__ */ jsx("main", {
|
|
92
|
+
...props,
|
|
93
|
+
className: ["chayns-app-layout__content", className].filter(Boolean).join(" "),
|
|
94
|
+
ref,
|
|
95
|
+
children
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
var CollapseToggle = forwardRef(function CollapseToggle({ children = "☰", className, collapseLabel, expandLabel, onClick, ...props }, ref) {
|
|
99
|
+
const layout = useLayout("CollapseToggle");
|
|
100
|
+
return /* @__PURE__ */ jsx("button", {
|
|
101
|
+
...props,
|
|
102
|
+
"aria-label": layout.collapsed ? expandLabel : collapseLabel,
|
|
103
|
+
className: ["chayns-app-layout__collapse", className].filter(Boolean).join(" "),
|
|
104
|
+
onClick: (event) => {
|
|
105
|
+
onClick?.(event);
|
|
106
|
+
if (!event.defaultPrevented) layout.toggle();
|
|
107
|
+
},
|
|
108
|
+
ref,
|
|
109
|
+
type: "button",
|
|
110
|
+
children
|
|
72
111
|
});
|
|
73
112
|
});
|
|
74
|
-
|
|
113
|
+
var Root = forwardRef(function Root({ children, className, collapsed, defaultCollapsed = false, onCollapsedChange, ...props }, ref) {
|
|
114
|
+
const [internal, setInternal] = useState(defaultCollapsed);
|
|
115
|
+
const isCollapsed = collapsed ?? internal;
|
|
116
|
+
const toggle = () => {
|
|
117
|
+
const next = !isCollapsed;
|
|
118
|
+
if (collapsed === void 0) setInternal(next);
|
|
119
|
+
onCollapsedChange?.(next);
|
|
120
|
+
};
|
|
121
|
+
return /* @__PURE__ */ jsx(LayoutContext.Provider, {
|
|
122
|
+
value: {
|
|
123
|
+
collapsed: isCollapsed,
|
|
124
|
+
toggle
|
|
125
|
+
},
|
|
126
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
127
|
+
...props,
|
|
128
|
+
className: [
|
|
129
|
+
"chayns-app-layout",
|
|
130
|
+
isCollapsed && "chayns-app-layout--collapsed",
|
|
131
|
+
className
|
|
132
|
+
].filter(Boolean).join(" "),
|
|
133
|
+
ref,
|
|
134
|
+
children
|
|
135
|
+
})
|
|
136
|
+
});
|
|
137
|
+
});
|
|
138
|
+
var AppLayout = Object.assign(Root, {
|
|
139
|
+
CollapseToggle,
|
|
140
|
+
Content,
|
|
141
|
+
Header,
|
|
142
|
+
Logo,
|
|
143
|
+
Navigation: Object.assign(Navigation, { Item: NavigationItem })
|
|
144
|
+
});
|
|
75
145
|
//#endregion
|
|
76
146
|
export { AppLayout };
|
|
77
147
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AppLayout.js","names":[],"sources":["../../../src/components/app-layout/AppLayout.tsx"],"sourcesContent":["import { forwardRef,
|
|
1
|
+
{"version":3,"file":"AppLayout.js","names":[],"sources":["../../../src/components/app-layout/AppLayout.tsx"],"sourcesContent":["import { createContext, forwardRef, useContext, useState } from 'react';\nimport type { ComponentPropsWithRef } from 'react';\nimport type {\n AppLayoutCollapseToggleProps,\n AppLayoutContentProps,\n AppLayoutHeaderProps,\n AppLayoutLogoProps,\n AppLayoutNavigationItemProps,\n AppLayoutNavigationProps,\n AppLayoutProps,\n} from './AppLayout.types.js';\n\ninterface LayoutState {\n collapsed: boolean;\n toggle: () => void;\n}\nconst LayoutContext = createContext<LayoutState | null>(null);\nconst NavigationContext = createContext(false);\nfunction useLayout(part: string) {\n const context = useContext(LayoutContext);\n if (context === null) throw new Error(`AppLayout.${part} must be rendered within AppLayout.`);\n return context;\n}\n\nconst Header = forwardRef<HTMLElement, AppLayoutHeaderProps>(function Header(\n { children, className, ...props },\n ref,\n) {\n useLayout('Header');\n return (\n <header\n {...props}\n className={['chayns-app-layout__header', className].filter(Boolean).join(' ')}\n ref={ref}\n >\n {children}\n </header>\n );\n});\nconst Logo = forwardRef<HTMLImageElement, AppLayoutLogoProps>(function Logo(\n { alt = '', className, ...props },\n ref,\n) {\n useLayout('Logo');\n return (\n <img\n {...props}\n alt={alt}\n className={['chayns-app-layout__logo', className].filter(Boolean).join(' ')}\n ref={ref}\n />\n );\n});\nconst Navigation = forwardRef<HTMLElement, AppLayoutNavigationProps>(function Navigation(\n { children, className, ...props },\n ref,\n) {\n useLayout('Navigation');\n return (\n <NavigationContext.Provider value>\n <nav\n {...props}\n className={['chayns-app-layout__navigation', className].filter(Boolean).join(' ')}\n ref={ref}\n >\n <ul className=\"chayns-app-layout__list\">{children}</ul>\n </nav>\n </NavigationContext.Provider>\n );\n});\nfunction NavigationItem({\n children,\n className,\n href,\n isActive = false,\n label,\n ...props\n}: AppLayoutNavigationItemProps) {\n if (!useContext(NavigationContext))\n throw new Error('AppLayout.Navigation.Item must be rendered within AppLayout.Navigation.');\n const { collapsed } = useLayout('Navigation.Item');\n const [expanded, setExpanded] = useState(false);\n const hasChildren = children !== undefined;\n const content = (\n <span\n className={`chayns-app-layout__label${collapsed ? ' chayns-app-layout__label--hidden' : ''}`}\n >\n {label}\n </span>\n );\n const actionClass = ['chayns-app-layout__action', className].filter(Boolean).join(' ');\n return (\n <li className={`chayns-app-layout__item${isActive ? ' chayns-app-layout__item--active' : ''}`}>\n <div className=\"chayns-app-layout__row\">\n {href ? (\n <a\n {...(props as ComponentPropsWithRef<'a'>)}\n aria-current={isActive ? 'page' : undefined}\n className={actionClass}\n href={href}\n >\n {content}\n </a>\n ) : (\n <button\n {...props}\n aria-current={isActive ? 'page' : undefined}\n className={actionClass}\n type=\"button\"\n >\n {content}\n </button>\n )}\n {hasChildren && !collapsed ? (\n <button\n aria-label={typeof label === 'string' ? label : undefined}\n aria-expanded={expanded}\n className=\"chayns-app-layout__disclosure\"\n onClick={() => setExpanded((current) => !current)}\n type=\"button\"\n >\n ⌄\n </button>\n ) : null}\n </div>\n {hasChildren && !collapsed ? (\n <div\n aria-hidden={!expanded}\n className={`chayns-app-layout__children${expanded ? ' chayns-app-layout__children--open' : ''}`}\n inert={!expanded}\n >\n <ul className=\"chayns-app-layout__list\">{children}</ul>\n </div>\n ) : null}\n </li>\n );\n}\nconst Content = forwardRef<HTMLElement, AppLayoutContentProps>(function Content(\n { children, className, ...props },\n ref,\n) {\n useLayout('Content');\n return (\n <main\n {...props}\n className={['chayns-app-layout__content', className].filter(Boolean).join(' ')}\n ref={ref}\n >\n {children}\n </main>\n );\n});\nconst CollapseToggle = forwardRef<HTMLButtonElement, AppLayoutCollapseToggleProps>(\n function CollapseToggle(\n { children = '☰', className, collapseLabel, expandLabel, onClick, ...props },\n ref,\n ) {\n const layout = useLayout('CollapseToggle');\n return (\n <button\n {...props}\n aria-label={layout.collapsed ? expandLabel : collapseLabel}\n className={['chayns-app-layout__collapse', className].filter(Boolean).join(' ')}\n onClick={(event) => {\n onClick?.(event);\n if (!event.defaultPrevented) layout.toggle();\n }}\n ref={ref}\n type=\"button\"\n >\n {children}\n </button>\n );\n },\n);\nconst Root = forwardRef<HTMLDivElement, AppLayoutProps>(function Root(\n { children, className, collapsed, defaultCollapsed = false, onCollapsedChange, ...props },\n ref,\n) {\n const [internal, setInternal] = useState(defaultCollapsed);\n const isCollapsed = collapsed ?? internal;\n const toggle = () => {\n const next = !isCollapsed;\n if (collapsed === undefined) setInternal(next);\n onCollapsedChange?.(next);\n };\n return (\n <LayoutContext.Provider value={{ collapsed: isCollapsed, toggle }}>\n <div\n {...props}\n className={['chayns-app-layout', isCollapsed && 'chayns-app-layout--collapsed', className]\n .filter(Boolean)\n .join(' ')}\n ref={ref}\n >\n {children}\n </div>\n </LayoutContext.Provider>\n );\n});\nexport const AppLayout = Object.assign(Root, {\n CollapseToggle,\n Content,\n Header,\n Logo,\n Navigation: Object.assign(Navigation, { Item: NavigationItem }),\n});\n"],"mappings":"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"}
|
|
@@ -1,103 +1,23 @@
|
|
|
1
1
|
import type { ComponentPropsWithRef, ReactNode } from 'react';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
* @description Stable identifier passed to `onClick` and compared against
|
|
17
|
-
* `activeItemId`.
|
|
18
|
-
*/
|
|
19
|
-
id: string;
|
|
20
|
-
/**
|
|
21
|
-
* @description Visible, localized navigation label. Remains accessible for
|
|
22
|
-
* each item even while the sidebar is collapsed.
|
|
23
|
-
*/
|
|
24
|
-
name: string;
|
|
25
|
-
/**
|
|
26
|
-
* @description FontAwesome Classic icon name shown for this item, including
|
|
27
|
-
* in the collapsed sidebar.
|
|
28
|
-
*/
|
|
29
|
-
icon: AppLayoutIcon;
|
|
30
|
-
/**
|
|
31
|
-
* @description Nested child items, rendered behind this item's own
|
|
32
|
-
* disclosure control and hidden while the sidebar is collapsed.
|
|
33
|
-
*/
|
|
34
|
-
children?: AppLayoutItem[];
|
|
2
|
+
export interface AppLayoutProps extends Omit<ComponentPropsWithRef<'div'>, 'children'> {
|
|
3
|
+
children: ReactNode;
|
|
4
|
+
collapsed?: boolean;
|
|
5
|
+
defaultCollapsed?: boolean;
|
|
6
|
+
onCollapsedChange?: (collapsed: boolean) => void;
|
|
7
|
+
}
|
|
8
|
+
export type AppLayoutHeaderProps = ComponentPropsWithRef<'header'>;
|
|
9
|
+
export type AppLayoutLogoProps = ComponentPropsWithRef<'img'>;
|
|
10
|
+
export type AppLayoutNavigationProps = ComponentPropsWithRef<'nav'>;
|
|
11
|
+
export interface AppLayoutNavigationItemProps extends Omit<ComponentPropsWithRef<'button'>, 'children' | 'ref' | 'type'> {
|
|
12
|
+
label: ReactNode;
|
|
13
|
+
children?: ReactNode;
|
|
14
|
+
href?: string;
|
|
15
|
+
isActive?: boolean;
|
|
35
16
|
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
* logo, a collapsible sidebar of recursively nested navigation items, and a
|
|
39
|
-
* consumer-owned content area. Forwards all remaining native `div` props
|
|
40
|
-
* (except `children` and `onClick`, which have `AppLayout`-specific meaning),
|
|
41
|
-
* `className` and `ref`.
|
|
42
|
-
*/
|
|
43
|
-
export interface AppLayoutProps extends Omit<ComponentPropsWithRef<'div'>, 'children' | 'onClick'> {
|
|
44
|
-
/**
|
|
45
|
-
* @description URL of an image or SVG resource rendered as the header logo.
|
|
46
|
-
* Always decorative (`alt=""`); it does not itself provide any accessible
|
|
47
|
-
* name.
|
|
48
|
-
*/
|
|
49
|
-
logo: string;
|
|
50
|
-
/**
|
|
51
|
-
* @description Top-level navigation items, recursively composable via each
|
|
52
|
-
* item's own `children`. An empty array renders an empty navigation list.
|
|
53
|
-
*/
|
|
54
|
-
items: AppLayoutItem[];
|
|
55
|
-
/**
|
|
56
|
-
* @description Called with an item's `id` when that item's own action is
|
|
57
|
-
* activated, for both parent and child items. Toggling a parent's
|
|
58
|
-
* disclosure control does not call `onClick`.
|
|
59
|
-
*/
|
|
60
|
-
onClick: (id: string) => void;
|
|
61
|
-
/**
|
|
62
|
-
* @description Localized accessible name for the navigation landmark.
|
|
63
|
-
*/
|
|
64
|
-
navigationLabel: string;
|
|
65
|
-
/**
|
|
66
|
-
* @description Localized accessible name for the sidebar toggle control
|
|
67
|
-
* when activating it will collapse the sidebar.
|
|
68
|
-
*/
|
|
17
|
+
export type AppLayoutContentProps = ComponentPropsWithRef<'main'>;
|
|
18
|
+
export interface AppLayoutCollapseToggleProps extends Omit<ComponentPropsWithRef<'button'>, 'children' | 'type' | 'aria-label'> {
|
|
69
19
|
collapseLabel: string;
|
|
70
|
-
/**
|
|
71
|
-
* @description Localized accessible name for the sidebar toggle control
|
|
72
|
-
* when activating it will expand the sidebar.
|
|
73
|
-
*/
|
|
74
20
|
expandLabel: string;
|
|
75
|
-
/**
|
|
76
|
-
* @description `id` of the currently active navigation item. `AppLayout`
|
|
77
|
-
* only renders the active visual state; it does not derive or own
|
|
78
|
-
* activeness from routing.
|
|
79
|
-
*/
|
|
80
|
-
activeItemId?: string;
|
|
81
|
-
/**
|
|
82
|
-
* @description Consumer-provided content rendered in the area beside the
|
|
83
|
-
* sidebar. Owns its own internal semantics and scrolling.
|
|
84
|
-
*/
|
|
85
21
|
children?: ReactNode;
|
|
86
|
-
/**
|
|
87
|
-
* @description Controlled collapsed state of the sidebar.
|
|
88
|
-
*/
|
|
89
|
-
collapsed?: boolean;
|
|
90
|
-
/**
|
|
91
|
-
* @description Uncontrolled initial collapsed state of the sidebar.
|
|
92
|
-
* Persisting the collapsed state across sessions is outside `AppLayout`'s
|
|
93
|
-
* responsibility.
|
|
94
|
-
* @default false
|
|
95
|
-
*/
|
|
96
|
-
defaultCollapsed?: boolean;
|
|
97
|
-
/**
|
|
98
|
-
* @description Called with the next collapsed state when the sidebar
|
|
99
|
-
* toggle is activated, for both the controlled and uncontrolled usage.
|
|
100
|
-
*/
|
|
101
|
-
onCollapsedChange?: (collapsed: boolean) => void;
|
|
102
22
|
}
|
|
103
23
|
//# sourceMappingURL=AppLayout.types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AppLayout.types.d.ts","sourceRoot":"","sources":["../../../src/components/app-layout/AppLayout.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAE9D
|
|
1
|
+
{"version":3,"file":"AppLayout.types.d.ts","sourceRoot":"","sources":["../../../src/components/app-layout/AppLayout.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAE9D,MAAM,WAAW,cAAe,SAAQ,IAAI,CAAC,qBAAqB,CAAC,KAAK,CAAC,EAAE,UAAU,CAAC;IACpF,QAAQ,EAAE,SAAS,CAAC;IACpB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,iBAAiB,CAAC,EAAE,CAAC,SAAS,EAAE,OAAO,KAAK,IAAI,CAAC;CAClD;AACD,MAAM,MAAM,oBAAoB,GAAG,qBAAqB,CAAC,QAAQ,CAAC,CAAC;AACnE,MAAM,MAAM,kBAAkB,GAAG,qBAAqB,CAAC,KAAK,CAAC,CAAC;AAC9D,MAAM,MAAM,wBAAwB,GAAG,qBAAqB,CAAC,KAAK,CAAC,CAAC;AACpE,MAAM,WAAW,4BAA6B,SAAQ,IAAI,CACxD,qBAAqB,CAAC,QAAQ,CAAC,EAC/B,UAAU,GAAG,KAAK,GAAG,MAAM,CAC5B;IACC,KAAK,EAAE,SAAS,CAAC;IACjB,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AACD,MAAM,MAAM,qBAAqB,GAAG,qBAAqB,CAAC,MAAM,CAAC,CAAC;AAClE,MAAM,WAAW,4BAA6B,SAAQ,IAAI,CACxD,qBAAqB,CAAC,QAAQ,CAAC,EAC/B,UAAU,GAAG,MAAM,GAAG,YAAY,CACnC;IACC,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
type AppLayoutIconName = `fa-${string}`;
|
|
2
2
|
declare const AppLayoutIcon: ({ icon }: {
|
|
3
|
-
icon:
|
|
3
|
+
icon: AppLayoutIconName;
|
|
4
4
|
}) => import("react").JSX.Element;
|
|
5
5
|
export default AppLayoutIcon;
|
|
6
6
|
//# sourceMappingURL=AppLayoutIcon.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AppLayoutIcon.d.ts","sourceRoot":"","sources":["../../../../src/components/app-layout/app-layout-icon/AppLayoutIcon.tsx"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"AppLayoutIcon.d.ts","sourceRoot":"","sources":["../../../../src/components/app-layout/app-layout-icon/AppLayoutIcon.tsx"],"names":[],"mappings":"AAAA,KAAK,iBAAiB,GAAG,MAAM,MAAM,EAAE,CAAC;AAExC,QAAA,MAAM,aAAa,GAAI,UAAU;IAAE,IAAI,EAAE,iBAAiB,CAAA;CAAE,gCAS3D,CAAC;AAEF,eAAe,aAAa,CAAC"}
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
-
import type { TabsProps } from './Tabs.types.js';
|
|
2
|
-
export declare const Tabs: import("react").ForwardRefExoticComponent<Omit<TabsProps, "ref"> & import("react").RefAttributes<HTMLDivElement
|
|
1
|
+
import type { TabsPanelProps, TabsProps, TabsTabProps } from './Tabs.types.js';
|
|
2
|
+
export declare const Tabs: import("react").ForwardRefExoticComponent<Omit<TabsProps, "ref"> & import("react").RefAttributes<HTMLDivElement>> & {
|
|
3
|
+
Add: import("react").ForwardRefExoticComponent<Omit<import("react").DetailedHTMLProps<import("react").ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "ref"> & import("react").RefAttributes<HTMLButtonElement>>;
|
|
4
|
+
List: import("react").ForwardRefExoticComponent<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
|
|
5
|
+
Panel: import("react").ForwardRefExoticComponent<Omit<TabsPanelProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
|
|
6
|
+
Tab: import("react").ForwardRefExoticComponent<Omit<TabsTabProps, "ref"> & import("react").RefAttributes<HTMLButtonElement>>;
|
|
7
|
+
};
|
|
3
8
|
//# sourceMappingURL=Tabs.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Tabs.d.ts","sourceRoot":"","sources":["../../../src/components/tabs/Tabs.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Tabs.d.ts","sourceRoot":"","sources":["../../../src/components/tabs/Tabs.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAGV,cAAc,EACd,SAAS,EACT,YAAY,EACb,MAAM,iBAAiB,CAAC;AAuJzB,eAAO,MAAM,IAAI;;;;;CAAiD,CAAC"}
|
|
@@ -1,101 +1,127 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
1
|
+
import { createContext, forwardRef, useContext, useId, useState } from "react";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
4
3
|
//#region src/components/tabs/Tabs.tsx
|
|
5
|
-
var
|
|
6
|
-
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
4
|
+
var TabsContext = createContext(null);
|
|
5
|
+
function useTabs(part) {
|
|
6
|
+
const context = useContext(TabsContext);
|
|
7
|
+
if (context === null) throw new Error(`Tabs.${part} must be rendered within Tabs.`);
|
|
8
|
+
return context;
|
|
9
|
+
}
|
|
10
|
+
var List = forwardRef(function List({ children, className, ...props }, ref) {
|
|
11
|
+
useTabs("List");
|
|
12
|
+
return /* @__PURE__ */ jsx("div", {
|
|
13
|
+
...props,
|
|
14
|
+
className: ["chayns-tabs__list", className].filter(Boolean).join(" "),
|
|
15
|
+
ref,
|
|
16
|
+
role: "tablist",
|
|
17
|
+
children
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
var Tab = forwardRef(function Tab({ children, className, onRemove, onClick, value, ...props }, ref) {
|
|
21
|
+
const tabs = useTabs("Tab");
|
|
22
|
+
const selected = tabs.value === value;
|
|
23
|
+
const tabId = `${tabs.baseId}-tab-${value}`;
|
|
24
|
+
const panelId = `${tabs.baseId}-panel-${value}`;
|
|
25
|
+
function handleKeyDown(event) {
|
|
26
|
+
if ((event.key === "Delete" || event.key === "Backspace") && onRemove) {
|
|
17
27
|
event.preventDefault();
|
|
18
|
-
|
|
28
|
+
onRemove();
|
|
19
29
|
return;
|
|
20
30
|
}
|
|
21
|
-
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
const values = [...tabs.tabs.keys()];
|
|
32
|
+
const index = values.indexOf(value);
|
|
33
|
+
const nextIndex = event.key === "Home" ? 0 : event.key === "End" ? values.length - 1 : event.key === "ArrowRight" || event.key === "ArrowDown" ? (index + 1) % values.length : event.key === "ArrowLeft" || event.key === "ArrowUp" ? (index - 1 + values.length) % values.length : -1;
|
|
34
|
+
if (nextIndex >= 0) {
|
|
35
|
+
event.preventDefault();
|
|
36
|
+
const next = values[nextIndex];
|
|
37
|
+
if (next) {
|
|
38
|
+
tabs.select(next);
|
|
39
|
+
tabs.tabs.get(next)?.focus();
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
function setRef(node) {
|
|
44
|
+
if (node) tabs.tabs.set(value, node);
|
|
45
|
+
else tabs.tabs.delete(value);
|
|
46
|
+
if (typeof ref === "function") ref(node);
|
|
47
|
+
else if (ref) ref.current = node;
|
|
48
|
+
}
|
|
49
|
+
return /* @__PURE__ */ jsx("button", {
|
|
50
|
+
...props,
|
|
51
|
+
"aria-controls": panelId,
|
|
52
|
+
"aria-selected": selected,
|
|
53
|
+
className: [
|
|
54
|
+
"chayns-tabs__tab",
|
|
55
|
+
selected && "chayns-tabs__tab--active",
|
|
56
|
+
className
|
|
57
|
+
].filter(Boolean).join(" "),
|
|
58
|
+
id: tabId,
|
|
59
|
+
onClick: (event) => {
|
|
60
|
+
onClick?.(event);
|
|
61
|
+
if (!event.defaultPrevented) tabs.select(value);
|
|
62
|
+
},
|
|
63
|
+
onKeyDown: handleKeyDown,
|
|
64
|
+
ref: setRef,
|
|
65
|
+
role: "tab",
|
|
66
|
+
tabIndex: selected ? 0 : -1,
|
|
67
|
+
type: "button",
|
|
68
|
+
children
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
var Panel = forwardRef(function Panel({ children, className, value, ...props }, ref) {
|
|
72
|
+
const tabs = useTabs("Panel");
|
|
73
|
+
if (tabs.value !== value) return null;
|
|
74
|
+
return /* @__PURE__ */ jsx("div", {
|
|
75
|
+
...props,
|
|
76
|
+
"aria-labelledby": `${tabs.baseId}-tab-${value}`,
|
|
77
|
+
className: ["chayns-tabs__panel", className].filter(Boolean).join(" "),
|
|
78
|
+
id: `${tabs.baseId}-panel-${value}`,
|
|
33
79
|
ref,
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
className: "chayns-tabs__list",
|
|
38
|
-
role: "tablist",
|
|
39
|
-
children: tabs.map((tab, index) => {
|
|
40
|
-
const tabId = `${baseId}-tab-${index}`;
|
|
41
|
-
const panelId = `${baseId}-panel-${index}`;
|
|
42
|
-
const isSelected = index === activeIndex;
|
|
43
|
-
return /* @__PURE__ */ jsx("div", {
|
|
44
|
-
className: "chayns-tabs__item",
|
|
45
|
-
role: "presentation",
|
|
46
|
-
children: /* @__PURE__ */ jsxs("button", {
|
|
47
|
-
"aria-controls": isSelected ? panelId : void 0,
|
|
48
|
-
"aria-selected": isSelected,
|
|
49
|
-
className: `chayns-tabs__tab${isSelected ? " chayns-tabs__tab--active" : ""}`,
|
|
50
|
-
id: tabId,
|
|
51
|
-
onClick: (event) => {
|
|
52
|
-
if (event.target.closest("[data-tabs-remove]")) {
|
|
53
|
-
tab.onRemove?.();
|
|
54
|
-
return;
|
|
55
|
-
}
|
|
56
|
-
tab.onClick();
|
|
57
|
-
},
|
|
58
|
-
onKeyDown: (event) => handleKeyDown(event, index),
|
|
59
|
-
ref: (element) => {
|
|
60
|
-
tabRefs.current[index] = element;
|
|
61
|
-
},
|
|
62
|
-
role: "tab",
|
|
63
|
-
tabIndex: isSelected ? 0 : -1,
|
|
64
|
-
type: "button",
|
|
65
|
-
children: [
|
|
66
|
-
/* @__PURE__ */ jsx(TabsIcon, { icon: tab.icon }),
|
|
67
|
-
/* @__PURE__ */ jsx("span", {
|
|
68
|
-
className: "chayns-tabs__label",
|
|
69
|
-
children: tab.name
|
|
70
|
-
}),
|
|
71
|
-
tab.onRemove ? /* @__PURE__ */ jsx("span", {
|
|
72
|
-
"aria-hidden": "true",
|
|
73
|
-
className: "chayns-tabs__remove",
|
|
74
|
-
"data-tabs-remove": true,
|
|
75
|
-
children: /* @__PURE__ */ jsx(TabsIcon, { icon: "fa-xmark" })
|
|
76
|
-
}) : null
|
|
77
|
-
]
|
|
78
|
-
})
|
|
79
|
-
}, tabId);
|
|
80
|
-
})
|
|
81
|
-
}), onAdd && addLabel ? /* @__PURE__ */ jsx("button", {
|
|
82
|
-
"aria-label": addLabel,
|
|
83
|
-
className: "chayns-tabs__add",
|
|
84
|
-
onClick: onAdd,
|
|
85
|
-
type: "button",
|
|
86
|
-
children: /* @__PURE__ */ jsx(TabsIcon, { icon: "fa-plus" })
|
|
87
|
-
}) : null]
|
|
88
|
-
}), activeTab && activeTabId && activePanelId ? /* @__PURE__ */ jsx("div", {
|
|
89
|
-
"aria-labelledby": activeTabId,
|
|
90
|
-
className: "chayns-tabs__panel",
|
|
91
|
-
id: activePanelId,
|
|
92
|
-
role: "tabpanel",
|
|
93
|
-
tabIndex: 0,
|
|
94
|
-
children: activeTab.content
|
|
95
|
-
}) : null]
|
|
80
|
+
role: "tabpanel",
|
|
81
|
+
tabIndex: 0,
|
|
82
|
+
children
|
|
96
83
|
});
|
|
97
84
|
});
|
|
98
|
-
|
|
85
|
+
var Add = forwardRef(function Add({ children, className, ...props }, ref) {
|
|
86
|
+
useTabs("Add");
|
|
87
|
+
return /* @__PURE__ */ jsx("button", {
|
|
88
|
+
...props,
|
|
89
|
+
className: ["chayns-tabs__add", className].filter(Boolean).join(" "),
|
|
90
|
+
ref,
|
|
91
|
+
type: "button",
|
|
92
|
+
children
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
var Root = forwardRef(function Root({ children, className, defaultValue, onValueChange, value, ...props }, ref) {
|
|
96
|
+
const baseId = useId();
|
|
97
|
+
const [internalValue, setInternalValue] = useState(defaultValue);
|
|
98
|
+
const [tabMap] = useState(() => /* @__PURE__ */ new Map());
|
|
99
|
+
const selectedValue = value ?? internalValue;
|
|
100
|
+
const select = (next) => {
|
|
101
|
+
if (value === void 0) setInternalValue(next);
|
|
102
|
+
onValueChange?.(next);
|
|
103
|
+
};
|
|
104
|
+
return /* @__PURE__ */ jsx(TabsContext.Provider, {
|
|
105
|
+
value: {
|
|
106
|
+
baseId,
|
|
107
|
+
select,
|
|
108
|
+
tabs: tabMap,
|
|
109
|
+
value: selectedValue
|
|
110
|
+
},
|
|
111
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
112
|
+
...props,
|
|
113
|
+
className: ["chayns-tabs", className].filter(Boolean).join(" "),
|
|
114
|
+
ref,
|
|
115
|
+
children
|
|
116
|
+
})
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
var Tabs = Object.assign(Root, {
|
|
120
|
+
Add,
|
|
121
|
+
List,
|
|
122
|
+
Panel,
|
|
123
|
+
Tab
|
|
124
|
+
});
|
|
99
125
|
//#endregion
|
|
100
126
|
export { Tabs };
|
|
101
127
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Tabs.js","names":[],"sources":["../../../src/components/tabs/Tabs.tsx"],"sourcesContent":["import { forwardRef, useId,
|
|
1
|
+
{"version":3,"file":"Tabs.js","names":[],"sources":["../../../src/components/tabs/Tabs.tsx"],"sourcesContent":["import { createContext, forwardRef, useContext, useId, useState } from 'react';\nimport type { KeyboardEvent } from 'react';\nimport type {\n TabsAddProps,\n TabsListProps,\n TabsPanelProps,\n TabsProps,\n TabsTabProps,\n} from './Tabs.types.js';\n\ninterface TabsContextValue {\n baseId: string;\n select: (value: string) => void;\n tabs: Map<string, HTMLButtonElement>;\n value: string | undefined;\n}\nconst TabsContext = createContext<TabsContextValue | null>(null);\nfunction useTabs(part: string) {\n const context = useContext(TabsContext);\n if (context === null) throw new Error(`Tabs.${part} must be rendered within Tabs.`);\n return context;\n}\n\nconst List = forwardRef<HTMLDivElement, TabsListProps>(function List(\n { children, className, ...props },\n ref,\n) {\n useTabs('List');\n return (\n <div\n {...props}\n className={['chayns-tabs__list', className].filter(Boolean).join(' ')}\n ref={ref}\n role=\"tablist\"\n >\n {children}\n </div>\n );\n});\nconst Tab = forwardRef<HTMLButtonElement, TabsTabProps>(function Tab(\n { children, className, onRemove, onClick, value, ...props },\n ref,\n) {\n const tabs = useTabs('Tab');\n const selected = tabs.value === value;\n const tabId = `${tabs.baseId}-tab-${value}`;\n const panelId = `${tabs.baseId}-panel-${value}`;\n function handleKeyDown(event: KeyboardEvent<HTMLButtonElement>) {\n if ((event.key === 'Delete' || event.key === 'Backspace') && onRemove) {\n event.preventDefault();\n onRemove();\n return;\n }\n const values = [...tabs.tabs.keys()];\n const index = values.indexOf(value);\n const nextIndex =\n event.key === 'Home'\n ? 0\n : event.key === 'End'\n ? values.length - 1\n : event.key === 'ArrowRight' || event.key === 'ArrowDown'\n ? (index + 1) % values.length\n : event.key === 'ArrowLeft' || event.key === 'ArrowUp'\n ? (index - 1 + values.length) % values.length\n : -1;\n if (nextIndex >= 0) {\n event.preventDefault();\n const next = values[nextIndex];\n if (next) {\n tabs.select(next);\n tabs.tabs.get(next)?.focus();\n }\n }\n }\n function setRef(node: HTMLButtonElement | null) {\n if (node) tabs.tabs.set(value, node);\n else tabs.tabs.delete(value);\n if (typeof ref === 'function') ref(node);\n else if (ref) ref.current = node;\n }\n return (\n <button\n {...props}\n aria-controls={panelId}\n aria-selected={selected}\n className={['chayns-tabs__tab', selected && 'chayns-tabs__tab--active', className]\n .filter(Boolean)\n .join(' ')}\n id={tabId}\n onClick={(event) => {\n onClick?.(event);\n if (!event.defaultPrevented) tabs.select(value);\n }}\n onKeyDown={handleKeyDown}\n ref={setRef}\n role=\"tab\"\n tabIndex={selected ? 0 : -1}\n type=\"button\"\n >\n {children}\n </button>\n );\n});\nconst Panel = forwardRef<HTMLDivElement, TabsPanelProps>(function Panel(\n { children, className, value, ...props },\n ref,\n) {\n const tabs = useTabs('Panel');\n if (tabs.value !== value) return null;\n return (\n <div\n {...props}\n aria-labelledby={`${tabs.baseId}-tab-${value}`}\n className={['chayns-tabs__panel', className].filter(Boolean).join(' ')}\n id={`${tabs.baseId}-panel-${value}`}\n ref={ref}\n role=\"tabpanel\"\n tabIndex={0}\n >\n {children}\n </div>\n );\n});\nconst Add = forwardRef<HTMLButtonElement, TabsAddProps>(function Add(\n { children, className, ...props },\n ref,\n) {\n useTabs('Add');\n return (\n <button\n {...props}\n className={['chayns-tabs__add', className].filter(Boolean).join(' ')}\n ref={ref}\n type=\"button\"\n >\n {children}\n </button>\n );\n});\nconst Root = forwardRef<HTMLDivElement, TabsProps>(function Root(\n { children, className, defaultValue, onValueChange, value, ...props },\n ref,\n) {\n const baseId = useId();\n const [internalValue, setInternalValue] = useState(defaultValue);\n const [tabMap] = useState(() => new Map<string, HTMLButtonElement>());\n const selectedValue = value ?? internalValue;\n const select = (next: string) => {\n if (value === undefined) setInternalValue(next);\n onValueChange?.(next);\n };\n return (\n <TabsContext.Provider value={{ baseId, select, tabs: tabMap, value: selectedValue }}>\n <div {...props} className={['chayns-tabs', className].filter(Boolean).join(' ')} ref={ref}>\n {children}\n </div>\n </TabsContext.Provider>\n );\n});\nexport const Tabs = Object.assign(Root, { Add, List, Panel, Tab });\n"],"mappings":"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"}
|
|
@@ -1,69 +1,19 @@
|
|
|
1
1
|
import type { ComponentPropsWithRef, ReactNode } from 'react';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
export interface TabsEntry {
|
|
13
|
-
/**
|
|
14
|
-
* @description FontAwesome Classic icon name shown on the tab trigger.
|
|
15
|
-
*/
|
|
16
|
-
icon: TabsIcon;
|
|
17
|
-
/**
|
|
18
|
-
* @description Visible, already-resolved localized tab label.
|
|
19
|
-
*/
|
|
20
|
-
name: string;
|
|
21
|
-
/**
|
|
22
|
-
* @description Whether this entry is the currently selected tab. Exactly
|
|
23
|
-
* one entry in a `tabs` array is expected to be active at a time; the
|
|
24
|
-
* consumer, not `Tabs`, is responsible for keeping this consistent.
|
|
25
|
-
*/
|
|
26
|
-
isActive: boolean;
|
|
27
|
-
/**
|
|
28
|
-
* @description Called when this tab's trigger is activated. The consumer
|
|
29
|
-
* is expected to update `isActive` in response.
|
|
30
|
-
*/
|
|
31
|
-
onClick: () => void;
|
|
32
|
-
/**
|
|
33
|
-
* @description Optional remove handler. When supplied, a remove affordance
|
|
34
|
-
* is rendered as part of the same native tab button, and `Delete` or
|
|
35
|
-
* `Backspace` triggers it while the tab is focused.
|
|
36
|
-
*/
|
|
2
|
+
export interface TabsProps extends Omit<ComponentPropsWithRef<'div'>, 'children'> {
|
|
3
|
+
children: ReactNode;
|
|
4
|
+
value?: string;
|
|
5
|
+
defaultValue?: string;
|
|
6
|
+
onValueChange?: (value: string) => void;
|
|
7
|
+
}
|
|
8
|
+
export type TabsListProps = ComponentPropsWithRef<'div'>;
|
|
9
|
+
export interface TabsTabProps extends Omit<ComponentPropsWithRef<'button'>, 'aria-controls' | 'aria-selected' | 'children' | 'role' | 'tabIndex' | 'type'> {
|
|
10
|
+
value: string;
|
|
11
|
+
children: ReactNode;
|
|
37
12
|
onRemove?: () => void;
|
|
38
|
-
/**
|
|
39
|
-
* @description Peer panel content for this tab. Only the active entry's
|
|
40
|
-
* `content` is rendered.
|
|
41
|
-
*/
|
|
42
|
-
content: ReactNode;
|
|
43
13
|
}
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
* translation; selection state lives entirely in `tabs[].isActive`. Forwards
|
|
48
|
-
* remaining native `div` props (except `children`, which `Tabs` derives from
|
|
49
|
-
* `tabs`), `className` and `ref`.
|
|
50
|
-
*/
|
|
51
|
-
export interface TabsProps extends Omit<ComponentPropsWithRef<'div'>, 'children'> {
|
|
52
|
-
/**
|
|
53
|
-
* @description Ordered tab entries; exactly one should have `isActive`
|
|
54
|
-
* `true`.
|
|
55
|
-
*/
|
|
56
|
-
tabs: TabsEntry[];
|
|
57
|
-
/**
|
|
58
|
-
* @description Optional handler that renders an add-tab trigger when
|
|
59
|
-
* supplied together with `addLabel`.
|
|
60
|
-
*/
|
|
61
|
-
onAdd?: () => void;
|
|
62
|
-
/**
|
|
63
|
-
* @description Localized accessible name for the add-tab trigger. Required
|
|
64
|
-
* for the add trigger to render; supplying `onAdd` without `addLabel` does
|
|
65
|
-
* not render the control.
|
|
66
|
-
*/
|
|
67
|
-
addLabel?: string;
|
|
14
|
+
export interface TabsPanelProps extends Omit<ComponentPropsWithRef<'div'>, 'aria-labelledby' | 'children' | 'role'> {
|
|
15
|
+
value: string;
|
|
16
|
+
children: ReactNode;
|
|
68
17
|
}
|
|
18
|
+
export type TabsAddProps = ComponentPropsWithRef<'button'>;
|
|
69
19
|
//# sourceMappingURL=Tabs.types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Tabs.types.d.ts","sourceRoot":"","sources":["../../../src/components/tabs/Tabs.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAE9D
|
|
1
|
+
{"version":3,"file":"Tabs.types.d.ts","sourceRoot":"","sources":["../../../src/components/tabs/Tabs.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAE9D,MAAM,WAAW,SAAU,SAAQ,IAAI,CAAC,qBAAqB,CAAC,KAAK,CAAC,EAAE,UAAU,CAAC;IAC/E,QAAQ,EAAE,SAAS,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACzC;AACD,MAAM,MAAM,aAAa,GAAG,qBAAqB,CAAC,KAAK,CAAC,CAAC;AACzD,MAAM,WAAW,YAAa,SAAQ,IAAI,CACxC,qBAAqB,CAAC,QAAQ,CAAC,EAC/B,eAAe,GAAG,eAAe,GAAG,UAAU,GAAG,MAAM,GAAG,UAAU,GAAG,MAAM,CAC9E;IACC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,SAAS,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;CACvB;AACD,MAAM,WAAW,cAAe,SAAQ,IAAI,CAC1C,qBAAqB,CAAC,KAAK,CAAC,EAC5B,iBAAiB,GAAG,UAAU,GAAG,MAAM,CACxC;IACC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,SAAS,CAAC;CACrB;AACD,MAAM,MAAM,YAAY,GAAG,qBAAqB,CAAC,QAAQ,CAAC,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
type TabsIconName = `fa-${string}`;
|
|
2
2
|
declare const TabsIcon: ({ icon }: {
|
|
3
|
-
icon:
|
|
3
|
+
icon: TabsIconName;
|
|
4
4
|
}) => import("react").JSX.Element;
|
|
5
5
|
export default TabsIcon;
|
|
6
6
|
//# sourceMappingURL=TabsIcon.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TabsIcon.d.ts","sourceRoot":"","sources":["../../../../src/components/tabs/tabs-icon/TabsIcon.tsx"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"TabsIcon.d.ts","sourceRoot":"","sources":["../../../../src/components/tabs/tabs-icon/TabsIcon.tsx"],"names":[],"mappings":"AAAA,KAAK,YAAY,GAAG,MAAM,MAAM,EAAE,CAAC;AAEnC,QAAA,MAAM,QAAQ,GAAI,UAAU;IAAE,IAAI,EAAE,YAAY,CAAA;CAAE,gCAIjD,CAAC;AAEF,eAAe,QAAQ,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { AppLayout } from './components/app-layout/AppLayout.js';
|
|
2
|
-
export type {
|
|
2
|
+
export type { AppLayoutCollapseToggleProps, AppLayoutContentProps, AppLayoutHeaderProps, AppLayoutLogoProps, AppLayoutNavigationItemProps, AppLayoutNavigationProps, AppLayoutProps, } from './components/app-layout/AppLayout.types.js';
|
|
3
3
|
export { Tabs } from './components/tabs/Tabs.js';
|
|
4
|
-
export type {
|
|
4
|
+
export type { TabsAddProps, TabsListProps, TabsPanelProps, TabsProps, TabsTabProps, } from './components/tabs/Tabs.types.js';
|
|
5
5
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,sCAAsC,CAAC;AACjE,YAAY,EACV,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,sCAAsC,CAAC;AACjE,YAAY,EACV,4BAA4B,EAC5B,qBAAqB,EACrB,oBAAoB,EACpB,kBAAkB,EAClB,4BAA4B,EAC5B,wBAAwB,EACxB,cAAc,GACf,MAAM,4CAA4C,CAAC;AACpD,OAAO,EAAE,IAAI,EAAE,MAAM,2BAA2B,CAAC;AACjD,YAAY,EACV,YAAY,EACZ,aAAa,EACb,cAAc,EACd,SAAS,EACT,YAAY,GACb,MAAM,iCAAiC,CAAC"}
|
package/dist/tabs.css
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@chayns-ui/layout",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Accessible application layout components for chayns UI",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -28,11 +28,11 @@
|
|
|
28
28
|
"./package.json": "./package.json"
|
|
29
29
|
},
|
|
30
30
|
"peerDependencies": {
|
|
31
|
-
"@chayns-ui/core": ">=0.
|
|
31
|
+
"@chayns-ui/core": ">=0.4.0",
|
|
32
32
|
"react": ">=18 <20"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
|
-
"@chayns-ui/core": "0.
|
|
35
|
+
"@chayns-ui/core": "0.4.0"
|
|
36
36
|
},
|
|
37
37
|
"engines": {
|
|
38
38
|
"node": ">=18"
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
-
//#region src/components/app-layout/app-layout-icon/AppLayoutIcon.tsx
|
|
3
|
-
var AppLayoutIcon = ({ icon }) => /* @__PURE__ */ jsxs("span", {
|
|
4
|
-
"aria-hidden": "true",
|
|
5
|
-
className: "chayns-app-layout__icon",
|
|
6
|
-
children: [/* @__PURE__ */ jsx("span", {
|
|
7
|
-
className: "chayns-app-layout__weight",
|
|
8
|
-
children: /* @__PURE__ */ jsx("i", { className: `far ${icon}` })
|
|
9
|
-
}), /* @__PURE__ */ jsx("span", {
|
|
10
|
-
className: "chayns-app-layout__weight chayns-app-layout__weight--active",
|
|
11
|
-
children: /* @__PURE__ */ jsx("i", { className: `fas ${icon}` })
|
|
12
|
-
})]
|
|
13
|
-
});
|
|
14
|
-
//#endregion
|
|
15
|
-
export { AppLayoutIcon as default };
|
|
16
|
-
|
|
17
|
-
//# sourceMappingURL=AppLayoutIcon.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"AppLayoutIcon.js","names":[],"sources":["../../../../src/components/app-layout/app-layout-icon/AppLayoutIcon.tsx"],"sourcesContent":["import type { AppLayoutItem } from '../AppLayout.types.js';\n\nconst AppLayoutIcon = ({ icon }: { icon: AppLayoutItem['icon'] }) => (\n <span aria-hidden=\"true\" className=\"chayns-app-layout__icon\">\n <span className=\"chayns-app-layout__weight\">\n <i className={`far ${icon}`} />\n </span>\n <span className=\"chayns-app-layout__weight chayns-app-layout__weight--active\">\n <i className={`fas ${icon}`} />\n </span>\n </span>\n);\n\nexport default AppLayoutIcon;\n"],"mappings":";;AAEA,IAAM,iBAAiB,EAAE,WACvB,qBAAC,QAAD;CAAM,eAAY;CAAO,WAAU;CAAnC,UAAA,CACE,oBAAC,QAAD;EAAM,WAAU;EACd,UAAA,oBAAC,KAAD,EAAG,WAAW,OAAO,OAAS,CAAA;CAC1B,CAAA,GACN,oBAAC,QAAD;EAAM,WAAU;EACd,UAAA,oBAAC,KAAD,EAAG,WAAW,OAAO,OAAS,CAAA;CAC1B,CAAA,CACF"}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import type { AppLayoutItem } from '../AppLayout.types.js';
|
|
2
|
-
interface NavigationItemsProps {
|
|
3
|
-
items: AppLayoutItem[];
|
|
4
|
-
activeItemId?: string | undefined;
|
|
5
|
-
collapsed: boolean;
|
|
6
|
-
onClick: (id: string) => void;
|
|
7
|
-
expandedIds: ReadonlySet<string>;
|
|
8
|
-
onToggle: (id: string) => void;
|
|
9
|
-
parentId?: string;
|
|
10
|
-
}
|
|
11
|
-
declare const NavigationItems: ({ activeItemId, collapsed, expandedIds, items, onClick, onToggle, parentId, }: NavigationItemsProps) => import("react").JSX.Element;
|
|
12
|
-
export default NavigationItems;
|
|
13
|
-
//# sourceMappingURL=NavigationItems.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"NavigationItems.d.ts","sourceRoot":"","sources":["../../../../src/components/app-layout/navigation-items/NavigationItems.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAE3D,UAAU,oBAAoB;IAC5B,KAAK,EAAE,aAAa,EAAE,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9B,WAAW,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACjC,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,QAAA,MAAM,eAAe,GAAI,+EAQtB,oBAAoB,gCAoEtB,CAAC;AAEF,eAAe,eAAe,CAAC"}
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
import AppLayoutIcon from "../app-layout-icon/AppLayoutIcon.js";
|
|
2
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
-
//#region src/components/app-layout/navigation-items/NavigationItems.tsx
|
|
4
|
-
var NavigationItems = ({ activeItemId, collapsed, expandedIds, items, onClick, onToggle, parentId }) => /* @__PURE__ */ jsx("ul", {
|
|
5
|
-
className: "chayns-app-layout__list",
|
|
6
|
-
children: items.map((item) => {
|
|
7
|
-
const hasChildren = Boolean(item.children?.length);
|
|
8
|
-
const isExpanded = expandedIds.has(item.id);
|
|
9
|
-
const panelId = `${parentId ?? "root"}-${item.id}-children`;
|
|
10
|
-
return /* @__PURE__ */ jsxs("li", {
|
|
11
|
-
className: `chayns-app-layout__item${activeItemId === item.id ? " chayns-app-layout__item--active" : ""}`,
|
|
12
|
-
children: [/* @__PURE__ */ jsxs("div", {
|
|
13
|
-
className: "chayns-app-layout__row",
|
|
14
|
-
children: [/* @__PURE__ */ jsxs("button", {
|
|
15
|
-
"aria-current": activeItemId === item.id ? "page" : void 0,
|
|
16
|
-
"aria-label": item.name,
|
|
17
|
-
className: "chayns-app-layout__action",
|
|
18
|
-
onClick: () => onClick(item.id),
|
|
19
|
-
type: "button",
|
|
20
|
-
children: [/* @__PURE__ */ jsx(AppLayoutIcon, { icon: item.icon }), /* @__PURE__ */ jsx("span", {
|
|
21
|
-
className: `chayns-app-layout__label${collapsed ? " chayns-app-layout__label--hidden" : ""}`,
|
|
22
|
-
children: item.name
|
|
23
|
-
})]
|
|
24
|
-
}), hasChildren && !collapsed ? /* @__PURE__ */ jsx("button", {
|
|
25
|
-
"aria-controls": panelId,
|
|
26
|
-
"aria-expanded": isExpanded,
|
|
27
|
-
"aria-label": item.name,
|
|
28
|
-
className: "chayns-app-layout__disclosure",
|
|
29
|
-
onClick: () => onToggle(item.id),
|
|
30
|
-
type: "button",
|
|
31
|
-
children: /* @__PURE__ */ jsx(AppLayoutIcon, { icon: "fa-chevron-down" })
|
|
32
|
-
}) : null]
|
|
33
|
-
}), hasChildren && !collapsed ? /* @__PURE__ */ jsx("div", {
|
|
34
|
-
"aria-hidden": !isExpanded,
|
|
35
|
-
className: `chayns-app-layout__children${isExpanded ? " chayns-app-layout__children--open" : ""}`,
|
|
36
|
-
id: panelId,
|
|
37
|
-
inert: !isExpanded,
|
|
38
|
-
children: /* @__PURE__ */ jsx(NavigationItems, {
|
|
39
|
-
activeItemId,
|
|
40
|
-
collapsed,
|
|
41
|
-
expandedIds,
|
|
42
|
-
items: item.children ?? [],
|
|
43
|
-
onClick,
|
|
44
|
-
onToggle,
|
|
45
|
-
parentId: item.id
|
|
46
|
-
})
|
|
47
|
-
}) : null]
|
|
48
|
-
}, item.id);
|
|
49
|
-
})
|
|
50
|
-
});
|
|
51
|
-
//#endregion
|
|
52
|
-
export { NavigationItems as default };
|
|
53
|
-
|
|
54
|
-
//# sourceMappingURL=NavigationItems.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"NavigationItems.js","names":[],"sources":["../../../../src/components/app-layout/navigation-items/NavigationItems.tsx"],"sourcesContent":["import AppLayoutIcon from '../app-layout-icon/AppLayoutIcon.js';\nimport type { AppLayoutItem } from '../AppLayout.types.js';\n\ninterface NavigationItemsProps {\n items: AppLayoutItem[];\n activeItemId?: string | undefined;\n collapsed: boolean;\n onClick: (id: string) => void;\n expandedIds: ReadonlySet<string>;\n onToggle: (id: string) => void;\n parentId?: string;\n}\n\nconst NavigationItems = ({\n activeItemId,\n collapsed,\n expandedIds,\n items,\n onClick,\n onToggle,\n parentId,\n}: NavigationItemsProps) => (\n <ul className=\"chayns-app-layout__list\">\n {items.map((item) => {\n const hasChildren = Boolean(item.children?.length);\n const isExpanded = expandedIds.has(item.id);\n const panelId = `${parentId ?? 'root'}-${item.id}-children`;\n\n return (\n <li\n className={`chayns-app-layout__item${\n activeItemId === item.id ? ' chayns-app-layout__item--active' : ''\n }`}\n key={item.id}\n >\n <div className=\"chayns-app-layout__row\">\n <button\n aria-current={activeItemId === item.id ? 'page' : undefined}\n aria-label={item.name}\n className=\"chayns-app-layout__action\"\n onClick={() => onClick(item.id)}\n type=\"button\"\n >\n <AppLayoutIcon icon={item.icon} />\n <span\n className={`chayns-app-layout__label${\n collapsed ? ' chayns-app-layout__label--hidden' : ''\n }`}\n >\n {item.name}\n </span>\n </button>\n {hasChildren && !collapsed ? (\n <button\n aria-controls={panelId}\n aria-expanded={isExpanded}\n aria-label={item.name}\n className=\"chayns-app-layout__disclosure\"\n onClick={() => onToggle(item.id)}\n type=\"button\"\n >\n <AppLayoutIcon icon=\"fa-chevron-down\" />\n </button>\n ) : null}\n </div>\n {hasChildren && !collapsed ? (\n <div\n aria-hidden={!isExpanded}\n className={`chayns-app-layout__children${\n isExpanded ? ' chayns-app-layout__children--open' : ''\n }`}\n id={panelId}\n inert={!isExpanded}\n >\n <NavigationItems\n activeItemId={activeItemId}\n collapsed={collapsed}\n expandedIds={expandedIds}\n items={item.children ?? []}\n onClick={onClick}\n onToggle={onToggle}\n parentId={item.id}\n />\n </div>\n ) : null}\n </li>\n );\n })}\n </ul>\n);\n\nexport default NavigationItems;\n"],"mappings":";;;AAaA,IAAM,mBAAmB,EACvB,cACA,WACA,aACA,OACA,SACA,UACA,eAEA,oBAAC,MAAD;CAAI,WAAU;CACX,UAAA,MAAM,KAAK,SAAS;EACnB,MAAM,cAAc,QAAQ,KAAK,UAAU,MAAM;EACjD,MAAM,aAAa,YAAY,IAAI,KAAK,EAAE;EAC1C,MAAM,UAAU,GAAG,YAAY,OAAO,GAAG,KAAK,GAAG;EAEjD,OACE,qBAAC,MAAD;GACE,WAAW,0BACT,iBAAiB,KAAK,KAAK,qCAAqC;GAFpE,UAAA,CAME,qBAAC,OAAD;IAAK,WAAU;IAAf,UAAA,CACE,qBAAC,UAAD;KACE,gBAAc,iBAAiB,KAAK,KAAK,SAAS,KAAA;KAClD,cAAY,KAAK;KACjB,WAAU;KACV,eAAe,QAAQ,KAAK,EAAE;KAC9B,MAAK;KALP,UAAA,CAOE,oBAAC,eAAD,EAAe,MAAM,KAAK,KAAO,CAAA,GACjC,oBAAC,QAAD;MACE,WAAW,2BACT,YAAY,sCAAsC;MAGnD,UAAA,KAAK;KACF,CAAA,CACA;IACP,CAAA,GAAA,eAAe,CAAC,YACf,oBAAC,UAAD;KACE,iBAAe;KACf,iBAAe;KACf,cAAY,KAAK;KACjB,WAAU;KACV,eAAe,SAAS,KAAK,EAAE;KAC/B,MAAK;KAEL,UAAA,oBAAC,eAAD,EAAe,MAAK,kBAAmB,CAAA;IACjC,CAAA,IACN,IACD;GACJ,CAAA,GAAA,eAAe,CAAC,YACf,oBAAC,OAAD;IACE,eAAa,CAAC;IACd,WAAW,8BACT,aAAa,uCAAuC;IAEtD,IAAI;IACJ,OAAO,CAAC;IAER,UAAA,oBAAC,iBAAD;KACgB;KACH;KACE;KACb,OAAO,KAAK,YAAY,CAAC;KAChB;KACC;KACV,UAAU,KAAK;IAChB,CAAA;GACE,CAAA,IACH,IACF;EApDG,GAAA,KAAK,EAoDR;CAER,CAAC;AACC,CAAA"}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { jsx } from "react/jsx-runtime";
|
|
2
|
-
//#region src/components/tabs/tabs-icon/TabsIcon.tsx
|
|
3
|
-
var TabsIcon = ({ icon }) => /* @__PURE__ */ jsx("span", {
|
|
4
|
-
"aria-hidden": "true",
|
|
5
|
-
className: "chayns-tabs__icon",
|
|
6
|
-
children: /* @__PURE__ */ jsx("i", { className: `far ${icon}` })
|
|
7
|
-
});
|
|
8
|
-
//#endregion
|
|
9
|
-
export { TabsIcon as default };
|
|
10
|
-
|
|
11
|
-
//# sourceMappingURL=TabsIcon.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"TabsIcon.js","names":[],"sources":["../../../../src/components/tabs/tabs-icon/TabsIcon.tsx"],"sourcesContent":["import type { TabsEntry } from '../Tabs.types.js';\n\nconst TabsIcon = ({ icon }: { icon: TabsEntry['icon'] }) => (\n <span aria-hidden=\"true\" className=\"chayns-tabs__icon\">\n <i className={`far ${icon}`} />\n </span>\n);\n\nexport default TabsIcon;\n"],"mappings":";;AAEA,IAAM,YAAY,EAAE,WAClB,oBAAC,QAAD;CAAM,eAAY;CAAO,WAAU;CACjC,UAAA,oBAAC,KAAD,EAAG,WAAW,OAAO,OAAS,CAAA;AAC1B,CAAA"}
|