@pallasoft/ps-core-components 2.36.0 → 2.38.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/ps-action-tile-content.d.ts +8 -0
- package/dist/components/ps-action-tile-content.js +7 -0
- package/dist/components/ps-action-tile-link.d.ts +10 -0
- package/dist/components/ps-action-tile-link.js +16 -0
- package/dist/components/ps-action-tile.js +2 -1
- package/dist/components/ps-capped-list.js +2 -2
- package/dist/components/ps-detail-pane.d.ts +11 -0
- package/dist/components/ps-detail-pane.js +7 -0
- package/dist/components/ps-document-row.d.ts +2 -1
- package/dist/components/ps-document-row.js +11 -6
- package/dist/components/ps-form-footer.d.ts +5 -2
- package/dist/components/ps-form-footer.js +2 -1
- package/dist/components/ps-split-view.d.ts +6 -0
- package/dist/components/ps-split-view.js +13 -0
- package/dist/components/ps-text-link.d.ts +12 -0
- package/dist/components/ps-text-link.js +13 -0
- package/dist/constants/ps-button-classes.js +2 -2
- package/dist/constants/ps-split-view-config.d.ts +4 -0
- package/dist/constants/ps-split-view-config.js +7 -0
- package/dist/constants/ps-text-link-classes.d.ts +5 -0
- package/dist/constants/ps-text-link-classes.js +8 -0
- package/dist/esm/components/ps-action-tile-content.js +3 -0
- package/dist/esm/components/ps-action-tile-link.js +12 -0
- package/dist/esm/components/ps-action-tile.js +3 -2
- package/dist/esm/components/ps-capped-list.js +2 -2
- package/dist/esm/components/ps-detail-pane.js +3 -0
- package/dist/esm/components/ps-document-row.js +11 -6
- package/dist/esm/components/ps-form-footer.js +2 -1
- package/dist/esm/components/ps-split-view.js +9 -0
- package/dist/esm/components/ps-text-link.js +9 -0
- package/dist/esm/constants/ps-button-classes.js +2 -2
- package/dist/esm/constants/ps-split-view-config.js +4 -0
- package/dist/esm/constants/ps-text-link-classes.js +5 -0
- package/dist/esm/hooks/use-ps-fill-height.js +20 -0
- package/dist/esm/index.js +5 -0
- package/dist/esm/services/ps-fill-height-service.js +33 -0
- package/dist/hooks/use-ps-fill-height.d.ts +4 -0
- package/dist/hooks/use-ps-fill-height.js +24 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +5 -0
- package/dist/services/ps-fill-height-service.d.ts +5 -0
- package/dist/services/ps-fill-height-service.js +37 -0
- package/package.json +1 -1
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
export interface PsActionTileContentProps {
|
|
3
|
+
description?: string;
|
|
4
|
+
icon?: ReactNode;
|
|
5
|
+
label: string;
|
|
6
|
+
variant: 'default' | 'primary';
|
|
7
|
+
}
|
|
8
|
+
export declare const PsActionTileContent: ({ description, icon, label, variant, }: PsActionTileContentProps) => import("react").JSX.Element;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PsActionTileContent = void 0;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const ps_design_system_1 = require("@pallasoft/ps-design-system");
|
|
6
|
+
const PsActionTileContent = ({ description, icon, label, variant, }) => ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)("span", { className: 'min-w-0', children: [(0, jsx_runtime_1.jsx)("span", { className: 'block break-words', children: label }), description ? ((0, jsx_runtime_1.jsx)("span", { className: ps_design_system_1.PallasoftClassNameService.merge('mt-0.5 block text-xs font-medium leading-5', variant === 'primary' ? 'text-white/75' : 'text-ink/50'), children: description })) : null] }), icon ? ((0, jsx_runtime_1.jsx)("span", { className: ps_design_system_1.PallasoftClassNameService.merge('flex h-9 w-9 shrink-0 items-center justify-center rounded-lg', variant === 'primary' ? 'bg-white/15 text-white' : 'ps-icon-surface'), children: icon })) : null] }));
|
|
7
|
+
exports.PsActionTileContent = PsActionTileContent;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { AnchorHTMLAttributes, ElementType, ReactNode } from 'react';
|
|
2
|
+
export interface PsActionTileLinkProps extends AnchorHTMLAttributes<HTMLAnchorElement> {
|
|
3
|
+
description?: string;
|
|
4
|
+
href: string;
|
|
5
|
+
icon?: ReactNode;
|
|
6
|
+
label: string;
|
|
7
|
+
LinkComponent?: ElementType;
|
|
8
|
+
variant?: 'default' | 'primary';
|
|
9
|
+
}
|
|
10
|
+
export declare const PsActionTileLink: ({ className, description, href, icon, label, LinkComponent, variant, ...props }: PsActionTileLinkProps) => import("react").JSX.Element;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PsActionTileLink = void 0;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const ps_design_system_1 = require("@pallasoft/ps-design-system");
|
|
6
|
+
const ps_action_tile_content_1 = require("./ps-action-tile-content");
|
|
7
|
+
const variantClassNames = {
|
|
8
|
+
default: 'ps-action-tile',
|
|
9
|
+
primary: 'ps-action-tile ps-action-tile-primary',
|
|
10
|
+
};
|
|
11
|
+
const PsActionTileLink = ({ className, description, href, icon, label, LinkComponent, variant = 'default', ...props }) => {
|
|
12
|
+
const linkClassName = ps_design_system_1.PallasoftClassNameService.merge('ps-focus-ring w-full', variantClassNames[variant], className);
|
|
13
|
+
const content = ((0, jsx_runtime_1.jsx)(ps_action_tile_content_1.PsActionTileContent, { description: description, icon: icon, label: label, variant: variant }));
|
|
14
|
+
return LinkComponent ? ((0, jsx_runtime_1.jsx)(LinkComponent, { className: linkClassName, prefetch: 'intent', to: href, ...props, children: content })) : ((0, jsx_runtime_1.jsx)("a", { className: linkClassName, href: href, ...props, children: content }));
|
|
15
|
+
};
|
|
16
|
+
exports.PsActionTileLink = PsActionTileLink;
|
|
@@ -4,10 +4,11 @@ exports.PsActionTile = void 0;
|
|
|
4
4
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
5
|
const ps_design_system_1 = require("@pallasoft/ps-design-system");
|
|
6
6
|
const ps_skeleton_shape_1 = require("../constants/ps-skeleton-shape");
|
|
7
|
+
const ps_action_tile_content_1 = require("./ps-action-tile-content");
|
|
7
8
|
const ps_skeleton_1 = require("./ps-skeleton");
|
|
8
9
|
const variantClassNames = {
|
|
9
10
|
default: 'ps-action-tile',
|
|
10
11
|
primary: 'ps-action-tile ps-action-tile-primary',
|
|
11
12
|
};
|
|
12
|
-
const PsActionTile = ({ className, description, icon, isLoading = false, label, type = 'button', variant = 'default', ...props }) => isLoading ? ((0, jsx_runtime_1.jsx)(ps_skeleton_1.PsSkeleton, { className: ps_design_system_1.PallasoftClassNameService.merge('h-16', className), shape: ps_skeleton_shape_1.PsSkeletonShape.Card })) : ((0, jsx_runtime_1.
|
|
13
|
+
const PsActionTile = ({ className, description, icon, isLoading = false, label, type = 'button', variant = 'default', ...props }) => isLoading ? ((0, jsx_runtime_1.jsx)(ps_skeleton_1.PsSkeleton, { className: ps_design_system_1.PallasoftClassNameService.merge('h-16', className), shape: ps_skeleton_shape_1.PsSkeletonShape.Card })) : ((0, jsx_runtime_1.jsx)("button", { className: ps_design_system_1.PallasoftClassNameService.merge('ps-focus-ring w-full', variantClassNames[variant], className), type: type, ...props, children: (0, jsx_runtime_1.jsx)(ps_action_tile_content_1.PsActionTileContent, { description: description, icon: icon, label: label, variant: variant }) }));
|
|
13
14
|
exports.PsActionTile = PsActionTile;
|
|
@@ -4,11 +4,11 @@ exports.PsCappedList = void 0;
|
|
|
4
4
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
5
|
const react_1 = require("react");
|
|
6
6
|
const ps_capped_list_config_1 = require("../constants/ps-capped-list-config");
|
|
7
|
-
const
|
|
7
|
+
const ps_text_link_1 = require("./ps-text-link");
|
|
8
8
|
const PsCappedList = ({ getKey, items, renderItem, showAllLabel, visibleRows = ps_capped_list_config_1.PsCappedListConfig.defaultVisibleRows, }) => {
|
|
9
9
|
const [isExpanded, setIsExpanded] = (0, react_1.useState)(false);
|
|
10
10
|
const isCapped = !isExpanded && items.length > visibleRows;
|
|
11
11
|
const shown = isCapped ? items.slice(0, visibleRows) : items;
|
|
12
|
-
return ((0, jsx_runtime_1.jsxs)("div", { className: 'flex flex-col gap-2', children: [(0, jsx_runtime_1.jsx)("ul", { className: '-my-2 flex flex-col divide-y divide-line', children: shown.map((item) => ((0, jsx_runtime_1.jsx)("li", { children: renderItem(item) }, getKey(item)))) }), isCapped ? ((0, jsx_runtime_1.jsx)(
|
|
12
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: 'flex flex-col gap-2', children: [(0, jsx_runtime_1.jsx)("ul", { className: '-my-2 flex flex-col divide-y divide-line', children: shown.map((item) => ((0, jsx_runtime_1.jsx)("li", { children: renderItem(item) }, getKey(item)))) }), isCapped ? ((0, jsx_runtime_1.jsx)(ps_text_link_1.PsTextLink, { className: 'self-start', onClick: () => setIsExpanded(true), size: 'compact', children: showAllLabel })) : null] }));
|
|
13
13
|
};
|
|
14
14
|
exports.PsCappedList = PsCappedList;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
export interface PsDetailPaneProps {
|
|
3
|
+
children: ReactNode;
|
|
4
|
+
className?: string;
|
|
5
|
+
footer?: ReactNode;
|
|
6
|
+
footerStart?: ReactNode;
|
|
7
|
+
headerActions?: ReactNode;
|
|
8
|
+
subtitle?: ReactNode;
|
|
9
|
+
title: string;
|
|
10
|
+
}
|
|
11
|
+
export declare const PsDetailPane: ({ children, className, footer, footerStart, headerActions, subtitle, title, }: PsDetailPaneProps) => import("react").JSX.Element;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PsDetailPane = void 0;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const ps_design_system_1 = require("@pallasoft/ps-design-system");
|
|
6
|
+
const PsDetailPane = ({ children, className, footer, footerStart, headerActions, subtitle, title, }) => ((0, jsx_runtime_1.jsxs)("section", { "aria-label": title, className: ps_design_system_1.PallasoftClassNameService.merge('ps-card flex h-full min-h-0 min-w-0 flex-col overflow-hidden rounded-ps-card', className), children: [(0, jsx_runtime_1.jsxs)("header", { className: 'flex shrink-0 items-start justify-between gap-3 border-b border-line/80 px-4 py-3.5 sm:px-5', children: [(0, jsx_runtime_1.jsxs)("div", { className: 'flex min-w-0 flex-col gap-0.5', children: [(0, jsx_runtime_1.jsx)("h2", { className: 'truncate text-lg font-semibold leading-tight text-ink', children: title }), subtitle ? (0, jsx_runtime_1.jsx)("p", { className: 'truncate text-xs text-ink/55', children: subtitle }) : null] }), headerActions ? ((0, jsx_runtime_1.jsx)("div", { className: 'flex shrink-0 items-center gap-2', children: headerActions })) : null] }), (0, jsx_runtime_1.jsx)("div", { className: 'ps-scrollbar-hidden min-h-0 flex-1 overflow-y-auto px-4 py-4 sm:px-5', children: children }), footer || footerStart ? ((0, jsx_runtime_1.jsxs)("footer", { className: 'flex shrink-0 flex-wrap items-center justify-between gap-2 border-t border-line/80 px-4 py-3 sm:px-5', children: [footerStart ? (0, jsx_runtime_1.jsx)("div", { className: 'flex min-w-0 items-center gap-2', children: footerStart }) : null, (0, jsx_runtime_1.jsx)("div", { className: 'ml-auto flex flex-wrap items-center justify-end gap-2', children: footer })] })) : null] }));
|
|
7
|
+
exports.PsDetailPane = PsDetailPane;
|
|
@@ -5,6 +5,7 @@ export interface PsDocumentRowProps {
|
|
|
5
5
|
badges?: ReactNode;
|
|
6
6
|
className?: string;
|
|
7
7
|
date?: string;
|
|
8
|
+
isActive?: boolean;
|
|
8
9
|
isSelected?: boolean;
|
|
9
10
|
note?: ReactNode;
|
|
10
11
|
onOpen?: () => void;
|
|
@@ -16,4 +17,4 @@ export interface PsDocumentRowProps {
|
|
|
16
17
|
thumbnailSrc?: string | null;
|
|
17
18
|
title: string;
|
|
18
19
|
}
|
|
19
|
-
export declare const PsDocumentRow: ({ actions, amount, badges, className, date, isSelected, note, onOpen, onPrefetch, select, subtitle, thumbnailAlt, thumbnailFallback, thumbnailSrc, title, }: PsDocumentRowProps) => import("react").JSX.Element;
|
|
20
|
+
export declare const PsDocumentRow: ({ actions, amount, badges, className, date, isActive, isSelected, note, onOpen, onPrefetch, select, subtitle, thumbnailAlt, thumbnailFallback, thumbnailSrc, title, }: PsDocumentRowProps) => import("react").JSX.Element;
|
|
@@ -3,14 +3,19 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.PsDocumentRow = void 0;
|
|
4
4
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
5
|
const ps_design_system_1 = require("@pallasoft/ps-design-system");
|
|
6
|
-
const PsDocumentRow = ({ actions, amount, badges, className, date, isSelected = false, note, onOpen, onPrefetch, select, subtitle, thumbnailAlt = '', thumbnailFallback, thumbnailSrc, title, }) => {
|
|
6
|
+
const PsDocumentRow = ({ actions, amount, badges, className, date, isActive = false, isSelected = false, note, onOpen, onPrefetch, select, subtitle, thumbnailAlt = '', thumbnailFallback, thumbnailSrc, title, }) => {
|
|
7
7
|
const Main = onOpen ? 'button' : 'div';
|
|
8
|
-
return ((0, jsx_runtime_1.jsxs)("div", { className: ps_design_system_1.PallasoftClassNameService.merge('flex min-w-0 flex-wrap items-center gap-x-3 gap-y-2 border-b border-line/70 px-3 py-3 transition-colors last:border-b-0 sm:flex-nowrap',
|
|
8
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: ps_design_system_1.PallasoftClassNameService.merge('flex min-w-0 flex-wrap items-center gap-x-3 gap-y-2 border-b border-line/70 px-3 py-3 transition-colors last:border-b-0 sm:flex-nowrap', isActive
|
|
9
|
+
? 'bg-primary/8 shadow-[inset_3px_0_0_rgb(var(--ps-color-primary-rgb))]'
|
|
10
|
+
: isSelected
|
|
11
|
+
? 'bg-primary/5'
|
|
12
|
+
: 'hover:bg-mist/40', className), children: [select ? (0, jsx_runtime_1.jsx)("span", { className: 'flex shrink-0 items-center', children: select }) : null, (0, jsx_runtime_1.jsxs)(Main, { className: 'ps-focus-ring grid min-w-0 flex-1 basis-0 grid-cols-[auto_minmax(0,1fr)] items-center gap-x-3 gap-y-1 rounded-ps-control text-left sm:grid-cols-[auto_minmax(0,1fr)_auto]', ...(onOpen
|
|
9
13
|
? {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
+
'aria-current': isActive ? 'true' : undefined,
|
|
15
|
+
'onClick': onOpen,
|
|
16
|
+
'onFocus': onPrefetch,
|
|
17
|
+
'onPointerEnter': onPrefetch,
|
|
18
|
+
'type': 'button',
|
|
14
19
|
}
|
|
15
20
|
: {}), children: [(0, jsx_runtime_1.jsx)("span", { className: 'row-span-2 flex h-14 w-11 shrink-0 items-center justify-center overflow-hidden rounded-ps-control border border-line/60 bg-mist/40 sm:row-span-1', children: thumbnailSrc ? ((0, jsx_runtime_1.jsx)("img", { alt: thumbnailAlt, className: 'h-full w-full object-cover object-top', decoding: 'async', loading: 'lazy', src: thumbnailSrc })) : (thumbnailFallback) }), (0, jsx_runtime_1.jsxs)("span", { className: 'flex min-w-0 flex-col gap-0.5', children: [(0, jsx_runtime_1.jsx)("span", { className: 'truncate text-sm font-semibold text-ink', children: title }), subtitle ? (0, jsx_runtime_1.jsx)("span", { className: 'truncate text-xs text-ink/55', children: subtitle }) : null, badges ? ((0, jsx_runtime_1.jsx)("span", { className: 'flex flex-wrap items-center gap-1.5 pt-1', children: badges })) : null, note ? ((0, jsx_runtime_1.jsx)("span", { className: 'line-clamp-2 break-words pt-0.5 text-xs text-ink/70', children: note })) : null] }), amount || date ? ((0, jsx_runtime_1.jsxs)("span", { className: 'col-start-2 flex items-baseline gap-2 sm:col-start-3 sm:flex-col sm:items-end sm:gap-0.5', children: [amount ? ((0, jsx_runtime_1.jsx)("span", { className: 'text-sm font-semibold tabular-nums text-ink', children: amount })) : null, date ? (0, jsx_runtime_1.jsx)("span", { className: 'text-xs tabular-nums text-ink/55', children: date }) : null] })) : null] }), actions ? ((0, jsx_runtime_1.jsx)("div", { className: 'flex w-full shrink-0 items-center justify-end gap-2 sm:w-auto', children: actions })) : null] }));
|
|
16
21
|
};
|
|
@@ -1,10 +1,13 @@
|
|
|
1
|
+
import type { ElementType } from 'react';
|
|
1
2
|
export interface PsFormFooterProps {
|
|
2
3
|
isSaving: boolean;
|
|
3
4
|
isSecondaryVisible?: boolean;
|
|
4
5
|
isSubmitDisabled: boolean;
|
|
5
|
-
|
|
6
|
+
LinkComponent?: ElementType;
|
|
7
|
+
onSecondary?: () => void;
|
|
6
8
|
savingLabel: string;
|
|
9
|
+
secondaryHref?: string;
|
|
7
10
|
secondaryLabel: string;
|
|
8
11
|
submitLabel: string;
|
|
9
12
|
}
|
|
10
|
-
export declare const PsFormFooter: ({ isSaving, isSecondaryVisible, isSubmitDisabled, onSecondary, savingLabel, secondaryLabel, submitLabel, }: PsFormFooterProps) => import("react").JSX.Element;
|
|
13
|
+
export declare const PsFormFooter: ({ isSaving, isSecondaryVisible, isSubmitDisabled, LinkComponent, onSecondary, savingLabel, secondaryHref, secondaryLabel, submitLabel, }: PsFormFooterProps) => import("react").JSX.Element;
|
|
@@ -3,5 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.PsFormFooter = void 0;
|
|
4
4
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
5
|
const ps_button_1 = require("./ps-button");
|
|
6
|
-
const
|
|
6
|
+
const ps_link_button_1 = require("./ps-link-button");
|
|
7
|
+
const PsFormFooter = ({ isSaving, isSecondaryVisible = true, isSubmitDisabled, LinkComponent, onSecondary, savingLabel, secondaryHref, secondaryLabel, submitLabel, }) => ((0, jsx_runtime_1.jsxs)("div", { className: 'sticky bottom-0 z-docked -mx-4 flex justify-end gap-2 border-t border-line bg-surface/90 px-4 py-3 backdrop-blur sm:bottom-4 sm:mx-0 sm:border-0 sm:bg-transparent sm:px-0 sm:py-0 sm:backdrop-blur-none', children: [!isSecondaryVisible ? null : secondaryHref === undefined ? ((0, jsx_runtime_1.jsx)(ps_button_1.PsButton, { disabled: isSaving, onClick: onSecondary, type: 'button', variant: 'surface', children: secondaryLabel })) : ((0, jsx_runtime_1.jsx)(ps_link_button_1.PsLinkButton, { href: secondaryHref, LinkComponent: LinkComponent, variant: 'surface', children: secondaryLabel })), (0, jsx_runtime_1.jsx)(ps_button_1.PsButton, { disabled: isSubmitDisabled || isSaving, isLoading: isSaving, loadingLabel: savingLabel, type: 'submit', variant: 'primary', children: submitLabel })] }));
|
|
7
8
|
exports.PsFormFooter = PsFormFooter;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PsSplitView = void 0;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const use_ps_fill_height_1 = require("../hooks/use-ps-fill-height");
|
|
6
|
+
const PsSplitView = ({ detail, list }) => {
|
|
7
|
+
const isSplit = detail !== null && detail !== undefined && detail !== false;
|
|
8
|
+
const { height, ref } = (0, use_ps_fill_height_1.usePsFillHeight)(isSplit);
|
|
9
|
+
if (!isSplit)
|
|
10
|
+
return (0, jsx_runtime_1.jsx)("div", { className: 'min-w-0', children: list });
|
|
11
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: 'min-w-0 xl:grid xl:h-[var(--ps-split-height,calc(100dvh-14rem))] xl:grid-cols-[minmax(0,1fr)_minmax(26rem,34rem)] xl:gap-4', ref: ref, style: height === null ? undefined : { '--ps-split-height': `${height}px` }, children: [(0, jsx_runtime_1.jsx)("div", { className: 'ps-scrollbar-hidden min-h-0 min-w-0 xl:overflow-y-auto', children: list }), (0, jsx_runtime_1.jsx)("div", { className: 'hidden min-h-0 min-w-0 xl:block', children: detail })] }));
|
|
12
|
+
};
|
|
13
|
+
exports.PsSplitView = PsSplitView;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ElementType, ReactNode } from 'react';
|
|
2
|
+
export interface PsTextLinkProps {
|
|
3
|
+
'aria-label'?: string;
|
|
4
|
+
'children': ReactNode;
|
|
5
|
+
'className'?: string;
|
|
6
|
+
'href'?: string;
|
|
7
|
+
'id'?: string;
|
|
8
|
+
'LinkComponent'?: ElementType;
|
|
9
|
+
'onClick'?: () => void;
|
|
10
|
+
'size'?: 'compact' | 'default';
|
|
11
|
+
}
|
|
12
|
+
export declare const PsTextLink: ({ children, className, href, LinkComponent, onClick, size, ...props }: PsTextLinkProps) => import("react").JSX.Element;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PsTextLink = void 0;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const ps_design_system_1 = require("@pallasoft/ps-design-system");
|
|
6
|
+
const ps_text_link_classes_1 = require("../constants/ps-text-link-classes");
|
|
7
|
+
const PsTextLink = ({ children, className, href, LinkComponent, onClick, size = 'default', ...props }) => {
|
|
8
|
+
const linkClassName = ps_design_system_1.PallasoftClassNameService.merge(ps_text_link_classes_1.PsTextLinkClassName, ps_text_link_classes_1.PsTextLinkSizeClassNames[size], className);
|
|
9
|
+
if (href === undefined)
|
|
10
|
+
return ((0, jsx_runtime_1.jsx)("button", { className: linkClassName, onClick: onClick, type: 'button', ...props, children: children }));
|
|
11
|
+
return LinkComponent ? ((0, jsx_runtime_1.jsx)(LinkComponent, { className: linkClassName, onClick: onClick, prefetch: 'intent', to: href, ...props, children: children })) : ((0, jsx_runtime_1.jsx)("a", { className: linkClassName, href: href, onClick: onClick, ...props, children: children }));
|
|
12
|
+
};
|
|
13
|
+
exports.PsTextLink = PsTextLink;
|
|
@@ -9,14 +9,14 @@ exports.PsButtonSizeClassNames = {
|
|
|
9
9
|
};
|
|
10
10
|
exports.PsButtonVariantClassNames = {
|
|
11
11
|
danger: 'border-danger bg-danger text-white enabled:hover:opacity-90',
|
|
12
|
-
ghost: '
|
|
12
|
+
ghost: 'ps-liquid ps-liquid-control bg-white/72 text-ink enabled:hover:border-primary/30 dark:border-white/16 dark:bg-white/12',
|
|
13
13
|
primary: 'border-primary bg-primary text-[color:var(--ps-color-primary-contrast)] enabled:hover:border-primary-dark enabled:hover:bg-primary-dark',
|
|
14
14
|
secondary: 'ps-liquid ps-liquid-control bg-white/72 text-ink enabled:hover:border-primary/30 enabled:hover:text-primary dark:border-white/16 dark:bg-white/12 dark:enabled:hover:text-white',
|
|
15
15
|
surface: 'ps-liquid ps-liquid-control bg-white/72 text-ink enabled:hover:border-primary/30 dark:border-white/16 dark:bg-white/12',
|
|
16
16
|
};
|
|
17
17
|
exports.PsLinkButtonVariantClassNames = {
|
|
18
18
|
danger: 'border-danger bg-danger text-white hover:opacity-90',
|
|
19
|
-
ghost: '
|
|
19
|
+
ghost: 'ps-liquid ps-liquid-control bg-white/72 text-ink hover:border-primary/30 dark:border-white/16 dark:bg-white/12',
|
|
20
20
|
primary: 'border-primary bg-primary text-[color:var(--ps-color-primary-contrast)] hover:border-primary-dark hover:bg-primary-dark',
|
|
21
21
|
secondary: 'ps-liquid ps-liquid-control bg-white/72 text-ink hover:border-primary/30 hover:text-primary dark:border-white/16 dark:bg-white/12 dark:hover:text-white',
|
|
22
22
|
surface: 'ps-liquid ps-liquid-control bg-white/72 text-ink hover:border-primary/30 dark:border-white/16 dark:bg-white/12',
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare const PsTextLinkClassName = "ps-focus-ring inline-flex max-w-full items-center gap-1 rounded-sm font-semibold text-primary underline-offset-4 transition-colors hover:underline";
|
|
2
|
+
export declare const PsTextLinkSizeClassNames: {
|
|
3
|
+
compact: string;
|
|
4
|
+
default: string;
|
|
5
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PsTextLinkSizeClassNames = exports.PsTextLinkClassName = void 0;
|
|
4
|
+
exports.PsTextLinkClassName = 'ps-focus-ring inline-flex max-w-full items-center gap-1 rounded-sm font-semibold text-primary underline-offset-4 transition-colors hover:underline';
|
|
5
|
+
exports.PsTextLinkSizeClassNames = {
|
|
6
|
+
compact: 'text-xs',
|
|
7
|
+
default: 'text-sm',
|
|
8
|
+
};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { PallasoftClassNameService } from '@pallasoft/ps-design-system';
|
|
3
|
+
export const PsActionTileContent = ({ description, icon, label, variant, }) => (_jsxs(_Fragment, { children: [_jsxs("span", { className: 'min-w-0', children: [_jsx("span", { className: 'block break-words', children: label }), description ? (_jsx("span", { className: PallasoftClassNameService.merge('mt-0.5 block text-xs font-medium leading-5', variant === 'primary' ? 'text-white/75' : 'text-ink/50'), children: description })) : null] }), icon ? (_jsx("span", { className: PallasoftClassNameService.merge('flex h-9 w-9 shrink-0 items-center justify-center rounded-lg', variant === 'primary' ? 'bg-white/15 text-white' : 'ps-icon-surface'), children: icon })) : null] }));
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { PallasoftClassNameService } from '@pallasoft/ps-design-system';
|
|
3
|
+
import { PsActionTileContent } from './ps-action-tile-content.js';
|
|
4
|
+
const variantClassNames = {
|
|
5
|
+
default: 'ps-action-tile',
|
|
6
|
+
primary: 'ps-action-tile ps-action-tile-primary',
|
|
7
|
+
};
|
|
8
|
+
export const PsActionTileLink = ({ className, description, href, icon, label, LinkComponent, variant = 'default', ...props }) => {
|
|
9
|
+
const linkClassName = PallasoftClassNameService.merge('ps-focus-ring w-full', variantClassNames[variant], className);
|
|
10
|
+
const content = (_jsx(PsActionTileContent, { description: description, icon: icon, label: label, variant: variant }));
|
|
11
|
+
return LinkComponent ? (_jsx(LinkComponent, { className: linkClassName, prefetch: 'intent', to: href, ...props, children: content })) : (_jsx("a", { className: linkClassName, href: href, ...props, children: content }));
|
|
12
|
+
};
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { jsx as _jsx
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { PallasoftClassNameService } from '@pallasoft/ps-design-system';
|
|
3
3
|
import { PsSkeletonShape } from '../constants/ps-skeleton-shape.js';
|
|
4
|
+
import { PsActionTileContent } from './ps-action-tile-content.js';
|
|
4
5
|
import { PsSkeleton } from './ps-skeleton.js';
|
|
5
6
|
const variantClassNames = {
|
|
6
7
|
default: 'ps-action-tile',
|
|
7
8
|
primary: 'ps-action-tile ps-action-tile-primary',
|
|
8
9
|
};
|
|
9
|
-
export const PsActionTile = ({ className, description, icon, isLoading = false, label, type = 'button', variant = 'default', ...props }) => isLoading ? (_jsx(PsSkeleton, { className: PallasoftClassNameService.merge('h-16', className), shape: PsSkeletonShape.Card })) : (
|
|
10
|
+
export const PsActionTile = ({ className, description, icon, isLoading = false, label, type = 'button', variant = 'default', ...props }) => isLoading ? (_jsx(PsSkeleton, { className: PallasoftClassNameService.merge('h-16', className), shape: PsSkeletonShape.Card })) : (_jsx("button", { className: PallasoftClassNameService.merge('ps-focus-ring w-full', variantClassNames[variant], className), type: type, ...props, children: _jsx(PsActionTileContent, { description: description, icon: icon, label: label, variant: variant }) }));
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useState } from 'react';
|
|
3
3
|
import { PsCappedListConfig } from '../constants/ps-capped-list-config.js';
|
|
4
|
-
import {
|
|
4
|
+
import { PsTextLink } from './ps-text-link.js';
|
|
5
5
|
export const PsCappedList = ({ getKey, items, renderItem, showAllLabel, visibleRows = PsCappedListConfig.defaultVisibleRows, }) => {
|
|
6
6
|
const [isExpanded, setIsExpanded] = useState(false);
|
|
7
7
|
const isCapped = !isExpanded && items.length > visibleRows;
|
|
8
8
|
const shown = isCapped ? items.slice(0, visibleRows) : items;
|
|
9
|
-
return (_jsxs("div", { className: 'flex flex-col gap-2', children: [_jsx("ul", { className: '-my-2 flex flex-col divide-y divide-line', children: shown.map((item) => (_jsx("li", { children: renderItem(item) }, getKey(item)))) }), isCapped ? (_jsx(
|
|
9
|
+
return (_jsxs("div", { className: 'flex flex-col gap-2', children: [_jsx("ul", { className: '-my-2 flex flex-col divide-y divide-line', children: shown.map((item) => (_jsx("li", { children: renderItem(item) }, getKey(item)))) }), isCapped ? (_jsx(PsTextLink, { className: 'self-start', onClick: () => setIsExpanded(true), size: 'compact', children: showAllLabel })) : null] }));
|
|
10
10
|
};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { PallasoftClassNameService } from '@pallasoft/ps-design-system';
|
|
3
|
+
export const PsDetailPane = ({ children, className, footer, footerStart, headerActions, subtitle, title, }) => (_jsxs("section", { "aria-label": title, className: PallasoftClassNameService.merge('ps-card flex h-full min-h-0 min-w-0 flex-col overflow-hidden rounded-ps-card', className), children: [_jsxs("header", { className: 'flex shrink-0 items-start justify-between gap-3 border-b border-line/80 px-4 py-3.5 sm:px-5', children: [_jsxs("div", { className: 'flex min-w-0 flex-col gap-0.5', children: [_jsx("h2", { className: 'truncate text-lg font-semibold leading-tight text-ink', children: title }), subtitle ? _jsx("p", { className: 'truncate text-xs text-ink/55', children: subtitle }) : null] }), headerActions ? (_jsx("div", { className: 'flex shrink-0 items-center gap-2', children: headerActions })) : null] }), _jsx("div", { className: 'ps-scrollbar-hidden min-h-0 flex-1 overflow-y-auto px-4 py-4 sm:px-5', children: children }), footer || footerStart ? (_jsxs("footer", { className: 'flex shrink-0 flex-wrap items-center justify-between gap-2 border-t border-line/80 px-4 py-3 sm:px-5', children: [footerStart ? _jsx("div", { className: 'flex min-w-0 items-center gap-2', children: footerStart }) : null, _jsx("div", { className: 'ml-auto flex flex-wrap items-center justify-end gap-2', children: footer })] })) : null] }));
|
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { PallasoftClassNameService } from '@pallasoft/ps-design-system';
|
|
3
|
-
export const PsDocumentRow = ({ actions, amount, badges, className, date, isSelected = false, note, onOpen, onPrefetch, select, subtitle, thumbnailAlt = '', thumbnailFallback, thumbnailSrc, title, }) => {
|
|
3
|
+
export const PsDocumentRow = ({ actions, amount, badges, className, date, isActive = false, isSelected = false, note, onOpen, onPrefetch, select, subtitle, thumbnailAlt = '', thumbnailFallback, thumbnailSrc, title, }) => {
|
|
4
4
|
const Main = onOpen ? 'button' : 'div';
|
|
5
|
-
return (_jsxs("div", { className: PallasoftClassNameService.merge('flex min-w-0 flex-wrap items-center gap-x-3 gap-y-2 border-b border-line/70 px-3 py-3 transition-colors last:border-b-0 sm:flex-nowrap',
|
|
5
|
+
return (_jsxs("div", { className: PallasoftClassNameService.merge('flex min-w-0 flex-wrap items-center gap-x-3 gap-y-2 border-b border-line/70 px-3 py-3 transition-colors last:border-b-0 sm:flex-nowrap', isActive
|
|
6
|
+
? 'bg-primary/8 shadow-[inset_3px_0_0_rgb(var(--ps-color-primary-rgb))]'
|
|
7
|
+
: isSelected
|
|
8
|
+
? 'bg-primary/5'
|
|
9
|
+
: 'hover:bg-mist/40', className), children: [select ? _jsx("span", { className: 'flex shrink-0 items-center', children: select }) : null, _jsxs(Main, { className: 'ps-focus-ring grid min-w-0 flex-1 basis-0 grid-cols-[auto_minmax(0,1fr)] items-center gap-x-3 gap-y-1 rounded-ps-control text-left sm:grid-cols-[auto_minmax(0,1fr)_auto]', ...(onOpen
|
|
6
10
|
? {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
+
'aria-current': isActive ? 'true' : undefined,
|
|
12
|
+
'onClick': onOpen,
|
|
13
|
+
'onFocus': onPrefetch,
|
|
14
|
+
'onPointerEnter': onPrefetch,
|
|
15
|
+
'type': 'button',
|
|
11
16
|
}
|
|
12
17
|
: {}), children: [_jsx("span", { className: 'row-span-2 flex h-14 w-11 shrink-0 items-center justify-center overflow-hidden rounded-ps-control border border-line/60 bg-mist/40 sm:row-span-1', children: thumbnailSrc ? (_jsx("img", { alt: thumbnailAlt, className: 'h-full w-full object-cover object-top', decoding: 'async', loading: 'lazy', src: thumbnailSrc })) : (thumbnailFallback) }), _jsxs("span", { className: 'flex min-w-0 flex-col gap-0.5', children: [_jsx("span", { className: 'truncate text-sm font-semibold text-ink', children: title }), subtitle ? _jsx("span", { className: 'truncate text-xs text-ink/55', children: subtitle }) : null, badges ? (_jsx("span", { className: 'flex flex-wrap items-center gap-1.5 pt-1', children: badges })) : null, note ? (_jsx("span", { className: 'line-clamp-2 break-words pt-0.5 text-xs text-ink/70', children: note })) : null] }), amount || date ? (_jsxs("span", { className: 'col-start-2 flex items-baseline gap-2 sm:col-start-3 sm:flex-col sm:items-end sm:gap-0.5', children: [amount ? (_jsx("span", { className: 'text-sm font-semibold tabular-nums text-ink', children: amount })) : null, date ? _jsx("span", { className: 'text-xs tabular-nums text-ink/55', children: date }) : null] })) : null] }), actions ? (_jsx("div", { className: 'flex w-full shrink-0 items-center justify-end gap-2 sm:w-auto', children: actions })) : null] }));
|
|
13
18
|
};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { PsButton } from './ps-button.js';
|
|
3
|
-
|
|
3
|
+
import { PsLinkButton } from './ps-link-button.js';
|
|
4
|
+
export const PsFormFooter = ({ isSaving, isSecondaryVisible = true, isSubmitDisabled, LinkComponent, onSecondary, savingLabel, secondaryHref, secondaryLabel, submitLabel, }) => (_jsxs("div", { className: 'sticky bottom-0 z-docked -mx-4 flex justify-end gap-2 border-t border-line bg-surface/90 px-4 py-3 backdrop-blur sm:bottom-4 sm:mx-0 sm:border-0 sm:bg-transparent sm:px-0 sm:py-0 sm:backdrop-blur-none', children: [!isSecondaryVisible ? null : secondaryHref === undefined ? (_jsx(PsButton, { disabled: isSaving, onClick: onSecondary, type: 'button', variant: 'surface', children: secondaryLabel })) : (_jsx(PsLinkButton, { href: secondaryHref, LinkComponent: LinkComponent, variant: 'surface', children: secondaryLabel })), _jsx(PsButton, { disabled: isSubmitDisabled || isSaving, isLoading: isSaving, loadingLabel: savingLabel, type: 'submit', variant: 'primary', children: submitLabel })] }));
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { usePsFillHeight } from '../hooks/use-ps-fill-height.js';
|
|
3
|
+
export const PsSplitView = ({ detail, list }) => {
|
|
4
|
+
const isSplit = detail !== null && detail !== undefined && detail !== false;
|
|
5
|
+
const { height, ref } = usePsFillHeight(isSplit);
|
|
6
|
+
if (!isSplit)
|
|
7
|
+
return _jsx("div", { className: 'min-w-0', children: list });
|
|
8
|
+
return (_jsxs("div", { className: 'min-w-0 xl:grid xl:h-[var(--ps-split-height,calc(100dvh-14rem))] xl:grid-cols-[minmax(0,1fr)_minmax(26rem,34rem)] xl:gap-4', ref: ref, style: height === null ? undefined : { '--ps-split-height': `${height}px` }, children: [_jsx("div", { className: 'ps-scrollbar-hidden min-h-0 min-w-0 xl:overflow-y-auto', children: list }), _jsx("div", { className: 'hidden min-h-0 min-w-0 xl:block', children: detail })] }));
|
|
9
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { PallasoftClassNameService } from '@pallasoft/ps-design-system';
|
|
3
|
+
import { PsTextLinkClassName, PsTextLinkSizeClassNames } from '../constants/ps-text-link-classes.js';
|
|
4
|
+
export const PsTextLink = ({ children, className, href, LinkComponent, onClick, size = 'default', ...props }) => {
|
|
5
|
+
const linkClassName = PallasoftClassNameService.merge(PsTextLinkClassName, PsTextLinkSizeClassNames[size], className);
|
|
6
|
+
if (href === undefined)
|
|
7
|
+
return (_jsx("button", { className: linkClassName, onClick: onClick, type: 'button', ...props, children: children }));
|
|
8
|
+
return LinkComponent ? (_jsx(LinkComponent, { className: linkClassName, onClick: onClick, prefetch: 'intent', to: href, ...props, children: children })) : (_jsx("a", { className: linkClassName, href: href, onClick: onClick, ...props, children: children }));
|
|
9
|
+
};
|
|
@@ -6,14 +6,14 @@ export const PsButtonSizeClassNames = {
|
|
|
6
6
|
};
|
|
7
7
|
export const PsButtonVariantClassNames = {
|
|
8
8
|
danger: 'border-danger bg-danger text-white enabled:hover:opacity-90',
|
|
9
|
-
ghost: '
|
|
9
|
+
ghost: 'ps-liquid ps-liquid-control bg-white/72 text-ink enabled:hover:border-primary/30 dark:border-white/16 dark:bg-white/12',
|
|
10
10
|
primary: 'border-primary bg-primary text-[color:var(--ps-color-primary-contrast)] enabled:hover:border-primary-dark enabled:hover:bg-primary-dark',
|
|
11
11
|
secondary: 'ps-liquid ps-liquid-control bg-white/72 text-ink enabled:hover:border-primary/30 enabled:hover:text-primary dark:border-white/16 dark:bg-white/12 dark:enabled:hover:text-white',
|
|
12
12
|
surface: 'ps-liquid ps-liquid-control bg-white/72 text-ink enabled:hover:border-primary/30 dark:border-white/16 dark:bg-white/12',
|
|
13
13
|
};
|
|
14
14
|
export const PsLinkButtonVariantClassNames = {
|
|
15
15
|
danger: 'border-danger bg-danger text-white hover:opacity-90',
|
|
16
|
-
ghost: '
|
|
16
|
+
ghost: 'ps-liquid ps-liquid-control bg-white/72 text-ink hover:border-primary/30 dark:border-white/16 dark:bg-white/12',
|
|
17
17
|
primary: 'border-primary bg-primary text-[color:var(--ps-color-primary-contrast)] hover:border-primary-dark hover:bg-primary-dark',
|
|
18
18
|
secondary: 'ps-liquid ps-liquid-control bg-white/72 text-ink hover:border-primary/30 hover:text-primary dark:border-white/16 dark:bg-white/12 dark:hover:text-white',
|
|
19
19
|
surface: 'ps-liquid ps-liquid-control bg-white/72 text-ink hover:border-primary/30 dark:border-white/16 dark:bg-white/12',
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export const PsTextLinkClassName = 'ps-focus-ring inline-flex max-w-full items-center gap-1 rounded-sm font-semibold text-primary underline-offset-4 transition-colors hover:underline';
|
|
2
|
+
export const PsTextLinkSizeClassNames = {
|
|
3
|
+
compact: 'text-xs',
|
|
4
|
+
default: 'text-sm',
|
|
5
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { useLayoutEffect, useRef, useState } from 'react';
|
|
2
|
+
import { PsFillHeightService } from '../services/ps-fill-height-service.js';
|
|
3
|
+
export const usePsFillHeight = (isActive) => {
|
|
4
|
+
const ref = useRef(null);
|
|
5
|
+
const [height, setHeight] = useState(null);
|
|
6
|
+
useLayoutEffect(() => {
|
|
7
|
+
const element = ref.current;
|
|
8
|
+
if (!isActive || element === null)
|
|
9
|
+
return;
|
|
10
|
+
const scroller = PsFillHeightService.scroller(element);
|
|
11
|
+
const measure = () => setHeight(PsFillHeightService.height(element, scroller));
|
|
12
|
+
const observer = new ResizeObserver(measure);
|
|
13
|
+
measure();
|
|
14
|
+
observer.observe(scroller);
|
|
15
|
+
if (element.parentElement !== null)
|
|
16
|
+
observer.observe(element.parentElement);
|
|
17
|
+
return () => observer.disconnect();
|
|
18
|
+
}, [isActive]);
|
|
19
|
+
return { height, ref };
|
|
20
|
+
};
|
package/dist/esm/index.js
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
export * from './components/ps-layer.js';
|
|
2
2
|
export * from './components/ps-accordion.js';
|
|
3
3
|
export * from './components/ps-action-tile.js';
|
|
4
|
+
export * from './components/ps-action-tile-link.js';
|
|
4
5
|
export * from './components/ps-audio-spectrum.js';
|
|
5
6
|
export * from './constants/ps-audio-spectrum-config.js';
|
|
6
7
|
export * from './components/ps-badge.js';
|
|
7
8
|
export * from './components/ps-button.js';
|
|
8
9
|
export * from './components/ps-link-button.js';
|
|
10
|
+
export * from './components/ps-text-link.js';
|
|
9
11
|
export * from './components/ps-pallasoft-mark.js';
|
|
10
12
|
export * from './components/ps-pallasoft-sign-in-button.js';
|
|
11
13
|
export * from './components/ps-store-badge.js';
|
|
@@ -69,6 +71,7 @@ export * from './hooks/use-ps-element-size.js';
|
|
|
69
71
|
export * from './hooks/use-ps-hydrated.js';
|
|
70
72
|
export * from './hooks/use-ps-viewport.js';
|
|
71
73
|
export * from './hooks/use-ps-media-query.js';
|
|
74
|
+
export * from './hooks/use-ps-fill-height.js';
|
|
72
75
|
export * from './interfaces/ps-component-props.js';
|
|
73
76
|
export * from './models/ps-element-size.js';
|
|
74
77
|
export * from './models/ps-voice-orb.js';
|
|
@@ -153,6 +156,8 @@ export * from './models/ps-theme-mode-state.js';
|
|
|
153
156
|
export * from './models/ps-tool-card-data.js';
|
|
154
157
|
export * from './components/ps-capped-list.js';
|
|
155
158
|
export * from './components/ps-detail-list.js';
|
|
159
|
+
export * from './components/ps-detail-pane.js';
|
|
160
|
+
export * from './components/ps-split-view.js';
|
|
156
161
|
export * from './components/ps-overview-card.js';
|
|
157
162
|
export * from './components/ps-form-footer.js';
|
|
158
163
|
export * from './components/ps-start-highlight.js';
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { PsSplitViewConfig } from '../constants/ps-split-view-config.js';
|
|
2
|
+
export class PsFillHeightService {
|
|
3
|
+
static scroller(element) {
|
|
4
|
+
let parent = element.parentElement;
|
|
5
|
+
while (parent !== null) {
|
|
6
|
+
if (PsSplitViewConfig.scrollableOverflow.test(getComputedStyle(parent).overflowY))
|
|
7
|
+
return parent;
|
|
8
|
+
parent = parent.parentElement;
|
|
9
|
+
}
|
|
10
|
+
return document.documentElement;
|
|
11
|
+
}
|
|
12
|
+
static height(element, scroller) {
|
|
13
|
+
const isPage = scroller === document.documentElement;
|
|
14
|
+
const frameTop = isPage ? 0 : scroller.getBoundingClientRect().top;
|
|
15
|
+
const frameHeight = isPage ? window.innerHeight : scroller.clientHeight;
|
|
16
|
+
const scrolled = isPage ? window.scrollY : scroller.scrollTop;
|
|
17
|
+
const box = element.getBoundingClientRect();
|
|
18
|
+
const top = box.top - frameTop + scrolled;
|
|
19
|
+
const below = PsFillHeightService.below(element, scroller);
|
|
20
|
+
return Math.max(PsSplitViewConfig.minHeight, Math.floor(frameHeight - top - below));
|
|
21
|
+
}
|
|
22
|
+
static below(element, scroller) {
|
|
23
|
+
let node = element;
|
|
24
|
+
let parent = element.parentElement;
|
|
25
|
+
let total = parseFloat(getComputedStyle(scroller).paddingBottom);
|
|
26
|
+
while (parent !== null && parent !== scroller && parent !== document.body) {
|
|
27
|
+
total += Math.max(0, parent.getBoundingClientRect().bottom - node.getBoundingClientRect().bottom);
|
|
28
|
+
node = parent;
|
|
29
|
+
parent = parent.parentElement;
|
|
30
|
+
}
|
|
31
|
+
return total;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.usePsFillHeight = void 0;
|
|
4
|
+
const react_1 = require("react");
|
|
5
|
+
const ps_fill_height_service_1 = require("../services/ps-fill-height-service");
|
|
6
|
+
const usePsFillHeight = (isActive) => {
|
|
7
|
+
const ref = (0, react_1.useRef)(null);
|
|
8
|
+
const [height, setHeight] = (0, react_1.useState)(null);
|
|
9
|
+
(0, react_1.useLayoutEffect)(() => {
|
|
10
|
+
const element = ref.current;
|
|
11
|
+
if (!isActive || element === null)
|
|
12
|
+
return;
|
|
13
|
+
const scroller = ps_fill_height_service_1.PsFillHeightService.scroller(element);
|
|
14
|
+
const measure = () => setHeight(ps_fill_height_service_1.PsFillHeightService.height(element, scroller));
|
|
15
|
+
const observer = new ResizeObserver(measure);
|
|
16
|
+
measure();
|
|
17
|
+
observer.observe(scroller);
|
|
18
|
+
if (element.parentElement !== null)
|
|
19
|
+
observer.observe(element.parentElement);
|
|
20
|
+
return () => observer.disconnect();
|
|
21
|
+
}, [isActive]);
|
|
22
|
+
return { height, ref };
|
|
23
|
+
};
|
|
24
|
+
exports.usePsFillHeight = usePsFillHeight;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
export * from './components/ps-layer';
|
|
2
2
|
export * from './components/ps-accordion';
|
|
3
3
|
export * from './components/ps-action-tile';
|
|
4
|
+
export * from './components/ps-action-tile-link';
|
|
4
5
|
export * from './components/ps-audio-spectrum';
|
|
5
6
|
export * from './constants/ps-audio-spectrum-config';
|
|
6
7
|
export * from './components/ps-badge';
|
|
7
8
|
export * from './components/ps-button';
|
|
8
9
|
export * from './components/ps-link-button';
|
|
10
|
+
export * from './components/ps-text-link';
|
|
9
11
|
export * from './components/ps-pallasoft-mark';
|
|
10
12
|
export * from './components/ps-pallasoft-sign-in-button';
|
|
11
13
|
export * from './components/ps-store-badge';
|
|
@@ -69,6 +71,7 @@ export * from './hooks/use-ps-element-size';
|
|
|
69
71
|
export * from './hooks/use-ps-hydrated';
|
|
70
72
|
export * from './hooks/use-ps-viewport';
|
|
71
73
|
export * from './hooks/use-ps-media-query';
|
|
74
|
+
export * from './hooks/use-ps-fill-height';
|
|
72
75
|
export * from './interfaces/ps-component-props';
|
|
73
76
|
export * from './models/ps-element-size';
|
|
74
77
|
export * from './models/ps-voice-orb';
|
|
@@ -153,6 +156,8 @@ export * from './models/ps-theme-mode-state';
|
|
|
153
156
|
export * from './models/ps-tool-card-data';
|
|
154
157
|
export * from './components/ps-capped-list';
|
|
155
158
|
export * from './components/ps-detail-list';
|
|
159
|
+
export * from './components/ps-detail-pane';
|
|
160
|
+
export * from './components/ps-split-view';
|
|
156
161
|
export * from './components/ps-overview-card';
|
|
157
162
|
export * from './components/ps-form-footer';
|
|
158
163
|
export * from './components/ps-start-highlight';
|
package/dist/index.js
CHANGED
|
@@ -17,11 +17,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
17
17
|
__exportStar(require("./components/ps-layer"), exports);
|
|
18
18
|
__exportStar(require("./components/ps-accordion"), exports);
|
|
19
19
|
__exportStar(require("./components/ps-action-tile"), exports);
|
|
20
|
+
__exportStar(require("./components/ps-action-tile-link"), exports);
|
|
20
21
|
__exportStar(require("./components/ps-audio-spectrum"), exports);
|
|
21
22
|
__exportStar(require("./constants/ps-audio-spectrum-config"), exports);
|
|
22
23
|
__exportStar(require("./components/ps-badge"), exports);
|
|
23
24
|
__exportStar(require("./components/ps-button"), exports);
|
|
24
25
|
__exportStar(require("./components/ps-link-button"), exports);
|
|
26
|
+
__exportStar(require("./components/ps-text-link"), exports);
|
|
25
27
|
__exportStar(require("./components/ps-pallasoft-mark"), exports);
|
|
26
28
|
__exportStar(require("./components/ps-pallasoft-sign-in-button"), exports);
|
|
27
29
|
__exportStar(require("./components/ps-store-badge"), exports);
|
|
@@ -85,6 +87,7 @@ __exportStar(require("./hooks/use-ps-element-size"), exports);
|
|
|
85
87
|
__exportStar(require("./hooks/use-ps-hydrated"), exports);
|
|
86
88
|
__exportStar(require("./hooks/use-ps-viewport"), exports);
|
|
87
89
|
__exportStar(require("./hooks/use-ps-media-query"), exports);
|
|
90
|
+
__exportStar(require("./hooks/use-ps-fill-height"), exports);
|
|
88
91
|
__exportStar(require("./interfaces/ps-component-props"), exports);
|
|
89
92
|
__exportStar(require("./models/ps-element-size"), exports);
|
|
90
93
|
__exportStar(require("./models/ps-voice-orb"), exports);
|
|
@@ -169,6 +172,8 @@ __exportStar(require("./models/ps-theme-mode-state"), exports);
|
|
|
169
172
|
__exportStar(require("./models/ps-tool-card-data"), exports);
|
|
170
173
|
__exportStar(require("./components/ps-capped-list"), exports);
|
|
171
174
|
__exportStar(require("./components/ps-detail-list"), exports);
|
|
175
|
+
__exportStar(require("./components/ps-detail-pane"), exports);
|
|
176
|
+
__exportStar(require("./components/ps-split-view"), exports);
|
|
172
177
|
__exportStar(require("./components/ps-overview-card"), exports);
|
|
173
178
|
__exportStar(require("./components/ps-form-footer"), exports);
|
|
174
179
|
__exportStar(require("./components/ps-start-highlight"), exports);
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PsFillHeightService = void 0;
|
|
4
|
+
const ps_split_view_config_1 = require("../constants/ps-split-view-config");
|
|
5
|
+
class PsFillHeightService {
|
|
6
|
+
static scroller(element) {
|
|
7
|
+
let parent = element.parentElement;
|
|
8
|
+
while (parent !== null) {
|
|
9
|
+
if (ps_split_view_config_1.PsSplitViewConfig.scrollableOverflow.test(getComputedStyle(parent).overflowY))
|
|
10
|
+
return parent;
|
|
11
|
+
parent = parent.parentElement;
|
|
12
|
+
}
|
|
13
|
+
return document.documentElement;
|
|
14
|
+
}
|
|
15
|
+
static height(element, scroller) {
|
|
16
|
+
const isPage = scroller === document.documentElement;
|
|
17
|
+
const frameTop = isPage ? 0 : scroller.getBoundingClientRect().top;
|
|
18
|
+
const frameHeight = isPage ? window.innerHeight : scroller.clientHeight;
|
|
19
|
+
const scrolled = isPage ? window.scrollY : scroller.scrollTop;
|
|
20
|
+
const box = element.getBoundingClientRect();
|
|
21
|
+
const top = box.top - frameTop + scrolled;
|
|
22
|
+
const below = PsFillHeightService.below(element, scroller);
|
|
23
|
+
return Math.max(ps_split_view_config_1.PsSplitViewConfig.minHeight, Math.floor(frameHeight - top - below));
|
|
24
|
+
}
|
|
25
|
+
static below(element, scroller) {
|
|
26
|
+
let node = element;
|
|
27
|
+
let parent = element.parentElement;
|
|
28
|
+
let total = parseFloat(getComputedStyle(scroller).paddingBottom);
|
|
29
|
+
while (parent !== null && parent !== scroller && parent !== document.body) {
|
|
30
|
+
total += Math.max(0, parent.getBoundingClientRect().bottom - node.getBoundingClientRect().bottom);
|
|
31
|
+
node = parent;
|
|
32
|
+
parent = parent.parentElement;
|
|
33
|
+
}
|
|
34
|
+
return total;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
exports.PsFillHeightService = PsFillHeightService;
|