@sqrzro/admin 2.1.0-bz.17 → 2.1.0-bz.19
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/components/AppLayout/index.js +5 -5
- package/dist/components/AppNavigation/index.d.ts +2 -2
- package/dist/components/AppNavigation/index.js +4 -12
- package/dist/components/AppNavigationComponent/index.d.ts +12 -0
- package/dist/components/AppNavigationComponent/index.js +19 -0
- package/dist/components/Auth/index.d.ts +10 -5
- package/dist/components/Auth/index.js +1 -6
- package/dist/components/Badge/index.d.ts +1 -1
- package/dist/components/Badge/index.js +6 -6
- package/dist/components/FilterBar/index.d.ts +2 -1
- package/dist/components/FilterBar/index.js +16 -3
- package/dist/components/FilterBarClearButton/index.d.ts +6 -0
- package/dist/components/FilterBarClearButton/index.js +5 -0
- package/dist/components/FilterBarItem/index.d.ts +4 -2
- package/dist/components/FilterBarItem/index.js +2 -1
- package/dist/components/GridList/index.d.ts +1 -1
- package/dist/components/GridListItem/index.d.ts +1 -1
- package/dist/components/GridListItem/index.js +2 -2
- package/dist/components/InfoPanel/index.js +10 -14
- package/dist/components/List/index.d.ts +3 -20
- package/dist/components/List/index.js +8 -24
- package/dist/components/ListActions/index.d.ts +6 -3
- package/dist/components/ListActions/index.js +10 -3
- package/dist/components/ListClientComponent/index.d.ts +15 -0
- package/dist/components/ListClientComponent/index.js +14 -0
- package/dist/components/ListComponent/index.d.ts +14 -0
- package/dist/components/ListComponent/index.js +21 -0
- package/dist/components/ListItem/index.d.ts +14 -9
- package/dist/components/ListItem/index.js +16 -6
- package/dist/components/ListSkeleton/index.d.ts +5 -0
- package/dist/components/ListSkeleton/index.js +5 -0
- package/dist/components/MeActions/index.js +2 -2
- package/dist/components/MePanel/index.d.ts +2 -1
- package/dist/components/MePanel/index.js +3 -2
- package/dist/components/Menu/index.d.ts +8 -0
- package/dist/components/Menu/index.js +7 -0
- package/dist/components/MenuItem/index.d.ts +5 -0
- package/dist/components/MenuItem/index.js +20 -0
- package/dist/components/Page/index.d.ts +4 -2
- package/dist/components/Page/index.js +4 -5
- package/dist/components/Panel/index.d.ts +3 -1
- package/dist/components/Panel/index.js +3 -2
- package/dist/components/RootLayout/index.d.ts +2 -1
- package/dist/components/RootLayout/index.js +3 -9
- package/dist/components/SettingsForm/index.d.ts +1 -3
- package/dist/components/SettingsForm/index.js +5 -5
- package/dist/components/SettingsPage/index.d.ts +1 -1
- package/dist/components/SettingsPage/index.js +2 -2
- package/dist/components/TableClientComponent/index.js +0 -8
- package/dist/components/Tabs/index.d.ts +2 -6
- package/dist/components/Tabs/index.js +5 -8
- package/dist/components/TabsComponent/index.d.ts +8 -0
- package/dist/components/TabsComponent/index.js +9 -0
- package/dist/components/index.d.ts +5 -5
- package/dist/components/index.js +2 -2
- package/dist/hooks/useNavigation.d.ts +11 -0
- package/dist/hooks/useNavigation.js +27 -0
- package/dist/index.cjs +1266 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.js.map +1 -0
- package/dist/interfaces.d.ts +8 -2
- package/dist/services/ConfigService.d.ts +7 -1
- package/dist/services/ConfigService.js +1 -1
- package/dist/services/PermissionService.d.ts +3 -0
- package/dist/services/PermissionService.js +25 -0
- package/dist/services/SettingsService.d.ts +8 -0
- package/dist/services/{LayoutService.js → SettingsService.js} +2 -2
- package/dist/styles/config.js +57 -21
- package/dist/styles/tailwind.d.ts +1 -1
- package/dist/styles/tailwind.js +6 -2
- package/package.json +27 -16
- package/dist/components/Icon/index.d.ts +0 -8
- package/dist/components/Icon/index.js +0 -23
- package/dist/icons/ErrorIcon/index.d.ts +0 -3
- package/dist/icons/ErrorIcon/index.js +0 -5
- package/dist/icons/InfoIcon/index.d.ts +0 -3
- package/dist/icons/InfoIcon/index.js +0 -5
- package/dist/icons/SuccessIcon/index.d.ts +0 -3
- package/dist/icons/SuccessIcon/index.js +0 -5
- package/dist/icons/WarningIcon/index.d.ts +0 -3
- package/dist/icons/WarningIcon/index.js +0 -5
- package/dist/services/LayoutService.d.ts +0 -7
- /package/{postcss.js → postcss.cjs} +0 -0
- /package/{tailwind.js → tailwind.cjs} +0 -0
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
2
|
interface MePanelProps {
|
|
3
|
+
layout?: string;
|
|
3
4
|
user?: {
|
|
4
5
|
name: string;
|
|
5
6
|
} | null;
|
|
6
7
|
}
|
|
7
|
-
declare function MePanel({ user }: Readonly<MePanelProps>): React.ReactElement;
|
|
8
|
+
declare function MePanel({ layout, user }: Readonly<MePanelProps>): React.ReactElement;
|
|
8
9
|
export default MePanel;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { tw } from '@sqrzro/components';
|
|
2
3
|
import MeActions from '../MeActions';
|
|
3
|
-
function MePanel({ user }) {
|
|
4
|
-
return (_jsxs("div", { className:
|
|
4
|
+
function MePanel({ layout, user }) {
|
|
5
|
+
return (_jsxs("div", { className: tw('flex gap-3', layout === 'sidebar' ? 'w-full p-4' : 'ml-auto items-center'), children: [_jsxs("div", { className: tw('flex flex-col gap-0.5 text-white', layout === 'sidebar' ? '' : 'items-end'), children: [_jsx("strong", { children: user?.name }), _jsx(MeActions, {})] }), layout === 'sidebar' ? null : (_jsx("div", { className: "h-9 w-9 flex-none rounded-full border-4 border-slate-500" }))] }));
|
|
5
6
|
}
|
|
6
7
|
export default MePanel;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import type { ConfirmableAction, LinkableAction } from '@sqrzro/interfaces';
|
|
3
|
+
interface MenuProps {
|
|
4
|
+
actions: (ConfirmableAction & LinkableAction)[];
|
|
5
|
+
align: 'left' | 'right';
|
|
6
|
+
}
|
|
7
|
+
declare function Menu({ actions, align }: Readonly<MenuProps>): React.ReactElement;
|
|
8
|
+
export default Menu;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { InputPanel } from '@sqrzro/components';
|
|
3
|
+
import MenuItem from '../MenuItem';
|
|
4
|
+
function Menu({ actions, align }) {
|
|
5
|
+
return (_jsx(InputPanel, { align: align, children: _jsx("ul", { children: actions.map((item) => (_jsx("li", { children: _jsx(MenuItem, { ...item }) }, item.label))) }) }));
|
|
6
|
+
}
|
|
7
|
+
export default Menu;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import type { ConfirmableAction, LinkableAction } from '@sqrzro/interfaces';
|
|
3
|
+
type MenuItemProps = ConfirmableAction & LinkableAction;
|
|
4
|
+
declare function MenuItem({ href, isConfirmable, label, onClick, variant, }: Readonly<MenuItemProps>): React.ReactElement;
|
|
5
|
+
export default MenuItem;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { ConfirmableButton, Link, tw } from '@sqrzro/components';
|
|
3
|
+
const classMap = {
|
|
4
|
+
danger: 'text-red-700',
|
|
5
|
+
error: 'text-red-700',
|
|
6
|
+
info: 'text-sky-700',
|
|
7
|
+
warning: 'text-yellow-700',
|
|
8
|
+
success: 'text-green-700',
|
|
9
|
+
};
|
|
10
|
+
function MenuItem({ href, isConfirmable, label, onClick, variant, }) {
|
|
11
|
+
const classNames = tw('whitespace-nowrap p-2 px-3 text-sm text-slate-700', variant ? classMap[variant] : null);
|
|
12
|
+
if (!href) {
|
|
13
|
+
if (isConfirmable) {
|
|
14
|
+
return (_jsx(ConfirmableButton, { classNames: { root: { default: classNames } }, onClick: onClick, type: "button", children: label }));
|
|
15
|
+
}
|
|
16
|
+
return (_jsx("button", { className: classNames, onClick: onClick, type: "button", children: label }));
|
|
17
|
+
}
|
|
18
|
+
return (_jsx(Link, { className: classNames, href: href, onClick: onClick, children: label }));
|
|
19
|
+
}
|
|
20
|
+
export default MenuItem;
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
2
|
import type { LinkableAction } from '@sqrzro/interfaces';
|
|
3
|
+
import type { NavigationAction } from '../../interfaces';
|
|
3
4
|
export interface PageProps {
|
|
4
5
|
actions?: LinkableAction[];
|
|
5
6
|
basePath?: string;
|
|
6
7
|
children: React.ReactNode;
|
|
8
|
+
icon?: string;
|
|
7
9
|
isFullWidth?: boolean;
|
|
8
|
-
tabs?:
|
|
10
|
+
tabs?: (NavigationAction | null)[];
|
|
9
11
|
title: string;
|
|
10
12
|
}
|
|
11
|
-
declare function Page({ basePath, children, isFullWidth, tabs, title, }: Readonly<PageProps>): Promise<React.ReactElement>;
|
|
13
|
+
declare function Page({ basePath, children, icon, isFullWidth, tabs, title, }: Readonly<PageProps>): Promise<React.ReactElement>;
|
|
12
14
|
export default Page;
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { Fragment } from 'react';
|
|
3
3
|
import { Container, tw } from '@sqrzro/components';
|
|
4
|
-
import {
|
|
4
|
+
import { filterNull } from '@sqrzro/utility';
|
|
5
|
+
import { getLayout } from '../../services/SettingsService';
|
|
5
6
|
import Tabs from '../Tabs';
|
|
6
|
-
async function Page({ basePath, children, isFullWidth, tabs, title, }) {
|
|
7
|
+
async function Page({ basePath, children, icon, isFullWidth, tabs, title, }) {
|
|
7
8
|
const layout = await getLayout();
|
|
8
|
-
return (_jsxs(Fragment, { children: [_jsx("header", { className: tw('', layout === 'sidebar'
|
|
9
|
-
? 'border-b border-slate-200 bg-white'
|
|
10
|
-
: 'bg-slate-800 pb-16 text-white'), children: _jsxs(Container, { isFullWidth: layout === 'sidebar' || isFullWidth, children: [_jsxs("div", { className: "flex items-center justify-between py-10", children: [_jsx("h1", { className: "min-h-10 text-3xl font-semibold", children: title }), _jsx("div", { className: "flex gap-2", id: "page-actions" })] }), tabs ? (_jsx("div", { className: "-mt-4 mb-8", children: _jsx(Tabs, { basePath: basePath, data: tabs }) })) : null] }) }), _jsx(Container, { isFullWidth: layout === 'sidebar' || isFullWidth, children: _jsx("div", { className: tw('flex flex-col gap-8', layout === 'sidebar' ? 'mt-8' : '-mt-16'), children: children }) })] }));
|
|
9
|
+
return (_jsxs(Fragment, { children: [_jsx("header", { className: tw(layout === 'sidebar' ? 'bg-slate-200' : 'bg-slate-800 pb-16 text-white'), children: _jsxs(Container, { isFullWidth: layout === 'sidebar' || isFullWidth, children: [_jsxs("div", { className: tw('flex items-center justify-between', layout === 'sidebar' ? 'py-8' : 'py-10'), children: [_jsxs("h1", { className: "flex min-h-10 items-center text-3xl font-semibold", children: [icon ? (_jsx("i", { className: tw('mr-3 h-10 w-10 rounded-full border-4 border-blue-300/50 bg-blue-300 bg-clip-padding', icon) })) : null, title] }), _jsx("div", { className: "flex gap-2", id: "page-actions" })] }), tabs ? (_jsx("div", { className: tw('', layout === 'sidebar' ? '' : '-mt-4 mb-8 border-b border-slate-700'), children: _jsx(Tabs, { basePath: basePath, data: filterNull(tabs) }) })) : null] }) }), _jsx(Container, { isFullWidth: layout === 'sidebar' || isFullWidth, children: _jsx("div", { className: tw('@container flex flex-col gap-8', layout === 'sidebar' ? 'mt-8' : '-mt-16'), children: children }) })] }));
|
|
11
10
|
}
|
|
12
11
|
export default Page;
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
|
+
import type { LinkableAction } from '@sqrzro/interfaces';
|
|
2
3
|
export interface PanelProps {
|
|
4
|
+
action?: LinkableAction;
|
|
3
5
|
children: React.ReactNode;
|
|
4
6
|
title?: string;
|
|
5
7
|
}
|
|
6
|
-
declare function Panel({ children, title }: Readonly<PanelProps>): React.ReactElement;
|
|
8
|
+
declare function Panel({ action, children, title }: Readonly<PanelProps>): React.ReactElement;
|
|
7
9
|
export default Panel;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
import { Button } from '@sqrzro/components';
|
|
3
|
+
function Panel({ action, children, title }) {
|
|
4
|
+
return (_jsxs("article", { className: "@container bg-panel relative rounded p-6 shadow-[0px_0px_0px_1px_rgba(9,9,11,0.07),0px_2px_2px_0px_rgba(9,9,11,0.05)]", children: [title ? (_jsxs("header", { className: "mb-4 flex justify-between border-b border-slate-200", children: [_jsx("h3", { className: "pb-3 text-lg font-semibold leading-none", children: title }), action ? _jsx(Button, { href: action.href, children: action.label }) : null] })) : null, children] }));
|
|
4
5
|
}
|
|
5
6
|
export default Panel;
|
|
@@ -3,7 +3,8 @@ import type { Config as ConfigObject } from '../../services/ConfigService';
|
|
|
3
3
|
export interface RootLayoutProps {
|
|
4
4
|
children: React.ReactNode;
|
|
5
5
|
config?: ConfigObject;
|
|
6
|
+
font?: string;
|
|
6
7
|
logo?: () => React.ReactElement;
|
|
7
8
|
}
|
|
8
|
-
declare function RootLayout({ children, config, logo }: Readonly<RootLayoutProps>): React.ReactElement;
|
|
9
|
+
declare function RootLayout({ children, config, font, logo, }: Readonly<RootLayoutProps>): React.ReactElement;
|
|
9
10
|
export default RootLayout;
|
|
@@ -1,21 +1,15 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
/* eslint-disable react/no-danger */
|
|
3
|
-
import { Suspense } from 'react';
|
|
4
|
-
import { Inter as getInter } from 'next/font/google';
|
|
5
3
|
import { ClassNames, Toaster, tw } from '@sqrzro/components';
|
|
6
4
|
import { setConfig } from '../../services/ConfigService';
|
|
7
5
|
import classNames from '../../styles/config';
|
|
8
6
|
import Config from '../Config';
|
|
9
|
-
|
|
10
|
-
subsets: ['latin'],
|
|
11
|
-
variable: '--font-inter',
|
|
12
|
-
});
|
|
13
|
-
function RootLayout({ children, config, logo }) {
|
|
7
|
+
function RootLayout({ children, config, font, logo, }) {
|
|
14
8
|
if (config) {
|
|
15
9
|
setConfig(config, logo);
|
|
16
10
|
}
|
|
17
|
-
return (_jsxs("html", { lang: "en", children: [_jsx("head", {}), _jsxs("body", { className: tw(
|
|
11
|
+
return (_jsxs("html", { lang: "en", children: [_jsx("head", {}), _jsxs("body", { className: tw(font, 'overflow-x-hidden overflow-y-scroll bg-slate-50 font-sans text-sm text-slate-800 has-[[data-modal][open]]:overflow-hidden'), children: [_jsx("script", { dangerouslySetInnerHTML: {
|
|
18
12
|
__html: "(function(d){var v=d.createElement('div'),t=d.createElement('style'),s=v.style;s.overflowY='scroll';s.width='50';s.height='50';d.body.append(v);t.innerHTML='body:has([data-modal][open]){padding-right:'+(v.offsetWidth-v.clientWidth)+'px}';d.body.append(t);v.remove()}(document))",
|
|
19
|
-
} }), _jsx(Config, { data: config }), _jsx(ClassNames, { data: classNames }), children, _jsx(
|
|
13
|
+
} }), _jsx(Config, { data: config }), _jsx(ClassNames, { data: classNames }), children, _jsx(Toaster, {})] })] }));
|
|
20
14
|
}
|
|
21
15
|
export default RootLayout;
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
-
import { EditableForm, EditableRadioFormField } from '@sqrzro/components';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { EditableForm, EditableRadioFormField, EditableSwitchFormField } from '@sqrzro/components';
|
|
4
4
|
import { useEditableForm } from '@sqrzro/hooks';
|
|
5
|
-
import {
|
|
5
|
+
import { submitSettingsForm } from '../../services/SettingsService';
|
|
6
6
|
const options = { sidebar: 'Side bar', topbar: 'Top bar' };
|
|
7
7
|
function SettingsForm({ defaults }) {
|
|
8
8
|
const { fieldProps, formProps } = useEditableForm({
|
|
9
9
|
defaults,
|
|
10
|
-
onSubmit:
|
|
10
|
+
onSubmit: submitSettingsForm,
|
|
11
11
|
});
|
|
12
|
-
return (
|
|
12
|
+
return (_jsxs(EditableForm, { title: "Appearance", ...formProps, children: [_jsx(EditableRadioFormField, { ...fieldProps('layout'), options: options, renderValue: (value) => (value ? options[value] || '-' : '-') }), _jsx(EditableSwitchFormField, { ...fieldProps('isDark'), label: "Dark mode" })] }));
|
|
13
13
|
}
|
|
14
14
|
export default SettingsForm;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { getLayout } from '../../services/
|
|
2
|
+
import { getLayout } from '../../services/SettingsService';
|
|
3
3
|
import Page from '../Page';
|
|
4
4
|
import SettingsForm from '../SettingsForm';
|
|
5
5
|
async function SettingsPage() {
|
|
6
6
|
const layout = await getLayout();
|
|
7
|
-
return (_jsx(Page, { title: "Settings", children: _jsx(SettingsForm, { defaults: { layout } }) }));
|
|
7
|
+
return (_jsx(Page, { title: "Settings", children: _jsx("div", { className: "flex flex-col gap-6", children: _jsx(SettingsForm, { defaults: { layout } }) }) }));
|
|
8
8
|
}
|
|
9
9
|
export default SettingsPage;
|
|
@@ -1,14 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
-
import { useState } from 'react';
|
|
4
3
|
import { Link, tw } from '@sqrzro/components';
|
|
5
4
|
import { usePathname, useSearchParams } from 'next/navigation';
|
|
6
|
-
function toggleArrayItem(array, item) {
|
|
7
|
-
if (array.includes(item)) {
|
|
8
|
-
return array.filter((itm) => itm !== item);
|
|
9
|
-
}
|
|
10
|
-
return [...array, item];
|
|
11
|
-
}
|
|
12
5
|
function createFilterLink(pathname, searchParams, filters) {
|
|
13
6
|
const updatedSearchParams = new URLSearchParams({
|
|
14
7
|
...Object.fromEntries(searchParams),
|
|
@@ -47,7 +40,6 @@ function parseColumns(columns) {
|
|
|
47
40
|
function TableClientComponent({ columns, data, }) {
|
|
48
41
|
const pathname = usePathname();
|
|
49
42
|
const searchParams = useSearchParams();
|
|
50
|
-
const [selected, setSelected] = useState([]);
|
|
51
43
|
const parsedColumns = parseColumns(columns);
|
|
52
44
|
const hasTitles = parsedColumns.some((column) => column.title);
|
|
53
45
|
return (_jsx("div", { className: "bg-white shadow-sm", children: _jsxs("table", { className: "w-full", children: [hasTitles ? (_jsx("thead", { children: _jsx("tr", { children: parsedColumns.map((column) => (_jsx("th", { className: tw('p-4', column.type === 'number' ? 'text-right' : 'text-left'), children: column.title ? (_jsxs(Link, { href: createSortLink(pathname, searchParams, column.key), children: [column.title, ' '] })) : null }, column.key))) }) })) : null, _jsx("tbody", { children: data.map((item) => (_jsx("tr", { className: "odd:bg-slate-100", children: parsedColumns.map((column) => (_jsx("td", { className: tw('border-x border-transparent p-4', getSortIconProps(searchParams, column.key).dir
|
|
@@ -1,8 +1,4 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
|
-
import type {
|
|
3
|
-
|
|
4
|
-
basePath?: string;
|
|
5
|
-
data: LinkableAction[];
|
|
6
|
-
}
|
|
7
|
-
declare function Tabs({ basePath, data }: Readonly<TabBarProps>): React.ReactElement;
|
|
2
|
+
import type { TabsComponentProps } from '../TabsComponent';
|
|
3
|
+
declare function Tabs({ basePath, data }: Readonly<TabsComponentProps>): Promise<React.ReactElement>;
|
|
8
4
|
export default Tabs;
|
|
@@ -1,11 +1,8 @@
|
|
|
1
|
-
'use client';
|
|
2
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
return
|
|
8
|
-
? 'border-primary border-b-4 text-white'
|
|
9
|
-
: 'text-white/80 hover:text-white'), href: href, children: label }) }, href))) }) }));
|
|
2
|
+
import { filterNull } from '@sqrzro/utility';
|
|
3
|
+
import { filterList } from '../../services/PermissionService';
|
|
4
|
+
import TabsComponent from '../TabsComponent';
|
|
5
|
+
async function Tabs({ basePath, data }) {
|
|
6
|
+
return _jsx(TabsComponent, { basePath: basePath, data: await filterList(filterNull(data)) });
|
|
10
7
|
}
|
|
11
8
|
export default Tabs;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import type { NavigationAction } from '../../interfaces';
|
|
3
|
+
export interface TabsComponentProps {
|
|
4
|
+
basePath?: string;
|
|
5
|
+
data: NavigationAction[];
|
|
6
|
+
}
|
|
7
|
+
declare function TabsComponent({ basePath, data }: Readonly<TabsComponentProps>): React.ReactElement;
|
|
8
|
+
export default TabsComponent;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import { Link, tw } from '@sqrzro/components';
|
|
4
|
+
import useNavigation from '../../hooks/useNavigation';
|
|
5
|
+
function TabsComponent({ basePath = '', data }) {
|
|
6
|
+
const navigation = useNavigation(data, { basePath });
|
|
7
|
+
return (_jsx("nav", { children: _jsx("ul", { className: "flex gap-4", children: navigation.map(({ href, isActive, label }) => (_jsx("li", { children: _jsx(Link, { className: tw('block border-b-4 border-transparent px-1 pb-2 font-semibold', isActive ? 'border-primary' : 'opacity-80 hover:opacity-100'), href: href, children: label }) }, href))) }) }));
|
|
8
|
+
}
|
|
9
|
+
export default TabsComponent;
|
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
export { Autocomplete, AutocompleteFormField, Button, CalendarInput,
|
|
2
|
-
export type { DropdownItem } from '@sqrzro/components';
|
|
1
|
+
export { Autocomplete, AutocompleteFormField, Button, CalendarInput, CheckboxInput, ConfirmableButton, ConfirmableForm, ContentFormField, DateFormField, DateInput, DefinitionList, Dropdown, DropdownFormField, EditableAutocompleteFormField, EditableDateFormField, EditableDropdownFormField, EditableForm, EditableFormField, EditableMultiFormField, EditableNumberFormField, EditableSwitchFormField, EditableTextAreaFormField, EditableTextFormField, EmptyMessage, Fieldset, Form, FormField, FormSubmit, ImageInput, ImageFormField, Link, LoadingModal, Modal, ModalActions, ModalForm, MoneyFormField, MoneyInput, MultiFormField, NumberFormField, NumberInput, ObjectFormField, RadioInput, Switch, SwitchFormField, TextArea, TextAreaFormField, TextFormField, TextInput, Toaster, } from '@sqrzro/components';
|
|
2
|
+
export type { DropdownItem, EditableFormFieldProps, FormFieldProps, LinkProps, NumberInputProps, } from '@sqrzro/components';
|
|
3
3
|
export type { AppLayoutProps } from './AppLayout';
|
|
4
4
|
export { default as AppLayout } from './AppLayout';
|
|
5
|
-
export type { AuthProps } from './Auth';
|
|
6
|
-
export { default as Auth } from './Auth';
|
|
7
5
|
export type { BadgeProps } from './Badge';
|
|
8
6
|
export { default as Badge } from './Badge';
|
|
9
7
|
export type { DashboardProps } from './Dashboard';
|
|
@@ -14,8 +12,10 @@ export type { GridListProps } from './GridList';
|
|
|
14
12
|
export { default as GridList } from './GridList';
|
|
15
13
|
export type { InfoPanelProps } from './InfoPanel';
|
|
16
14
|
export { default as InfoPanel } from './InfoPanel';
|
|
17
|
-
export type {
|
|
15
|
+
export type { ListProps } from './List';
|
|
18
16
|
export { default as List } from './List';
|
|
17
|
+
export type { ListClientComponentProps } from './ListClientComponent';
|
|
18
|
+
export { default as ListClientComponent } from './ListClientComponent';
|
|
19
19
|
export type { ListObject } from './ListItem';
|
|
20
20
|
export type { ListActionsProps } from './ListActions';
|
|
21
21
|
export { default as ListActions } from './ListActions';
|
package/dist/components/index.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
// Exported from @sqrzro/components
|
|
2
|
-
export { Autocomplete, AutocompleteFormField, Button, CalendarInput,
|
|
2
|
+
export { Autocomplete, AutocompleteFormField, Button, CalendarInput, CheckboxInput, ConfirmableButton, ConfirmableForm, ContentFormField, DateFormField, DateInput, DefinitionList, Dropdown, DropdownFormField, EditableAutocompleteFormField, EditableDateFormField, EditableDropdownFormField, EditableForm, EditableFormField, EditableMultiFormField, EditableNumberFormField, EditableSwitchFormField, EditableTextAreaFormField, EditableTextFormField, EmptyMessage, Fieldset, Form, FormField, FormSubmit, ImageInput, ImageFormField, Link, LoadingModal, Modal, ModalActions, ModalForm, MoneyFormField, MoneyInput, MultiFormField, NumberFormField, NumberInput, ObjectFormField, RadioInput, Switch, SwitchFormField, TextArea, TextAreaFormField, TextFormField, TextInput, Toaster, } from '@sqrzro/components';
|
|
3
3
|
export { default as AppLayout } from './AppLayout';
|
|
4
|
-
export { default as Auth } from './Auth';
|
|
5
4
|
export { default as Badge } from './Badge';
|
|
6
5
|
export { default as Dashboard } from './Dashboard';
|
|
7
6
|
export { default as FilterBar } from './FilterBar';
|
|
8
7
|
export { default as GridList } from './GridList';
|
|
9
8
|
export { default as InfoPanel } from './InfoPanel';
|
|
10
9
|
export { default as List } from './List';
|
|
10
|
+
export { default as ListClientComponent } from './ListClientComponent';
|
|
11
11
|
export { default as ListActions } from './ListActions';
|
|
12
12
|
export { default as Page } from './Page';
|
|
13
13
|
export { default as Panel } from './Panel';
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { NavigationAction } from '../interfaces';
|
|
2
|
+
interface NavigationObject {
|
|
3
|
+
href: string;
|
|
4
|
+
isActive: boolean;
|
|
5
|
+
label: string;
|
|
6
|
+
}
|
|
7
|
+
interface UseNavigationOptions {
|
|
8
|
+
basePath?: string;
|
|
9
|
+
}
|
|
10
|
+
declare function useNavigation(data: NavigationAction[], options?: UseNavigationOptions): NavigationObject[];
|
|
11
|
+
export default useNavigation;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { useEffect, useState } from 'react';
|
|
2
|
+
import { joinUrl } from '@sqrzro/utility';
|
|
3
|
+
import { usePathname } from 'next/navigation';
|
|
4
|
+
function getActiveHref(pathname, hrefs) {
|
|
5
|
+
return (hrefs
|
|
6
|
+
.filter((href) => href && pathname.startsWith(`/${href.replace(/^\//u, '')}`))
|
|
7
|
+
.sort((first, second) => {
|
|
8
|
+
if (!first || !second) {
|
|
9
|
+
return 0;
|
|
10
|
+
}
|
|
11
|
+
return second.length - first.length;
|
|
12
|
+
})[0] || '');
|
|
13
|
+
}
|
|
14
|
+
function useNavigation(data, options) {
|
|
15
|
+
const [activeHref, setActiveHref] = useState('');
|
|
16
|
+
const pathname = usePathname();
|
|
17
|
+
const hrefs = data.map(({ href }) => joinUrl(options?.basePath, href));
|
|
18
|
+
useEffect(() => {
|
|
19
|
+
setActiveHref(getActiveHref(pathname, hrefs));
|
|
20
|
+
}, [pathname]);
|
|
21
|
+
return data.map(({ href, label }) => ({
|
|
22
|
+
href: joinUrl(options?.basePath, href),
|
|
23
|
+
isActive: joinUrl(options?.basePath, href) === activeHref,
|
|
24
|
+
label,
|
|
25
|
+
}));
|
|
26
|
+
}
|
|
27
|
+
export default useNavigation;
|