@sybilion/uilib 1.2.12 → 1.2.14
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/esm/components/ui/Page/PageContent/PageContent.js +2 -2
- package/dist/esm/components/ui/Page/PageContent/PageContent.styl.js +2 -2
- package/dist/esm/components/ui/Page/PageFooter/PageFooter.js +23 -2
- package/dist/esm/components/ui/Page/PageFooter/PageFooter.styl.js +2 -2
- package/dist/esm/components/ui/Tabs/Tabs.js +2 -2
- package/dist/esm/components/ui/Tabs/Tabs.styl.js +2 -2
- package/dist/esm/hooks/index.js +1 -0
- package/dist/esm/index.js +1 -0
- package/dist/esm/types/src/components/ui/Page/PageContent/PageContent.d.ts +2 -1
- package/dist/esm/types/src/components/ui/Page/PageFooter/PageFooter.d.ts +13 -1
- package/dist/esm/types/src/components/ui/Page/index.d.ts +1 -1
- package/dist/esm/types/src/components/ui/Tabs/Tabs.d.ts +2 -1
- package/dist/esm/types/src/docs/pages/PageFooterPage.d.ts +1 -0
- package/dist/esm/types/src/docs/pages/PageTabsPage.d.ts +1 -0
- package/dist/esm/types/src/hooks/index.d.ts +1 -0
- package/dist/esm/types/src/index.d.ts +1 -0
- package/package.json +6 -1
- package/src/components/ui/Page/PageContent/PageContent.styl +3 -1
- package/src/components/ui/Page/PageContent/PageContent.styl.d.ts +1 -0
- package/src/components/ui/Page/PageContent/PageContent.tsx +3 -1
- package/src/components/ui/Page/PageFooter/PageFooter.styl +21 -1
- package/src/components/ui/Page/PageFooter/PageFooter.styl.d.ts +3 -0
- package/src/components/ui/Page/PageFooter/PageFooter.tsx +57 -13
- package/src/components/ui/Page/index.ts +4 -1
- package/src/components/ui/Tabs/Tabs.styl +38 -0
- package/src/components/ui/Tabs/Tabs.styl.d.ts +2 -0
- package/src/components/ui/Tabs/Tabs.tsx +8 -1
- package/src/docs/pages/PageFooterPage.styl +10 -0
- package/src/docs/pages/PageFooterPage.styl.d.ts +8 -0
- package/src/docs/pages/PageFooterPage.tsx +99 -0
- package/src/docs/pages/PageTabsPage.tsx +60 -0
- package/src/docs/pages/TabsPage.tsx +106 -10
- package/src/docs/registry.ts +12 -0
- package/src/hooks/index.ts +1 -0
- package/src/index.ts +1 -0
|
@@ -5,8 +5,8 @@ import S from './PageContent.styl.js';
|
|
|
5
5
|
function PageContent({ className, children, variant = 'default', }) {
|
|
6
6
|
return (jsx("div", { className: cn(S.root, S[`variant-${variant}`], className), children: children }));
|
|
7
7
|
}
|
|
8
|
-
function PageContentSection({ className, children, ...rest }) {
|
|
9
|
-
return (jsx("div", { className: cn(S.section, className), ...rest, children: children }));
|
|
8
|
+
function PageContentSection({ className, children, grow = true, ...rest }) {
|
|
9
|
+
return (jsx("div", { className: cn(S.section, className, grow && S.grow), ...rest, children: children }));
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
export { PageContent, PageContentSection };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import styleInject from 'style-inject';
|
|
2
2
|
|
|
3
|
-
var css_248z = "@media (max-width:768px){:root{--page-x-padding:var(--p-6);--page-y-padding:var(--p-6)}}.PageContent_root__caExB{max-width:var(--page-width);padding-bottom:var(--page-y-padding);width:100%}.
|
|
4
|
-
var S = {"root":"PageContent_root__caExB","section":"PageContent_section__Wve-w"};
|
|
3
|
+
var css_248z = "@media (max-width:768px){:root{--page-x-padding:var(--p-6);--page-y-padding:var(--p-6)}}.PageContent_root__caExB{display:flex;flex:1;flex-direction:column;max-width:var(--page-width);min-height:0;padding-bottom:var(--page-y-padding);width:100%}.PageContent_section__Wve-w{display:flex;flex-direction:column;min-height:0;padding-left:var(--page-x-padding);padding-right:var(--page-x-padding)}.PageContent_grow__Nkfqk{flex-grow:1}";
|
|
4
|
+
var S = {"root":"PageContent_root__caExB","section":"PageContent_section__Wve-w","grow":"PageContent_grow__Nkfqk"};
|
|
5
5
|
styleInject(css_248z);
|
|
6
6
|
|
|
7
7
|
export { S as default };
|
|
@@ -3,8 +3,29 @@ import { Link } from 'react-router-dom';
|
|
|
3
3
|
import { GlobeIcon, MailIcon } from 'lucide-react';
|
|
4
4
|
import S from './PageFooter.styl.js';
|
|
5
5
|
|
|
6
|
-
function
|
|
7
|
-
|
|
6
|
+
function PageFooterLinkEl({ item }) {
|
|
7
|
+
const { label, url, ariaLabel } = item;
|
|
8
|
+
const openInNewTab = /^https?:\/\//i.test(url);
|
|
9
|
+
return (jsx("a", { href: url, className: S.link, ...(ariaLabel !== undefined ? { 'aria-label': ariaLabel } : {}), ...(openInNewTab ? { target: '_blank', rel: 'noreferrer' } : {}), children: label }));
|
|
10
|
+
}
|
|
11
|
+
function PageFooter({ children, versionLink, versionLabel, homeTo = '/', brandText = 'Sybilion', logo, websiteHref = 'https://sybilion.com', mailHref = 'mailto:support@sybilion.com', copyrightText = '© 2026 Sybilion. All rights reserved.', links: linksProp, }) {
|
|
12
|
+
const resolvedLinks = linksProp !== undefined
|
|
13
|
+
? linksProp
|
|
14
|
+
: [
|
|
15
|
+
{
|
|
16
|
+
id: 'website',
|
|
17
|
+
label: jsx(GlobeIcon, { "aria-hidden": true }),
|
|
18
|
+
url: websiteHref,
|
|
19
|
+
ariaLabel: 'Visit Sybilion website',
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
id: 'email',
|
|
23
|
+
label: jsx(MailIcon, { "aria-hidden": true }),
|
|
24
|
+
url: mailHref,
|
|
25
|
+
ariaLabel: 'Contact support via email',
|
|
26
|
+
},
|
|
27
|
+
];
|
|
28
|
+
return (jsx("footer", { className: S.root, children: jsxs("div", { className: S.line, children: [jsxs("div", { className: S.logo, children: [jsxs(Link, { to: homeTo, children: [logo, "\u00A0", brandText] }), versionLink !== '' && (jsx("div", { className: S.version, children: jsx(Link, { to: versionLink, className: S.versionLink, children: versionLabel }) }))] }), children, jsxs("div", { className: S.meta, children: [jsx("div", { className: S.copyright, children: copyrightText }), resolvedLinks.length > 0 && (jsx("nav", { className: S.links, "aria-label": "Footer links", children: resolvedLinks.map(item => (jsx(PageFooterLinkEl, { item: item }, item.id))) }))] })] }) }));
|
|
8
29
|
}
|
|
9
30
|
|
|
10
31
|
export { PageFooter };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import styleInject from 'style-inject';
|
|
2
2
|
|
|
3
|
-
var css_248z = "@media (max-width:768px){:root{--page-x-padding:var(--p-6);--page-y-padding:var(--p-6)}}.PageFooter_root__TAfX6{display:flex;flex-direction:column;gap:6px;padding:var(--p-5) var(--p-10)}.PageFooter_line__OyGA-{align-items:center;display:flex;flex-wrap:wrap;justify-content:space-between}.PageFooter_line__OyGA-:last-child{min-height:55px}.
|
|
4
|
-
var S = {"root":"PageFooter_root__TAfX6","line":"PageFooter_line__OyGA-","copyright":"PageFooter_copyright__4LFUP","logo":"PageFooter_logo__B2SRg","version":"PageFooter_version__8pZXn","versionLink":"PageFooter_versionLink__dILP5"};
|
|
3
|
+
var css_248z = "@media (max-width:768px){:root{--page-x-padding:var(--p-6);--page-y-padding:var(--p-6)}}.PageFooter_root__TAfX6{display:flex;flex-direction:column;gap:6px;padding:var(--p-5) var(--p-10)}.PageFooter_line__OyGA-{align-items:center;display:flex;flex-wrap:wrap;justify-content:space-between}.PageFooter_line__OyGA-:last-child{min-height:55px}.PageFooter_meta__Gvenf{align-items:center;display:flex;flex-wrap:wrap;gap:var(--p-4)}.PageFooter_copyright__4LFUP{font-size:14px}.PageFooter_links__q5BXo{align-items:center;display:flex;flex-wrap:wrap;gap:var(--p-4)}.PageFooter_link__mel3N{align-items:center;color:var(--foreground);display:inline-flex;font-size:14px;gap:var(--p-2);text-decoration:none}.PageFooter_link__mel3N:hover{text-decoration:underline}.PageFooter_link__mel3N svg{color:var(--brand-color-400);flex-shrink:0;height:20px;width:20px}.PageFooter_logo__B2SRg{align-items:center;display:flex;font-size:var(--text-2xl);position:relative}.PageFooter_logo__B2SRg a{align-items:center;color:var(--foreground);display:flex;gap:var(--p-2);text-decoration:none}.PageFooter_logo__B2SRg svg{height:24px;width:24px}.PageFooter_version__8pZXn{align-items:center;bottom:5px;color:var(--muted-foreground);display:flex;font-size:14px;left:calc(100% + 10px);opacity:.5;position:absolute;transition:opacity .3s ease-out;white-space:nowrap}.PageFooter_version__8pZXn:before{content:\"v\"}.PageFooter_versionLink__dILP5{color:inherit;text-decoration:none}.PageFooter_logo__B2SRg:hover .PageFooter_version__8pZXn{opacity:1}";
|
|
4
|
+
var S = {"root":"PageFooter_root__TAfX6","line":"PageFooter_line__OyGA-","meta":"PageFooter_meta__Gvenf","copyright":"PageFooter_copyright__4LFUP","links":"PageFooter_links__q5BXo","link":"PageFooter_link__mel3N","logo":"PageFooter_logo__B2SRg","version":"PageFooter_version__8pZXn","versionLink":"PageFooter_versionLink__dILP5"};
|
|
5
5
|
styleInject(css_248z);
|
|
6
6
|
|
|
7
7
|
export { S as default };
|
|
@@ -3,8 +3,8 @@ import cn from 'classnames';
|
|
|
3
3
|
import * as TabsPrimitive from '@radix-ui/react-tabs';
|
|
4
4
|
import S from './Tabs.styl.js';
|
|
5
5
|
|
|
6
|
-
function Tabs({ className, variant = 'button', darker = false, ...props }) {
|
|
7
|
-
return (jsx(TabsPrimitive.Root, { "data-slot": "tabs", className: cn(S.root, S[`variant-${variant}`], darker && S.darker, className), ...props }));
|
|
6
|
+
function Tabs({ className, variant = 'button', size = 'md', darker = false, ...props }) {
|
|
7
|
+
return (jsx(TabsPrimitive.Root, { "data-slot": "tabs", className: cn(S.root, S[`variant-${variant}`], size === 'sm' && S.sizeSm, size === 'lg' && S.sizeLg, darker && S.darker, className), ...props }));
|
|
8
8
|
}
|
|
9
9
|
function TabsList({ className, fullWidth, darker, ...props }) {
|
|
10
10
|
return (jsx(TabsPrimitive.List, { "data-slot": "tabs-list", className: cn(S.list, fullWidth && S.fullWidth, darker && S.darker, className), ...props }));
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import styleInject from 'style-inject';
|
|
2
2
|
|
|
3
|
-
var css_248z = ".Tabs_root__cB9Au{display:flex;flex-direction:column;gap:.5rem}.Tabs_list__9Hs22{align-items:center;color:var(--muted-foreground);display:inline-flex;height:48px;justify-content:center;width:-moz-fit-content;width:fit-content}.Tabs_list__9Hs22.Tabs_fullWidth__Lj2Dd{width:100%}.Tabs_variant-link__xOMDg>.Tabs_list__9Hs22{background-color:transparent!important}.Tabs_variant-button__wtc8k .Tabs_list__9Hs22{border-radius:1.5rem;box-shadow:none;gap:.25rem;height:auto}.Tabs_trigger__uzdqH{align-items:center;border:1px solid transparent;border-radius:.375rem;color:var(--muted-foreground);cursor:pointer;display:inline-flex;flex:1;font-size:var(--text-sm);font-weight:500;gap:.375rem;height:calc(100% - 1px);justify-content:center;padding:.25rem .5rem;transition:color .2s,box-shadow .2s;white-space:nowrap}.Tabs_trigger__uzdqH:focus-visible{border-color:var(--ring);box-shadow:0 0 0 3px var(--ring-50);outline:1px solid var(--ring);outline-offset:0}.Tabs_trigger__uzdqH:disabled{opacity:.5;pointer-events:none}.Tabs_trigger__uzdqH[data-state=active]{background-color:var(--background);box-shadow:0 1px 2px 0 rgba(0,0,0,.05)}.Tabs_trigger__uzdqH:hover,.Tabs_trigger__uzdqH[data-state=active]{color:var(--foreground)!important}.Tabs_darker__l-R0I .Tabs_trigger__uzdqH{background-color:var(--muted)}.Tabs_variant-button__wtc8k .Tabs_list__9Hs22 .Tabs_trigger__uzdqH{border:none;border-radius:var(--p-4);box-shadow:none;color:var(--muted-foreground);flex-shrink:0;font-weight:600;padding:var(--p-1) var(--p-3);transition:all .15s ease-in-out}.Tabs_variant-button__wtc8k .Tabs_list__9Hs22 .Tabs_trigger__uzdqH[data-state=active]{border-radius:var(--p-6);box-shadow:0 1px 2px 0 rgba(0,0,0,.05);color:var(--foreground)}.Tabs_variant-link__xOMDg>.Tabs_list__9Hs22 .Tabs_trigger__uzdqH{background-color:transparent!important;border:0!important;border-radius:0!important;box-shadow:0!important;font-size:16px;padding:12px 16px}.Tabs_variant-link__xOMDg>.Tabs_list__9Hs22 .Tabs_trigger__uzdqH[data-state=active]{box-shadow:inset 0 -3px 0 -1px var(--sb-cyan-400)!important}.Tabs_trigger__uzdqH svg{flex-shrink:0;pointer-events:none}.Tabs_trigger__uzdqH svg:not([class*=size-]){height:1rem;width:1rem}.dark .Tabs_trigger__uzdqH{color:var(--muted-foreground)}.dark .Tabs_trigger__uzdqH[data-state=active]{background-color:var(--input-30);border-color:var(--input);color:var(--foreground)}.Tabs_content__K27Vl{flex:1;outline:none}";
|
|
4
|
-
var S = {"root":"Tabs_root__cB9Au","list":"Tabs_list__9Hs22","fullWidth":"Tabs_fullWidth__Lj2Dd","variant-link":"Tabs_variant-link__xOMDg","variant-button":"Tabs_variant-button__wtc8k","trigger":"Tabs_trigger__uzdqH","darker":"Tabs_darker__l-R0I","content":"Tabs_content__K27Vl"};
|
|
3
|
+
var css_248z = ".Tabs_root__cB9Au{display:flex;flex-direction:column;gap:.5rem}.Tabs_list__9Hs22{align-items:center;color:var(--muted-foreground);display:inline-flex;height:48px;justify-content:center;width:-moz-fit-content;width:fit-content}.Tabs_list__9Hs22.Tabs_fullWidth__Lj2Dd{width:100%}.Tabs_variant-link__xOMDg>.Tabs_list__9Hs22{background-color:transparent!important}.Tabs_variant-button__wtc8k .Tabs_list__9Hs22{border-radius:1.5rem;box-shadow:none;gap:.25rem;height:auto}.Tabs_trigger__uzdqH{align-items:center;border:1px solid transparent;border-radius:.375rem;color:var(--muted-foreground);cursor:pointer;display:inline-flex;flex:1;font-size:var(--text-sm);font-weight:500;gap:.375rem;height:calc(100% - 1px);justify-content:center;padding:.25rem .5rem;transition:color .2s,box-shadow .2s;white-space:nowrap}.Tabs_trigger__uzdqH:focus-visible{border-color:var(--ring);box-shadow:0 0 0 3px var(--ring-50);outline:1px solid var(--ring);outline-offset:0}.Tabs_trigger__uzdqH:disabled{opacity:.5;pointer-events:none}.Tabs_trigger__uzdqH[data-state=active]{background-color:var(--background);box-shadow:0 1px 2px 0 rgba(0,0,0,.05)}.Tabs_trigger__uzdqH:hover,.Tabs_trigger__uzdqH[data-state=active]{color:var(--foreground)!important}.Tabs_darker__l-R0I .Tabs_trigger__uzdqH{background-color:var(--muted)}.Tabs_variant-button__wtc8k .Tabs_list__9Hs22 .Tabs_trigger__uzdqH{border:none;border-radius:var(--p-4);box-shadow:none;color:var(--muted-foreground);flex-shrink:0;font-weight:600;padding:var(--p-1) var(--p-3);transition:all .15s ease-in-out}.Tabs_variant-button__wtc8k .Tabs_list__9Hs22 .Tabs_trigger__uzdqH[data-state=active]{border-radius:var(--p-6);box-shadow:0 1px 2px 0 rgba(0,0,0,.05);color:var(--foreground)}.Tabs_variant-link__xOMDg>.Tabs_list__9Hs22 .Tabs_trigger__uzdqH{background-color:transparent!important;border:0!important;border-radius:0!important;box-shadow:0!important;font-size:16px;padding:12px 16px}.Tabs_variant-link__xOMDg>.Tabs_list__9Hs22 .Tabs_trigger__uzdqH[data-state=active]{box-shadow:inset 0 -3px 0 -1px var(--sb-cyan-400)!important}.Tabs_trigger__uzdqH svg{flex-shrink:0;pointer-events:none}.Tabs_trigger__uzdqH svg:not([class*=size-]){height:1rem;width:1rem}.dark .Tabs_trigger__uzdqH{color:var(--muted-foreground)}.dark .Tabs_trigger__uzdqH[data-state=active]{background-color:var(--input-30);border-color:var(--input);color:var(--foreground)}.Tabs_content__K27Vl{flex:1;outline:none}.Tabs_root__cB9Au.Tabs_variant-button__wtc8k.Tabs_sizeSm__gfpc6 .Tabs_list__9Hs22 .Tabs_trigger__uzdqH{font-size:var(--text-xs);padding:var(--p-1) var(--p-2)}.Tabs_root__cB9Au.Tabs_variant-button__wtc8k.Tabs_sizeSm__gfpc6 .Tabs_list__9Hs22 .Tabs_trigger__uzdqH[data-state=active]{border-radius:var(--p-4)}.Tabs_root__cB9Au.Tabs_variant-button__wtc8k.Tabs_sizeLg__CcRFZ .Tabs_list__9Hs22 .Tabs_trigger__uzdqH{font-size:var(--text-base);padding:var(--p-2) var(--p-4)}.Tabs_root__cB9Au.Tabs_variant-button__wtc8k.Tabs_sizeLg__CcRFZ .Tabs_list__9Hs22 .Tabs_trigger__uzdqH[data-state=active]{border-radius:var(--p-8)}.Tabs_root__cB9Au.Tabs_variant-link__xOMDg.Tabs_sizeSm__gfpc6>.Tabs_list__9Hs22{height:auto;min-height:36px}.Tabs_root__cB9Au.Tabs_variant-link__xOMDg.Tabs_sizeSm__gfpc6>.Tabs_list__9Hs22 .Tabs_trigger__uzdqH{font-size:14px;padding:8px 12px}.Tabs_root__cB9Au.Tabs_variant-link__xOMDg.Tabs_sizeLg__CcRFZ>.Tabs_list__9Hs22{height:auto;min-height:56px}.Tabs_root__cB9Au.Tabs_variant-link__xOMDg.Tabs_sizeLg__CcRFZ>.Tabs_list__9Hs22 .Tabs_trigger__uzdqH{font-size:18px;padding:16px 24px}";
|
|
4
|
+
var S = {"root":"Tabs_root__cB9Au","list":"Tabs_list__9Hs22","fullWidth":"Tabs_fullWidth__Lj2Dd","variant-link":"Tabs_variant-link__xOMDg","variant-button":"Tabs_variant-button__wtc8k","trigger":"Tabs_trigger__uzdqH","darker":"Tabs_darker__l-R0I","content":"Tabs_content__K27Vl","sizeSm":"Tabs_sizeSm__gfpc6","sizeLg":"Tabs_sizeLg__CcRFZ"};
|
|
5
5
|
styleInject(css_248z);
|
|
6
6
|
|
|
7
7
|
export { S as default };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { useIsMobile } from './useIsMobile.js';
|
package/dist/esm/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export { useIsMobile } from './hooks/useIsMobile.js';
|
|
1
2
|
export { ThemeProvider, useTheme } from './contexts/theme-context.js';
|
|
2
3
|
export { DEFAULT_THEME_ACTIVE_COLOR } from './docs/lib/theme.js';
|
|
3
4
|
export { SybilionAuthProvider, createSybilionApiFetch, getSybilionApiOriginFromSdk, sybilionApiFetch, useSybilionApiFetch, useSybilionAuth } from './sybilion-auth/SybilionAuthProvider.js';
|
|
@@ -3,7 +3,8 @@ export declare function PageContent({ className, children, variant, }: {
|
|
|
3
3
|
children: React.ReactNode;
|
|
4
4
|
variant?: 'default' | 'clean';
|
|
5
5
|
}): import("react/jsx-runtime").JSX.Element;
|
|
6
|
-
export declare function PageContentSection({ className, children, ...rest }: {
|
|
6
|
+
export declare function PageContentSection({ className, children, grow, ...rest }: {
|
|
7
7
|
className?: string;
|
|
8
8
|
children: React.ReactNode;
|
|
9
|
+
grow?: boolean;
|
|
9
10
|
} & Omit<React.ComponentProps<'div'>, 'className' | 'children'>): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,4 +1,11 @@
|
|
|
1
1
|
import type { ReactNode } from 'react';
|
|
2
|
+
export interface PageFooterLinkItem {
|
|
3
|
+
id: string;
|
|
4
|
+
label: ReactNode;
|
|
5
|
+
url: string;
|
|
6
|
+
/** For icon-only or non-text labels (screen readers). */
|
|
7
|
+
ariaLabel?: string;
|
|
8
|
+
}
|
|
2
9
|
export interface PageFooterProps {
|
|
3
10
|
logo?: ReactNode;
|
|
4
11
|
/** Rendered between logo block and copyright (e.g. debug UI from the app). */
|
|
@@ -12,5 +19,10 @@ export interface PageFooterProps {
|
|
|
12
19
|
websiteHref?: string;
|
|
13
20
|
mailHref?: string;
|
|
14
21
|
copyrightText?: string;
|
|
22
|
+
/**
|
|
23
|
+
* Footer links. When set (including `[]`), replaces default website + email icons.
|
|
24
|
+
* Omit to keep icon links from `websiteHref` / `mailHref`.
|
|
25
|
+
*/
|
|
26
|
+
links?: PageFooterLinkItem[];
|
|
15
27
|
}
|
|
16
|
-
export declare function PageFooter({ children, versionLink, versionLabel, homeTo, brandText, logo, websiteHref, mailHref, copyrightText, }: PageFooterProps): import("react/jsx-runtime").JSX.Element;
|
|
28
|
+
export declare function PageFooter({ children, versionLink, versionLabel, homeTo, brandText, logo, websiteHref, mailHref, copyrightText, links: linksProp, }: PageFooterProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -6,7 +6,7 @@ export { PageScroll } from './PageScroll/PageScroll';
|
|
|
6
6
|
export { PageXScroll } from './PageXScroll/PageXScroll';
|
|
7
7
|
export { Breadcrumbs } from './Breadcrumbs/Breadcrumbs';
|
|
8
8
|
export { PageFooter } from './PageFooter/PageFooter';
|
|
9
|
-
export type { PageFooterProps } from './PageFooter/PageFooter';
|
|
9
|
+
export type { PageFooterLinkItem, PageFooterProps, } from './PageFooter/PageFooter';
|
|
10
10
|
export { PageTabs } from './PageTabs/PageTabs';
|
|
11
11
|
export { PageColumns } from './PageColumns/PageColumns';
|
|
12
12
|
export { SectionHeader } from './SectionHeader';
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { TabsContentProps, TabsListProps, TabsProps, TabsTriggerProps } from './Tabs.types';
|
|
2
|
-
declare function Tabs({ className, variant, darker, ...props }: TabsProps & {
|
|
2
|
+
declare function Tabs({ className, variant, size, darker, ...props }: TabsProps & {
|
|
3
3
|
variant?: 'button' | 'link';
|
|
4
|
+
size?: 'sm' | 'md' | 'lg';
|
|
4
5
|
darker?: boolean;
|
|
5
6
|
}): import("react/jsx-runtime").JSX.Element;
|
|
6
7
|
declare function TabsList({ className, fullWidth, darker, ...props }: TabsListProps & {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default function PageFooterPage(): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default function PageTabsPage(): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { useIsMobile } from './useIsMobile';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sybilion/uilib",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.14",
|
|
4
4
|
"description": "Sybilion Design System — React UI components (Webpack + Stylus)",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public",
|
|
@@ -29,6 +29,11 @@
|
|
|
29
29
|
"import": "./src/index.ts",
|
|
30
30
|
"default": "./src/index.ts"
|
|
31
31
|
},
|
|
32
|
+
"./hooks": {
|
|
33
|
+
"types": "./dist/esm/types/src/hooks/index.d.ts",
|
|
34
|
+
"import": "./dist/esm/hooks/index.js",
|
|
35
|
+
"default": "./dist/esm/hooks/index.js"
|
|
36
|
+
},
|
|
32
37
|
"./src/*": "./src/*",
|
|
33
38
|
"./vite-standalone-dev": {
|
|
34
39
|
"types": "./dist/standalone/vite-sybilion-standalone-dev.d.ts",
|
|
@@ -21,13 +21,15 @@ export function PageContent({
|
|
|
21
21
|
export function PageContentSection({
|
|
22
22
|
className,
|
|
23
23
|
children,
|
|
24
|
+
grow = true,
|
|
24
25
|
...rest
|
|
25
26
|
}: {
|
|
26
27
|
className?: string;
|
|
27
28
|
children: React.ReactNode;
|
|
29
|
+
grow?: boolean;
|
|
28
30
|
} & Omit<React.ComponentProps<'div'>, 'className' | 'children'>) {
|
|
29
31
|
return (
|
|
30
|
-
<div className={cn(S.section, className)} {...rest}>
|
|
32
|
+
<div className={cn(S.section, className, grow && S.grow)} {...rest}>
|
|
31
33
|
{children}
|
|
32
34
|
</div>
|
|
33
35
|
);
|
|
@@ -15,14 +15,34 @@
|
|
|
15
15
|
&:last-child
|
|
16
16
|
min-height 55px
|
|
17
17
|
|
|
18
|
+
.meta
|
|
19
|
+
display flex
|
|
20
|
+
flex-wrap wrap
|
|
21
|
+
align-items center
|
|
22
|
+
gap var(--p-4)
|
|
23
|
+
|
|
18
24
|
.copyright
|
|
19
|
-
|
|
25
|
+
font-size 14px
|
|
26
|
+
|
|
27
|
+
.links
|
|
20
28
|
display flex
|
|
29
|
+
flex-wrap wrap
|
|
21
30
|
align-items center
|
|
22
31
|
gap var(--p-4)
|
|
32
|
+
|
|
33
|
+
.link
|
|
34
|
+
display inline-flex
|
|
35
|
+
align-items center
|
|
36
|
+
gap var(--p-2)
|
|
23
37
|
font-size 14px
|
|
38
|
+
color var(--foreground)
|
|
39
|
+
text-decoration none
|
|
40
|
+
|
|
41
|
+
&:hover
|
|
42
|
+
text-decoration underline
|
|
24
43
|
|
|
25
44
|
svg
|
|
45
|
+
flex-shrink 0
|
|
26
46
|
color var(--brand-color-400)
|
|
27
47
|
height 20px
|
|
28
48
|
width 20px
|
|
@@ -5,6 +5,14 @@ import { GlobeIcon, MailIcon } from 'lucide-react';
|
|
|
5
5
|
|
|
6
6
|
import S from './PageFooter.styl';
|
|
7
7
|
|
|
8
|
+
export interface PageFooterLinkItem {
|
|
9
|
+
id: string;
|
|
10
|
+
label: ReactNode;
|
|
11
|
+
url: string;
|
|
12
|
+
/** For icon-only or non-text labels (screen readers). */
|
|
13
|
+
ariaLabel?: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
8
16
|
export interface PageFooterProps {
|
|
9
17
|
logo?: ReactNode;
|
|
10
18
|
/** Rendered between logo block and copyright (e.g. debug UI from the app). */
|
|
@@ -18,6 +26,27 @@ export interface PageFooterProps {
|
|
|
18
26
|
websiteHref?: string;
|
|
19
27
|
mailHref?: string;
|
|
20
28
|
copyrightText?: string;
|
|
29
|
+
/**
|
|
30
|
+
* Footer links. When set (including `[]`), replaces default website + email icons.
|
|
31
|
+
* Omit to keep icon links from `websiteHref` / `mailHref`.
|
|
32
|
+
*/
|
|
33
|
+
links?: PageFooterLinkItem[];
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function PageFooterLinkEl({ item }: { item: PageFooterLinkItem }): ReactNode {
|
|
37
|
+
const { label, url, ariaLabel } = item;
|
|
38
|
+
const openInNewTab = /^https?:\/\//i.test(url);
|
|
39
|
+
|
|
40
|
+
return (
|
|
41
|
+
<a
|
|
42
|
+
href={url}
|
|
43
|
+
className={S.link}
|
|
44
|
+
{...(ariaLabel !== undefined ? { 'aria-label': ariaLabel } : {})}
|
|
45
|
+
{...(openInNewTab ? { target: '_blank', rel: 'noreferrer' } : {})}
|
|
46
|
+
>
|
|
47
|
+
{label}
|
|
48
|
+
</a>
|
|
49
|
+
);
|
|
21
50
|
}
|
|
22
51
|
|
|
23
52
|
export function PageFooter({
|
|
@@ -30,7 +59,26 @@ export function PageFooter({
|
|
|
30
59
|
websiteHref = 'https://sybilion.com',
|
|
31
60
|
mailHref = 'mailto:support@sybilion.com',
|
|
32
61
|
copyrightText = '© 2026 Sybilion. All rights reserved.',
|
|
62
|
+
links: linksProp,
|
|
33
63
|
}: PageFooterProps) {
|
|
64
|
+
const resolvedLinks: PageFooterLinkItem[] =
|
|
65
|
+
linksProp !== undefined
|
|
66
|
+
? linksProp
|
|
67
|
+
: [
|
|
68
|
+
{
|
|
69
|
+
id: 'website',
|
|
70
|
+
label: <GlobeIcon aria-hidden />,
|
|
71
|
+
url: websiteHref,
|
|
72
|
+
ariaLabel: 'Visit Sybilion website',
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
id: 'email',
|
|
76
|
+
label: <MailIcon aria-hidden />,
|
|
77
|
+
url: mailHref,
|
|
78
|
+
ariaLabel: 'Contact support via email',
|
|
79
|
+
},
|
|
80
|
+
];
|
|
81
|
+
|
|
34
82
|
return (
|
|
35
83
|
<footer className={S.root}>
|
|
36
84
|
<div className={S.line}>
|
|
@@ -48,19 +96,15 @@ export function PageFooter({
|
|
|
48
96
|
)}
|
|
49
97
|
</div>
|
|
50
98
|
{children}
|
|
51
|
-
<div className={S.
|
|
52
|
-
{copyrightText}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
</Link>
|
|
61
|
-
<a href={mailHref} aria-label="Contact support via email">
|
|
62
|
-
<MailIcon />
|
|
63
|
-
</a>
|
|
99
|
+
<div className={S.meta}>
|
|
100
|
+
<div className={S.copyright}>{copyrightText}</div>
|
|
101
|
+
{resolvedLinks.length > 0 && (
|
|
102
|
+
<nav className={S.links} aria-label="Footer links">
|
|
103
|
+
{resolvedLinks.map(item => (
|
|
104
|
+
<PageFooterLinkEl key={item.id} item={item} />
|
|
105
|
+
))}
|
|
106
|
+
</nav>
|
|
107
|
+
)}
|
|
64
108
|
</div>
|
|
65
109
|
</div>
|
|
66
110
|
</footer>
|
|
@@ -11,7 +11,10 @@ export { PageScroll } from './PageScroll/PageScroll';
|
|
|
11
11
|
export { PageXScroll } from './PageXScroll/PageXScroll';
|
|
12
12
|
export { Breadcrumbs } from './Breadcrumbs/Breadcrumbs';
|
|
13
13
|
export { PageFooter } from './PageFooter/PageFooter';
|
|
14
|
-
export type {
|
|
14
|
+
export type {
|
|
15
|
+
PageFooterLinkItem,
|
|
16
|
+
PageFooterProps,
|
|
17
|
+
} from './PageFooter/PageFooter';
|
|
15
18
|
export { PageTabs } from './PageTabs/PageTabs';
|
|
16
19
|
export { PageColumns } from './PageColumns/PageColumns';
|
|
17
20
|
export { SectionHeader } from './SectionHeader';
|
|
@@ -115,3 +115,41 @@
|
|
|
115
115
|
flex 1
|
|
116
116
|
outline none
|
|
117
117
|
|
|
118
|
+
// Sizes (md = default styles above)
|
|
119
|
+
.root
|
|
120
|
+
&.variant-button
|
|
121
|
+
&.sizeSm
|
|
122
|
+
.list .trigger
|
|
123
|
+
padding var(--p-1) var(--p-2)
|
|
124
|
+
font-size var(--text-xs)
|
|
125
|
+
|
|
126
|
+
&[data-state="active"]
|
|
127
|
+
border-radius var(--p-4)
|
|
128
|
+
|
|
129
|
+
&.sizeLg
|
|
130
|
+
.list .trigger
|
|
131
|
+
padding var(--p-2) var(--p-4)
|
|
132
|
+
font-size var(--text-base)
|
|
133
|
+
|
|
134
|
+
&[data-state="active"]
|
|
135
|
+
border-radius var(--p-8)
|
|
136
|
+
|
|
137
|
+
&.variant-link
|
|
138
|
+
&.sizeSm
|
|
139
|
+
> .list
|
|
140
|
+
height auto
|
|
141
|
+
min-height 36px
|
|
142
|
+
|
|
143
|
+
> .list .trigger
|
|
144
|
+
padding 8px 12px
|
|
145
|
+
font-size 14px
|
|
146
|
+
|
|
147
|
+
&.sizeLg
|
|
148
|
+
> .list
|
|
149
|
+
height auto
|
|
150
|
+
min-height 56px
|
|
151
|
+
|
|
152
|
+
> .list .trigger
|
|
153
|
+
padding 16px 24px
|
|
154
|
+
font-size 18px
|
|
155
|
+
|
|
@@ -13,15 +13,22 @@ import {
|
|
|
13
13
|
function Tabs({
|
|
14
14
|
className,
|
|
15
15
|
variant = 'button',
|
|
16
|
+
size = 'md',
|
|
16
17
|
darker = false,
|
|
17
18
|
...props
|
|
18
|
-
}: TabsProps & {
|
|
19
|
+
}: TabsProps & {
|
|
20
|
+
variant?: 'button' | 'link';
|
|
21
|
+
size?: 'sm' | 'md' | 'lg';
|
|
22
|
+
darker?: boolean;
|
|
23
|
+
}) {
|
|
19
24
|
return (
|
|
20
25
|
<TabsPrimitive.Root
|
|
21
26
|
data-slot="tabs"
|
|
22
27
|
className={cn(
|
|
23
28
|
S.root,
|
|
24
29
|
S[`variant-${variant}`],
|
|
30
|
+
size === 'sm' && S.sizeSm,
|
|
31
|
+
size === 'lg' && S.sizeLg,
|
|
25
32
|
darker && S.darker,
|
|
26
33
|
className,
|
|
27
34
|
)}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { useState } from 'react';
|
|
2
|
+
|
|
3
|
+
import { Label } from '#uilib/components/ui/Label';
|
|
4
|
+
import {
|
|
5
|
+
PageContent,
|
|
6
|
+
PageContentSection,
|
|
7
|
+
PageFooter,
|
|
8
|
+
} from '#uilib/components/ui/Page';
|
|
9
|
+
import type { PageFooterLinkItem } from '#uilib/components/ui/Page/PageFooter/PageFooter';
|
|
10
|
+
import { Switch } from '#uilib/components/ui/Switch';
|
|
11
|
+
import { GlobeIcon, Hash, MailIcon, MessageCircle } from 'lucide-react';
|
|
12
|
+
|
|
13
|
+
import { AppPageHeader } from '../components/AppPageHeader/AppPageHeader';
|
|
14
|
+
import { DocsHeaderActions } from '../docsHeaderActions';
|
|
15
|
+
import S from './PageFooterPage.styl';
|
|
16
|
+
|
|
17
|
+
const DEMO_LINKS: PageFooterLinkItem[] = [
|
|
18
|
+
{
|
|
19
|
+
id: 'site',
|
|
20
|
+
label: (
|
|
21
|
+
<>
|
|
22
|
+
<GlobeIcon aria-hidden />
|
|
23
|
+
Website
|
|
24
|
+
</>
|
|
25
|
+
),
|
|
26
|
+
url: 'https://sybilion.com',
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
id: 'email',
|
|
30
|
+
label: (
|
|
31
|
+
<>
|
|
32
|
+
<MailIcon aria-hidden />
|
|
33
|
+
Email
|
|
34
|
+
</>
|
|
35
|
+
),
|
|
36
|
+
url: 'mailto:support@sybilion.com',
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
id: 'discord',
|
|
40
|
+
label: (
|
|
41
|
+
<>
|
|
42
|
+
<MessageCircle aria-hidden />
|
|
43
|
+
Discord
|
|
44
|
+
</>
|
|
45
|
+
),
|
|
46
|
+
url: 'https://discord.com',
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
id: 'slack',
|
|
50
|
+
label: (
|
|
51
|
+
<>
|
|
52
|
+
<Hash aria-hidden />
|
|
53
|
+
Slack
|
|
54
|
+
</>
|
|
55
|
+
),
|
|
56
|
+
url: 'https://slack.com',
|
|
57
|
+
},
|
|
58
|
+
];
|
|
59
|
+
|
|
60
|
+
export default function PageFooterPage() {
|
|
61
|
+
const [isMobile, setIsMobile] = useState(false);
|
|
62
|
+
|
|
63
|
+
return (
|
|
64
|
+
<>
|
|
65
|
+
<AppPageHeader
|
|
66
|
+
breadcrumbs={[{ label: 'PageFooter' }]}
|
|
67
|
+
title="PageFooter"
|
|
68
|
+
subheader="Copyright + optional link row with gap and wrapping."
|
|
69
|
+
actions={<DocsHeaderActions />}
|
|
70
|
+
/>
|
|
71
|
+
<PageContent>
|
|
72
|
+
<PageContentSection title="With links prop">
|
|
73
|
+
<div
|
|
74
|
+
style={{
|
|
75
|
+
display: 'flex',
|
|
76
|
+
alignItems: 'center',
|
|
77
|
+
gap: 8,
|
|
78
|
+
marginTop: 'var(--p-3)',
|
|
79
|
+
}}
|
|
80
|
+
>
|
|
81
|
+
<Switch
|
|
82
|
+
id="page-footer-mobile-preview"
|
|
83
|
+
checked={isMobile}
|
|
84
|
+
onCheckedChange={setIsMobile}
|
|
85
|
+
/>
|
|
86
|
+
<Label htmlFor="page-footer-mobile-preview">Mobile</Label>
|
|
87
|
+
</div>
|
|
88
|
+
<div className={isMobile ? `${S.demo} ${S.isMobile}` : S.demo}>
|
|
89
|
+
<PageFooter
|
|
90
|
+
versionLink=""
|
|
91
|
+
versionLabel="0.0.0"
|
|
92
|
+
links={DEMO_LINKS}
|
|
93
|
+
/>
|
|
94
|
+
</div>
|
|
95
|
+
</PageContentSection>
|
|
96
|
+
</PageContent>
|
|
97
|
+
</>
|
|
98
|
+
);
|
|
99
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { PageContentSection, PageTabs } from '#uilib/components/ui/Page';
|
|
2
|
+
|
|
3
|
+
import { AppPageHeader } from '../components/AppPageHeader/AppPageHeader';
|
|
4
|
+
import { DocsHeaderActions } from '../docsHeaderActions';
|
|
5
|
+
|
|
6
|
+
const SCROLL_TEST_ITEMS = Array.from({ length: 10 }, (_, i) => {
|
|
7
|
+
const n = i + 1;
|
|
8
|
+
return {
|
|
9
|
+
value: `scroll-demo-${n}`,
|
|
10
|
+
label: `Tab ${n} — wider label`,
|
|
11
|
+
content: (
|
|
12
|
+
<p style={{ margin: 0, padding: '0 var(--page-x-padding)' }}>
|
|
13
|
+
Content for tab {n}. Narrow container forces horizontal scroll on tab
|
|
14
|
+
row.
|
|
15
|
+
</p>
|
|
16
|
+
),
|
|
17
|
+
};
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
export default function PageTabsPage() {
|
|
21
|
+
return (
|
|
22
|
+
<>
|
|
23
|
+
<AppPageHeader
|
|
24
|
+
breadcrumbs={[{ label: 'PageTabs' }]}
|
|
25
|
+
title="PageTabs"
|
|
26
|
+
subheader="Page-scoped tabs with horizontally scrollable tab strip."
|
|
27
|
+
actions={<DocsHeaderActions />}
|
|
28
|
+
/>
|
|
29
|
+
<PageContentSection
|
|
30
|
+
style={{ display: 'flex', flexDirection: 'column', gap: '1.5rem' }}
|
|
31
|
+
>
|
|
32
|
+
<section>
|
|
33
|
+
<h3 style={{ marginBottom: '0.75rem' }}>Scrollable row (10 tabs)</h3>
|
|
34
|
+
<p
|
|
35
|
+
style={{
|
|
36
|
+
marginBottom: '1rem',
|
|
37
|
+
color: 'var(--muted-foreground)',
|
|
38
|
+
}}
|
|
39
|
+
>
|
|
40
|
+
Container capped at <code>280px</code> so tab triggers overflow and
|
|
41
|
+
use <code>PageXScroll</code>.
|
|
42
|
+
</p>
|
|
43
|
+
<div
|
|
44
|
+
style={{
|
|
45
|
+
maxWidth: 500,
|
|
46
|
+
border: '2px dashed var(--border)',
|
|
47
|
+
borderRadius: 'var(--p-3)',
|
|
48
|
+
backgroundColor: 'var(--background)',
|
|
49
|
+
}}
|
|
50
|
+
>
|
|
51
|
+
<PageTabs
|
|
52
|
+
defaultValue={SCROLL_TEST_ITEMS[0].value}
|
|
53
|
+
items={SCROLL_TEST_ITEMS}
|
|
54
|
+
/>
|
|
55
|
+
</div>
|
|
56
|
+
</section>
|
|
57
|
+
</PageContentSection>
|
|
58
|
+
</>
|
|
59
|
+
);
|
|
60
|
+
}
|
|
@@ -9,24 +9,120 @@ import {
|
|
|
9
9
|
import { AppPageHeader } from '../components/AppPageHeader/AppPageHeader';
|
|
10
10
|
import { DocsHeaderActions } from '../docsHeaderActions';
|
|
11
11
|
|
|
12
|
+
const VARIANTS = ['button', 'link'] as const;
|
|
13
|
+
const SIZES = ['sm', 'md', 'lg'] as const;
|
|
14
|
+
|
|
15
|
+
function TabsDemoCell({
|
|
16
|
+
variant,
|
|
17
|
+
size,
|
|
18
|
+
}: {
|
|
19
|
+
variant: (typeof VARIANTS)[number];
|
|
20
|
+
size: (typeof SIZES)[number];
|
|
21
|
+
}) {
|
|
22
|
+
const id = `${variant}-${size}`;
|
|
23
|
+
return (
|
|
24
|
+
<Tabs
|
|
25
|
+
variant={variant}
|
|
26
|
+
size={size}
|
|
27
|
+
defaultValue={`${id}-a`}
|
|
28
|
+
style={{ maxWidth: 360 }}
|
|
29
|
+
>
|
|
30
|
+
<TabsList>
|
|
31
|
+
<TabsTrigger value={`${id}-a`}>Alpha</TabsTrigger>
|
|
32
|
+
<TabsTrigger value={`${id}-b`}>Beta</TabsTrigger>
|
|
33
|
+
</TabsList>
|
|
34
|
+
<TabsContent value={`${id}-a`}>
|
|
35
|
+
Panel A ({variant}, {size}).
|
|
36
|
+
</TabsContent>
|
|
37
|
+
<TabsContent value={`${id}-b`}>
|
|
38
|
+
Panel B ({variant}, {size}).
|
|
39
|
+
</TabsContent>
|
|
40
|
+
</Tabs>
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
|
|
12
44
|
export default function TabsPage() {
|
|
13
45
|
return (
|
|
14
46
|
<>
|
|
15
47
|
<AppPageHeader
|
|
16
48
|
breadcrumbs={[{ label: 'Tabs' }]}
|
|
17
49
|
title="Tabs"
|
|
18
|
-
subheader="
|
|
50
|
+
subheader="Variants, sizes, full-width list, darker surface."
|
|
19
51
|
actions={<DocsHeaderActions />}
|
|
20
52
|
/>
|
|
21
|
-
<PageContentSection
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
53
|
+
<PageContentSection
|
|
54
|
+
style={{ display: 'flex', flexDirection: 'column', gap: '2rem' }}
|
|
55
|
+
>
|
|
56
|
+
<section>
|
|
57
|
+
<h3 style={{ marginBottom: '1rem' }}>Variants × sizes</h3>
|
|
58
|
+
<div style={{ overflowX: 'auto' }}>
|
|
59
|
+
<table style={{ borderCollapse: 'collapse', width: '100%' }}>
|
|
60
|
+
<thead>
|
|
61
|
+
<tr>
|
|
62
|
+
<th style={{ textAlign: 'left', padding: '0.5rem' }} />
|
|
63
|
+
{SIZES.map(s => (
|
|
64
|
+
<th key={s} style={{ padding: '0.5rem' }}>
|
|
65
|
+
{s}
|
|
66
|
+
</th>
|
|
67
|
+
))}
|
|
68
|
+
</tr>
|
|
69
|
+
</thead>
|
|
70
|
+
<tbody>
|
|
71
|
+
{VARIANTS.map(v => (
|
|
72
|
+
<tr key={v}>
|
|
73
|
+
<td
|
|
74
|
+
style={{
|
|
75
|
+
padding: '0.5rem',
|
|
76
|
+
fontWeight: 600,
|
|
77
|
+
whiteSpace: 'nowrap',
|
|
78
|
+
verticalAlign: 'top',
|
|
79
|
+
}}
|
|
80
|
+
>
|
|
81
|
+
{v}
|
|
82
|
+
</td>
|
|
83
|
+
{SIZES.map(s => (
|
|
84
|
+
<td key={s} style={{ padding: '0.5rem' }}>
|
|
85
|
+
<TabsDemoCell variant={v} size={s} />
|
|
86
|
+
</td>
|
|
87
|
+
))}
|
|
88
|
+
</tr>
|
|
89
|
+
))}
|
|
90
|
+
</tbody>
|
|
91
|
+
</table>
|
|
92
|
+
</div>
|
|
93
|
+
</section>
|
|
94
|
+
|
|
95
|
+
<section>
|
|
96
|
+
<h3 style={{ marginBottom: '1rem' }}>Darker</h3>
|
|
97
|
+
<p
|
|
98
|
+
style={{
|
|
99
|
+
marginBottom: '0.75rem',
|
|
100
|
+
color: 'var(--muted-foreground)',
|
|
101
|
+
}}
|
|
102
|
+
>
|
|
103
|
+
Pass <code>darker</code> on root and/or list for muted segment
|
|
104
|
+
background on inactive triggers.
|
|
105
|
+
</p>
|
|
106
|
+
<div
|
|
107
|
+
style={{
|
|
108
|
+
display: 'flex',
|
|
109
|
+
gap: '1rem',
|
|
110
|
+
backgroundColor: 'var(--background)',
|
|
111
|
+
padding: '1rem',
|
|
112
|
+
borderRadius: 'var(--p-3)',
|
|
113
|
+
width: '200px',
|
|
114
|
+
}}
|
|
115
|
+
>
|
|
116
|
+
<Tabs defaultValue="dk-a" variant="button" darker>
|
|
117
|
+
<TabsList darker>
|
|
118
|
+
<TabsTrigger value="dk-a">One</TabsTrigger>
|
|
119
|
+
<TabsTrigger value="dk-b">Two</TabsTrigger>
|
|
120
|
+
</TabsList>
|
|
121
|
+
<TabsContent value="dk-a">Button tabs + darker.</TabsContent>
|
|
122
|
+
<TabsContent value="dk-b">Second tab.</TabsContent>
|
|
123
|
+
</Tabs>
|
|
124
|
+
</div>
|
|
125
|
+
</section>
|
|
30
126
|
</PageContentSection>
|
|
31
127
|
</>
|
|
32
128
|
);
|
package/src/docs/registry.ts
CHANGED
|
@@ -216,6 +216,18 @@ export const DOC_REGISTRY: DocEntry[] = [
|
|
|
216
216
|
section: 'Layout',
|
|
217
217
|
load: () => import('./pages/PagePage'),
|
|
218
218
|
},
|
|
219
|
+
{
|
|
220
|
+
slug: 'page-footer',
|
|
221
|
+
title: 'PageFooter',
|
|
222
|
+
section: 'Layout',
|
|
223
|
+
load: () => import('./pages/PageFooterPage'),
|
|
224
|
+
},
|
|
225
|
+
{
|
|
226
|
+
slug: 'page-tabs',
|
|
227
|
+
title: 'PageTabs',
|
|
228
|
+
section: 'Layout',
|
|
229
|
+
load: () => import('./pages/PageTabsPage'),
|
|
230
|
+
},
|
|
219
231
|
{
|
|
220
232
|
slug: 'standalone-app-layout',
|
|
221
233
|
title: 'Standalone app layout',
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { useIsMobile } from './useIsMobile';
|
package/src/index.ts
CHANGED