@chayns-ui/layout 0.6.1 → 0.6.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.
- package/dist/app-layout.css +17 -1
- package/dist/components/app-layout/AppLayout.d.ts +1 -1
- package/dist/components/app-layout/AppLayout.d.ts.map +1 -1
- package/dist/components/app-layout/AppLayout.js +13 -9
- package/dist/components/app-layout/AppLayout.js.map +1 -1
- package/dist/components/app-layout/AppLayout.types.d.ts +2 -0
- package/dist/components/app-layout/AppLayout.types.d.ts.map +1 -1
- package/dist/components/app-layout/app-layout-icon/AppLayoutIcon.js +17 -0
- package/dist/components/app-layout/app-layout-icon/AppLayoutIcon.js.map +1 -0
- package/dist/components/tabs/Tabs.d.ts.map +1 -1
- package/dist/components/tabs/Tabs.js +15 -4
- package/dist/components/tabs/Tabs.js.map +1 -1
- package/dist/tabs.css +66 -49
- package/package.json +1 -1
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 > :not(.chayns-app-layout__logo) {
|
|
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__header-content {
|
|
22
31
|
display: flex;
|
|
23
32
|
flex: 1 1 auto;
|
|
@@ -43,8 +52,12 @@
|
|
|
43
52
|
}
|
|
44
53
|
|
|
45
54
|
.chayns-app-layout__navigation {
|
|
55
|
+
display: flex;
|
|
56
|
+
grid-area: sidebar;
|
|
57
|
+
flex-direction: column;
|
|
46
58
|
min-block-size: 0;
|
|
47
59
|
overflow: auto;
|
|
60
|
+
padding: 0 var(--sp-2) var(--sp-2);
|
|
48
61
|
}
|
|
49
62
|
|
|
50
63
|
.chayns-app-layout__list {
|
|
@@ -143,9 +156,12 @@
|
|
|
143
156
|
justify-content: center;
|
|
144
157
|
inline-size: var(--ctrl-h);
|
|
145
158
|
block-size: var(--ctrl-h);
|
|
146
|
-
align-self: flex-end;
|
|
147
159
|
border-radius: 50%;
|
|
148
160
|
background: transparent;
|
|
161
|
+
grid-area: sidebar;
|
|
162
|
+
place-self: end;
|
|
163
|
+
margin: 0 var(--sp-2) var(--sp-2) 0;
|
|
164
|
+
z-index: 1;
|
|
149
165
|
}
|
|
150
166
|
|
|
151
167
|
.chayns-app-layout__footer {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
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;
|
|
2
|
+
declare function NavigationItem({ children, className, href, icon, isActive, label, ...props }: AppLayoutNavigationItemProps): import("react").JSX.Element;
|
|
3
3
|
export declare const AppLayout: import("react").ForwardRefExoticComponent<Omit<AppLayoutProps, "ref"> & import("react").RefAttributes<HTMLDivElement>> & {
|
|
4
4
|
CollapseToggle: import("react").ForwardRefExoticComponent<Omit<AppLayoutCollapseToggleProps, "ref"> & import("react").RefAttributes<HTMLButtonElement>>;
|
|
5
5
|
Content: import("react").ForwardRefExoticComponent<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLElement>, HTMLElement>, "ref"> & import("react").RefAttributes<HTMLElement>>;
|
|
@@ -1 +1 @@
|
|
|
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;
|
|
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;AA6D9B,iBAAS,cAAc,CAAC,EACtB,QAAQ,EACR,SAAS,EACT,IAAI,EACJ,IAAI,EACJ,QAAgB,EAChB,KAAK,EACL,GAAG,KAAK,EACT,EAAE,4BAA4B,+BAgE9B;AAgED,eAAO,MAAM,SAAS;;;;;;;;CAMpB,CAAC"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import AppLayoutIcon from "./app-layout-icon/AppLayoutIcon.js";
|
|
2
|
+
import { createContext, forwardRef, useContext, useId, useState } from "react";
|
|
2
3
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
4
|
//#region src/components/app-layout/AppLayout.tsx
|
|
4
5
|
var LayoutContext = createContext(null);
|
|
@@ -41,10 +42,11 @@ var Navigation = forwardRef(function Navigation({ children, className, ...props
|
|
|
41
42
|
})
|
|
42
43
|
});
|
|
43
44
|
});
|
|
44
|
-
function NavigationItem({ children, className, href, isActive = false, label, ...props }) {
|
|
45
|
+
function NavigationItem({ children, className, href, icon, isActive = false, label, ...props }) {
|
|
45
46
|
if (!useContext(NavigationContext)) throw new Error("AppLayout.Navigation.Item must be rendered within AppLayout.Navigation.");
|
|
46
47
|
const { collapsed } = useLayout("Navigation.Item");
|
|
47
48
|
const [expanded, setExpanded] = useState(false);
|
|
49
|
+
const childrenId = useId();
|
|
48
50
|
const hasChildren = children !== void 0;
|
|
49
51
|
const content = /* @__PURE__ */ jsx("span", {
|
|
50
52
|
className: `chayns-app-layout__label${collapsed ? " chayns-app-layout__label--hidden" : ""}`,
|
|
@@ -55,29 +57,31 @@ function NavigationItem({ children, className, href, isActive = false, label, ..
|
|
|
55
57
|
className: `chayns-app-layout__item${isActive ? " chayns-app-layout__item--active" : ""}`,
|
|
56
58
|
children: [/* @__PURE__ */ jsxs("div", {
|
|
57
59
|
className: "chayns-app-layout__row",
|
|
58
|
-
children: [href ? /* @__PURE__ */
|
|
60
|
+
children: [href ? /* @__PURE__ */ jsxs("a", {
|
|
59
61
|
...props,
|
|
60
62
|
"aria-current": isActive ? "page" : void 0,
|
|
61
63
|
className: actionClass,
|
|
62
64
|
href,
|
|
63
|
-
children: content
|
|
64
|
-
}) : /* @__PURE__ */
|
|
65
|
+
children: [icon ? /* @__PURE__ */ jsx(AppLayoutIcon, { icon }) : null, content]
|
|
66
|
+
}) : /* @__PURE__ */ jsxs("button", {
|
|
65
67
|
...props,
|
|
66
68
|
"aria-current": isActive ? "page" : void 0,
|
|
67
69
|
className: actionClass,
|
|
68
70
|
type: "button",
|
|
69
|
-
children: content
|
|
71
|
+
children: [icon ? /* @__PURE__ */ jsx(AppLayoutIcon, { icon }) : null, content]
|
|
70
72
|
}), hasChildren && !collapsed ? /* @__PURE__ */ jsx("button", {
|
|
71
73
|
"aria-label": typeof label === "string" ? label : void 0,
|
|
74
|
+
"aria-controls": childrenId,
|
|
72
75
|
"aria-expanded": expanded,
|
|
73
76
|
className: "chayns-app-layout__disclosure",
|
|
74
77
|
onClick: () => setExpanded((current) => !current),
|
|
75
78
|
type: "button",
|
|
76
|
-
children: "
|
|
79
|
+
children: /* @__PURE__ */ jsx(AppLayoutIcon, { icon: "fa-chevron-down" })
|
|
77
80
|
}) : null]
|
|
78
81
|
}), hasChildren && !collapsed ? /* @__PURE__ */ jsx("div", {
|
|
79
82
|
"aria-hidden": !expanded,
|
|
80
83
|
className: `chayns-app-layout__children${expanded ? " chayns-app-layout__children--open" : ""}`,
|
|
84
|
+
id: childrenId,
|
|
81
85
|
inert: !expanded,
|
|
82
86
|
children: /* @__PURE__ */ jsx("ul", {
|
|
83
87
|
className: "chayns-app-layout__list",
|
|
@@ -95,7 +99,7 @@ var Content = forwardRef(function Content({ children, className, ...props }, ref
|
|
|
95
99
|
children
|
|
96
100
|
});
|
|
97
101
|
});
|
|
98
|
-
var CollapseToggle = forwardRef(function CollapseToggle({ children
|
|
102
|
+
var CollapseToggle = forwardRef(function CollapseToggle({ children, className, collapseLabel, expandLabel, onClick, ...props }, ref) {
|
|
99
103
|
const layout = useLayout("CollapseToggle");
|
|
100
104
|
return /* @__PURE__ */ jsx("button", {
|
|
101
105
|
...props,
|
|
@@ -107,7 +111,7 @@ var CollapseToggle = forwardRef(function CollapseToggle({ children = "☰", clas
|
|
|
107
111
|
},
|
|
108
112
|
ref,
|
|
109
113
|
type: "button",
|
|
110
|
-
children
|
|
114
|
+
children: children ?? /* @__PURE__ */ jsx(AppLayoutIcon, { icon: "fa-sidebar" })
|
|
111
115
|
});
|
|
112
116
|
});
|
|
113
117
|
var Root = forwardRef(function Root({ children, className, collapsed, defaultCollapsed = false, onCollapsedChange, ...props }, ref) {
|
|
@@ -1 +1 @@
|
|
|
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
|
|
1
|
+
{"version":3,"file":"AppLayout.js","names":[],"sources":["../../../src/components/app-layout/AppLayout.tsx"],"sourcesContent":["import { createContext, forwardRef, useContext, useId, 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';\nimport AppLayoutIcon from './app-layout-icon/AppLayoutIcon.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 icon,\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 childrenId = useId();\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 {icon ? <AppLayoutIcon icon={icon} /> : null}\n {content}\n </a>\n ) : (\n <button\n {...props}\n aria-current={isActive ? 'page' : undefined}\n className={actionClass}\n type=\"button\"\n >\n {icon ? <AppLayoutIcon icon={icon} /> : null}\n {content}\n </button>\n )}\n {hasChildren && !collapsed ? (\n <button\n aria-label={typeof label === 'string' ? label : undefined}\n aria-controls={childrenId}\n aria-expanded={expanded}\n className=\"chayns-app-layout__disclosure\"\n onClick={() => setExpanded((current) => !current)}\n type=\"button\"\n >\n <AppLayoutIcon icon=\"fa-chevron-down\" />\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 id={childrenId}\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 ?? <AppLayoutIcon icon=\"fa-sidebar\" />}\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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"}
|
|
@@ -9,6 +9,8 @@ export type AppLayoutHeaderProps = ComponentPropsWithRef<'header'>;
|
|
|
9
9
|
export type AppLayoutLogoProps = ComponentPropsWithRef<'img'>;
|
|
10
10
|
export type AppLayoutNavigationProps = ComponentPropsWithRef<'nav'>;
|
|
11
11
|
export interface AppLayoutNavigationItemProps extends Omit<ComponentPropsWithRef<'button'>, 'children' | 'ref' | 'type'> {
|
|
12
|
+
/** FontAwesome icon restored from the pre-compound navigation contract. */
|
|
13
|
+
icon?: `fa-${string}`;
|
|
12
14
|
label: ReactNode;
|
|
13
15
|
children?: ReactNode;
|
|
14
16
|
href?: string;
|
|
@@ -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,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
|
+
{"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,2EAA2E;IAC3E,IAAI,CAAC,EAAE,MAAM,MAAM,EAAE,CAAC;IACtB,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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
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
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AppLayoutIcon.js","names":[],"sources":["../../../../src/components/app-layout/app-layout-icon/AppLayoutIcon.tsx"],"sourcesContent":["type AppLayoutIconName = `fa-${string}`;\n\nconst AppLayoutIcon = ({ icon }: { icon: AppLayoutIconName }) => (\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 +1 @@
|
|
|
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;
|
|
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;AAmKzB,eAAO,MAAM,IAAI;;;;;CAAiD,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createContext, forwardRef, useContext, useId, useState } from "react";
|
|
2
|
-
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
3
|
//#region src/components/tabs/Tabs.tsx
|
|
4
4
|
var TabsContext = createContext(null);
|
|
5
5
|
function useTabs(part) {
|
|
@@ -17,12 +17,14 @@ var List = forwardRef(function List({ children, className, ...props }, ref) {
|
|
|
17
17
|
children
|
|
18
18
|
});
|
|
19
19
|
});
|
|
20
|
-
var Tab = forwardRef(function Tab({ children, className, onRemove, onClick, value, ...props }, ref) {
|
|
20
|
+
var Tab = forwardRef(function Tab({ children, className, onKeyDown, onRemove, onClick, value, ...props }, ref) {
|
|
21
21
|
const tabs = useTabs("Tab");
|
|
22
22
|
const selected = tabs.value === value;
|
|
23
23
|
const tabId = `${tabs.baseId}-tab-${value}`;
|
|
24
24
|
const panelId = `${tabs.baseId}-panel-${value}`;
|
|
25
25
|
function handleKeyDown(event) {
|
|
26
|
+
onKeyDown?.(event);
|
|
27
|
+
if (event.defaultPrevented) return;
|
|
26
28
|
if ((event.key === "Delete" || event.key === "Backspace") && onRemove) {
|
|
27
29
|
event.preventDefault();
|
|
28
30
|
onRemove();
|
|
@@ -46,7 +48,7 @@ var Tab = forwardRef(function Tab({ children, className, onRemove, onClick, valu
|
|
|
46
48
|
if (typeof ref === "function") ref(node);
|
|
47
49
|
else if (ref) ref.current = node;
|
|
48
50
|
}
|
|
49
|
-
return /* @__PURE__ */
|
|
51
|
+
return /* @__PURE__ */ jsxs("button", {
|
|
50
52
|
...props,
|
|
51
53
|
"aria-controls": panelId,
|
|
52
54
|
"aria-selected": selected,
|
|
@@ -57,6 +59,10 @@ var Tab = forwardRef(function Tab({ children, className, onRemove, onClick, valu
|
|
|
57
59
|
].filter(Boolean).join(" "),
|
|
58
60
|
id: tabId,
|
|
59
61
|
onClick: (event) => {
|
|
62
|
+
if (event.target.closest("[data-tabs-remove]")) {
|
|
63
|
+
onRemove?.();
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
60
66
|
onClick?.(event);
|
|
61
67
|
if (!event.defaultPrevented) tabs.select(value);
|
|
62
68
|
},
|
|
@@ -65,7 +71,12 @@ var Tab = forwardRef(function Tab({ children, className, onRemove, onClick, valu
|
|
|
65
71
|
role: "tab",
|
|
66
72
|
tabIndex: selected ? 0 : -1,
|
|
67
73
|
type: "button",
|
|
68
|
-
children
|
|
74
|
+
children: [children, onRemove ? /* @__PURE__ */ jsx("span", {
|
|
75
|
+
"aria-hidden": "true",
|
|
76
|
+
className: "chayns-tabs__remove",
|
|
77
|
+
"data-tabs-remove": true,
|
|
78
|
+
children: /* @__PURE__ */ jsx("i", { className: "far fa-xmark" })
|
|
79
|
+
}) : null]
|
|
69
80
|
});
|
|
70
81
|
});
|
|
71
82
|
var Panel = forwardRef(function Panel({ children, className, value, ...props }, ref) {
|
|
@@ -1 +1 @@
|
|
|
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":";;;AAgBA,IAAM,cAAc,cAAuC,IAAI;AAC/D,SAAS,QAAQ,MAAc;CAC7B,MAAM,UAAU,WAAW,WAAW;CACtC,IAAI,YAAY,MAAM,MAAM,IAAI,MAAM,QAAQ,KAAK,+BAA+B;CAClF,OAAO;AACT;AAEA,IAAM,OAAO,WAA0C,SAAS,KAC9D,EAAE,UAAU,WAAW,GAAG,SAC1B,KACA;CACA,QAAQ,MAAM;CACd,OACE,oBAAC,OAAD;EACE,GAAI;EACJ,WAAW,CAAC,qBAAqB,SAAS,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,GAAG;EAC/D;EACL,MAAK;EAEJ;CACE,CAAA;AAET,CAAC;AACD,IAAM,MAAM,WAA4C,SAAS,IAC/D,EAAE,UAAU,WAAW,UAAU,SAAS,OAAO,GAAG,
|
|
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, onKeyDown, 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 onKeyDown?.(event);\n if (event.defaultPrevented) return;\n\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 if ((event.target as HTMLElement).closest('[data-tabs-remove]')) {\n onRemove?.();\n return;\n }\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 {onRemove ? (\n <span aria-hidden=\"true\" className=\"chayns-tabs__remove\" data-tabs-remove>\n <i className=\"far fa-xmark\" />\n </span>\n ) : null}\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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"}
|
package/dist/tabs.css
CHANGED
|
@@ -1,91 +1,108 @@
|
|
|
1
1
|
@layer chayns.components {
|
|
2
2
|
.chayns-tabs {
|
|
3
|
+
position: relative;
|
|
3
4
|
display: flex;
|
|
4
5
|
flex-direction: column;
|
|
6
|
+
container-type: inline-size;
|
|
7
|
+
inline-size: 100%;
|
|
8
|
+
block-size: 100%;
|
|
5
9
|
min-inline-size: 0;
|
|
6
10
|
}
|
|
7
11
|
|
|
8
12
|
.chayns-tabs__list {
|
|
9
13
|
display: flex;
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
14
|
+
gap: var(--sp-1);
|
|
15
|
+
align-items: stretch;
|
|
16
|
+
block-size: var(--ctrl-h);
|
|
13
17
|
min-inline-size: 0;
|
|
18
|
+
overflow-x: auto;
|
|
19
|
+
padding-inline-end: var(--ctrl-h);
|
|
20
|
+
background: transparent;
|
|
14
21
|
}
|
|
15
22
|
|
|
16
|
-
.chayns-tabs__tab
|
|
17
|
-
.chayns-tabs__add {
|
|
23
|
+
.chayns-tabs__tab {
|
|
18
24
|
display: inline-flex;
|
|
25
|
+
flex: 0 0 auto;
|
|
19
26
|
align-items: center;
|
|
20
27
|
justify-content: center;
|
|
28
|
+
gap: var(--sp-2);
|
|
29
|
+
block-size: var(--ctrl-h);
|
|
30
|
+
min-block-size: var(--ctrl-h);
|
|
31
|
+
min-inline-size: var(--ctrl-h);
|
|
32
|
+
padding-block: 0;
|
|
33
|
+
padding-inline: var(--sp-3) var(--sp-2);
|
|
21
34
|
border: 0;
|
|
35
|
+
border-radius: var(--k12) var(--k12) 0 0;
|
|
36
|
+
color: var(--on-accent);
|
|
22
37
|
font: inherit;
|
|
23
38
|
cursor: pointer;
|
|
24
|
-
|
|
25
|
-
background 0.2s ease,
|
|
26
|
-
color 0.2s ease,
|
|
27
|
-
box-shadow 0.2s ease,
|
|
28
|
-
transform 0.15s ease;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
.chayns-tabs__tab {
|
|
32
|
-
gap: var(--k8);
|
|
33
|
-
padding: var(--k8) var(--k15);
|
|
34
|
-
border-radius: 999px;
|
|
35
|
-
background: var(--surface-alt);
|
|
36
|
-
color: var(--text-2);
|
|
37
|
-
font-size: var(--fs-body);
|
|
38
|
-
font-weight: 500;
|
|
39
|
-
line-height: 1.1;
|
|
39
|
+
background: color-mix(in srgb, var(--surface) 10%, transparent);
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
.chayns-tabs__tab--active {
|
|
43
|
-
background: var(--
|
|
44
|
-
color: var(--on-accent);
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
.chayns-tabs__add {
|
|
48
|
-
inline-size: var(--k32);
|
|
49
|
-
block-size: var(--k32);
|
|
50
|
-
padding: 0;
|
|
51
|
-
border-radius: 50%;
|
|
52
|
-
background: var(--surface-alt);
|
|
43
|
+
background: var(--surface);
|
|
53
44
|
color: var(--accent);
|
|
54
|
-
font-size: var(--fs-meta);
|
|
55
45
|
}
|
|
56
46
|
|
|
57
|
-
.chayns-
|
|
58
|
-
|
|
59
|
-
|
|
47
|
+
.chayns-tabs__add {
|
|
48
|
+
display: inline-flex;
|
|
49
|
+
flex: 0 0 auto;
|
|
50
|
+
align-items: center;
|
|
51
|
+
justify-content: center;
|
|
52
|
+
inline-size: var(--ctrl-h);
|
|
53
|
+
block-size: var(--ctrl-h);
|
|
54
|
+
min-block-size: var(--ctrl-h);
|
|
55
|
+
padding: 0 var(--sp-2);
|
|
56
|
+
border: 0;
|
|
57
|
+
color: var(--on-accent);
|
|
58
|
+
font: inherit;
|
|
59
|
+
cursor: pointer;
|
|
60
|
+
background: transparent;
|
|
61
|
+
position: absolute;
|
|
62
|
+
inset-block-start: 0;
|
|
63
|
+
inset-inline-end: 0;
|
|
60
64
|
}
|
|
61
65
|
|
|
62
|
-
.chayns-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
+
.chayns-tabs__remove {
|
|
67
|
+
display: inline-flex;
|
|
68
|
+
flex: none;
|
|
69
|
+
align-items: center;
|
|
70
|
+
justify-content: center;
|
|
71
|
+
inline-size: var(--icon);
|
|
72
|
+
block-size: var(--icon);
|
|
73
|
+
margin-inline-start: calc(var(--sp-2) * -1);
|
|
74
|
+
color: inherit;
|
|
66
75
|
}
|
|
67
76
|
|
|
68
|
-
.chayns-
|
|
69
|
-
|
|
70
|
-
transform: scale(0.97);
|
|
77
|
+
.chayns-tabs__remove > i {
|
|
78
|
+
font-size: var(--fs-meta);
|
|
71
79
|
}
|
|
72
80
|
|
|
73
81
|
.chayns-tabs__tab:focus-visible,
|
|
74
82
|
.chayns-tabs__add:focus-visible {
|
|
75
|
-
outline:
|
|
76
|
-
|
|
83
|
+
outline: none;
|
|
84
|
+
box-shadow: inset 0 0 0 var(--focus-ring-size)
|
|
85
|
+
rgb(var(--focus-ring-rgb), var(--focus-ring-alpha-strong));
|
|
77
86
|
}
|
|
78
87
|
|
|
79
88
|
.chayns-tabs__panel {
|
|
89
|
+
flex: 1 1 auto;
|
|
80
90
|
min-inline-size: 0;
|
|
81
|
-
|
|
91
|
+
min-block-size: 0;
|
|
92
|
+
padding: var(--sp-2);
|
|
93
|
+
overflow: auto;
|
|
94
|
+
background: var(--surface);
|
|
82
95
|
color: var(--text);
|
|
83
96
|
}
|
|
84
97
|
|
|
85
|
-
@
|
|
86
|
-
.chayns-
|
|
87
|
-
|
|
88
|
-
|
|
98
|
+
@container (max-width: 20rem) {
|
|
99
|
+
.chayns-tabs__label {
|
|
100
|
+
position: absolute;
|
|
101
|
+
inline-size: 1px;
|
|
102
|
+
block-size: 1px;
|
|
103
|
+
overflow: hidden;
|
|
104
|
+
clip-path: inset(50%);
|
|
105
|
+
white-space: nowrap;
|
|
89
106
|
}
|
|
90
107
|
}
|
|
91
108
|
}
|