@ssa-ui-kit/core 3.16.4 → 3.19.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.
@@ -0,0 +1,12 @@
1
+ import { BreadcrumbSibling } from './types';
2
+ export interface BreadcrumbMenuProps {
3
+ /** Element that opens the menu on hover/click. Must forward a ref. */
4
+ trigger: React.ReactElement;
5
+ /** Navigable options shown inside the menu. */
6
+ items: BreadcrumbSibling[];
7
+ }
8
+ /**
9
+ * A hover/click popover listing navigable routes. Shared by the collapsed `…`
10
+ * crumb and, in the route-aware mode, by crumbs that expose sibling routes.
11
+ */
12
+ export declare const BreadcrumbMenu: ({ trigger, items }: BreadcrumbMenuProps) => import("@emotion/react/jsx-runtime").JSX.Element;
@@ -0,0 +1,23 @@
1
+ import { BreadcrumbsProps } from './types';
2
+ /**
3
+ * Breadcrumbs — navigational trail of the current page's location.
4
+ *
5
+ * Accepts a list of `{ label, to }` items and renders them as react-router
6
+ * links separated by a chevron, with the current (last) crumb shown as a
7
+ * non-navigable, emphasised label. When the trail is longer than `maxItems`
8
+ * it collapses to `first … last`, with the hidden crumbs available from the
9
+ * `…` menu.
10
+ *
11
+ * @example
12
+ * ```tsx
13
+ * <Breadcrumbs
14
+ * maxItems={4}
15
+ * items={[
16
+ * { label: 'Home', to: '/' },
17
+ * { label: 'People', to: '/people' },
18
+ * { label: 'Jane Doe' },
19
+ * ]}
20
+ * />
21
+ * ```
22
+ */
23
+ export declare const Breadcrumbs: ({ items, maxItems, separator, ariaLabel, className, css, }: BreadcrumbsProps) => import("@emotion/react/jsx-runtime").JSX.Element | null;
@@ -0,0 +1,5 @@
1
+ export { Breadcrumbs } from './Breadcrumbs';
2
+ export { BreadcrumbMenu } from './BreadcrumbMenu';
3
+ export { useBreadcrumbs, deriveBreadcrumbs } from './useBreadcrumbs';
4
+ export type { BreadcrumbsProps, BreadcrumbItem, BreadcrumbSibling, } from './types';
5
+ export type { UseBreadcrumbsOptions, BreadcrumbRouteHandle, BreadcrumbMatchContext, } from './useBreadcrumbs';
@@ -0,0 +1,9 @@
1
+ export declare const nav: import("@emotion/react").SerializedStyles;
2
+ export declare const list: import("@emotion/react").SerializedStyles;
3
+ export declare const item: import("@emotion/react").SerializedStyles;
4
+ export declare const separator: import("@emotion/react").SerializedStyles;
5
+ export declare const crumbLink: import("@emotion/react").SerializedStyles;
6
+ export declare const crumbText: import("@emotion/react").SerializedStyles;
7
+ export declare const crumbCurrent: import("@emotion/react").SerializedStyles;
8
+ export declare const menu: import("@emotion/react").SerializedStyles;
9
+ export declare const menuItem: import("@emotion/react").SerializedStyles;
@@ -0,0 +1,57 @@
1
+ import { Interpolation, Theme } from '@emotion/react';
2
+ import { To } from 'react-router-dom';
3
+ import { CommonProps } from '../../types/emotion';
4
+ /**
5
+ * A sibling route option shown in a breadcrumb's hover menu.
6
+ *
7
+ * Reserved for the route-aware mode (Mode 2): when a crumb carries `siblings`,
8
+ * the crumb becomes a hover target that reveals these alternative routes.
9
+ */
10
+ export interface BreadcrumbSibling {
11
+ label: React.ReactNode;
12
+ to: To;
13
+ }
14
+ /**
15
+ * A single breadcrumb entry.
16
+ *
17
+ * In the "dummy" mode you build these by hand. In the future route-aware mode
18
+ * the same shape is produced from the router matches, so the presentational
19
+ * `Breadcrumbs` component never needs to know which mode produced it.
20
+ */
21
+ export interface BreadcrumbItem {
22
+ /** Visible label for the crumb. */
23
+ label: React.ReactNode;
24
+ /**
25
+ * react-router destination. Omit for a non-navigable crumb (e.g. the current
26
+ * page). When present, the crumb navigates via react-router.
27
+ */
28
+ to?: To;
29
+ /**
30
+ * Force the "current page" styling (blue, semibold, non-link). When not set,
31
+ * the last item in the list is treated as current automatically.
32
+ */
33
+ isCurrent?: boolean;
34
+ /** Optional click handler, fired in addition to navigation. */
35
+ onClick?: () => void;
36
+ /**
37
+ * Sibling routes for this crumb. When provided, the crumb reveals a hover
38
+ * menu offering these alternatives. Populated by the route-aware mode.
39
+ */
40
+ siblings?: BreadcrumbSibling[];
41
+ }
42
+ export interface BreadcrumbsProps extends CommonProps {
43
+ /** Ordered list of crumbs, root first, current page last. */
44
+ items: BreadcrumbItem[];
45
+ /**
46
+ * Collapse the trail into `first … last` once the number of items exceeds
47
+ * this value. The collapsed middle crumbs are revealed from the `…` menu.
48
+ * When omitted, the full trail is always shown.
49
+ */
50
+ maxItems?: number;
51
+ /** Custom separator between crumbs. Defaults to a right chevron. */
52
+ separator?: React.ReactNode;
53
+ /** Accessible label for the wrapping `nav`. */
54
+ ariaLabel?: string;
55
+ /** Custom Emotion styles applied to the wrapping `nav`. */
56
+ css?: Interpolation<Theme>;
57
+ }
@@ -0,0 +1,54 @@
1
+ import { RouteObject } from 'react-router-dom';
2
+ import { BreadcrumbItem } from './types';
3
+ /** Context passed to a route's `crumb` resolver function. */
4
+ export interface BreadcrumbMatchContext {
5
+ params: Record<string, string | undefined>;
6
+ pathname: string;
7
+ }
8
+ /**
9
+ * Shape read from a route's `handle` to build its crumb. Attach this to routes
10
+ * in your `createBrowserRouter` config:
11
+ *
12
+ * ```ts
13
+ * { path: 'people', handle: { crumb: 'People' } as BreadcrumbRouteHandle }
14
+ * ```
15
+ */
16
+ export interface BreadcrumbRouteHandle {
17
+ /** Static label, or a resolver receiving the matched params/pathname. */
18
+ crumb?: React.ReactNode | ((ctx: BreadcrumbMatchContext) => React.ReactNode);
19
+ /** Fallback label used when `crumb` is absent (e.g. a page title). */
20
+ title?: React.ReactNode;
21
+ /** Explicitly exclude this route from the trail even if it has a title. */
22
+ hideCrumb?: boolean;
23
+ }
24
+ export interface UseBreadcrumbsOptions {
25
+ /** The route tree — the same array passed to `createBrowserRouter`. */
26
+ routes: RouteObject[];
27
+ /** Path to resolve against. Defaults to the current location. */
28
+ pathname?: string;
29
+ /** Attach sibling routes for the hover menu. Defaults to `true`. */
30
+ includeSiblings?: boolean;
31
+ /**
32
+ * Last-resort label resolver, called when a matched route has no
33
+ * `handle.crumb`/`handle.title`. Return `null`/`undefined` to skip the crumb.
34
+ */
35
+ getLabel?: (route: RouteObject, ctx: BreadcrumbMatchContext) => React.ReactNode;
36
+ }
37
+ /**
38
+ * Pure derivation of breadcrumb items from a route tree and a pathname.
39
+ * Extracted from the hook so it can be unit-tested without a router.
40
+ */
41
+ export declare const deriveBreadcrumbs: (routes: RouteObject[], pathname: string, { includeSiblings, getLabel }?: Partial<UseBreadcrumbsOptions>) => BreadcrumbItem[];
42
+ /**
43
+ * Route-aware breadcrumb builder. Reads the current location, matches it
44
+ * against your route tree, and returns `BreadcrumbItem[]` ready for
45
+ * `<Breadcrumbs>`. Labels come from each route's `handle.crumb`/`handle.title`;
46
+ * sibling routes (other children of a crumb's parent) power the hover menu.
47
+ *
48
+ * @example
49
+ * ```tsx
50
+ * const items = useBreadcrumbs({ routes });
51
+ * return <Breadcrumbs items={items} maxItems={4} />;
52
+ * ```
53
+ */
54
+ export declare const useBreadcrumbs: ({ routes, pathname, includeSiblings, getLabel, }: UseBreadcrumbsOptions) => BreadcrumbItem[];
@@ -0,0 +1,17 @@
1
+ import { BreadcrumbItem } from './types';
2
+ /** A rendered slot in the trail: either a real crumb or the collapsed `…`. */
3
+ export type BreadcrumbEntry = {
4
+ type: 'item';
5
+ item: BreadcrumbItem;
6
+ index: number;
7
+ } | {
8
+ type: 'ellipsis';
9
+ items: BreadcrumbItem[];
10
+ };
11
+ /**
12
+ * Collapse the trail to `first … last` when it exceeds `maxItems`, per design.
13
+ * The hidden middle crumbs are returned on the ellipsis entry so they can be
14
+ * offered from its menu. When `maxItems` is falsy or not exceeded, every item
15
+ * is returned as-is.
16
+ */
17
+ export declare const collapseItems: (items: BreadcrumbItem[], maxItems?: number) => BreadcrumbEntry[];
@@ -8,7 +8,7 @@
8
8
  * - **`both`** — a standalone selection (or a one-cell range), fully rounded
9
9
  */
10
10
  export type RangeEdge = 'start' | 'end' | 'both';
11
- export declare const getCellRadius: (rangeEdge: RangeEdge | undefined, isHighlighted: boolean) => "6px" | "6px 0 0 6px" | "0 6px 6px 0" | "0";
11
+ export declare const getCellRadius: (rangeEdge: RangeEdge | undefined, isHighlighted: boolean) => "6px" | "0" | "6px 0 0 6px" | "0 6px 6px 0";
12
12
  /**
13
13
  * Works out which edge of a highlighted range a selected cell sits on.
14
14
  *
@@ -0,0 +1,36 @@
1
+ import { FileAttachmentProps } from './types';
2
+ /**
3
+ * FileAttachment - Read-only row displaying a single attached/uploading file
4
+ *
5
+ * @example
6
+ * ```tsx
7
+ * <FileAttachment
8
+ * file={{ name: 'Report.pdf', size: 20 * 1024 * 1024 }}
9
+ * progress={50}
10
+ * onRemove={() => handleRemove(file)}
11
+ * />
12
+ * ```
13
+ *
14
+ * @example
15
+ * ```tsx
16
+ * // Progress bar look instead of the default percentage text
17
+ * <FileAttachment
18
+ * file={{ name: 'Report.pdf', size: 20 * 1024 * 1024 }}
19
+ * progress={50}
20
+ * progressDisplay="bar"
21
+ * onRemove={() => handleRemove(file)}
22
+ * />
23
+ * ```
24
+ *
25
+ * @example
26
+ * ```tsx
27
+ * // Omitting `progress` entirely shows just the file size, no progress copy —
28
+ * // e.g. a file that's been selected but whose upload hasn't started yet.
29
+ * <FileAttachment
30
+ * file={{ name: 'Report.pdf', size: 20 * 1024 * 1024 }}
31
+ * onRemove={() => handleRemove(file)}
32
+ * />
33
+ * ```
34
+ */
35
+ declare const FileAttachment: ({ file, size, progress, progressDisplay, uploadingText, uploadedText, showDescription, icon, isDisabled, onRemove, className, css: cssProp, }: FileAttachmentProps) => import("@emotion/react/jsx-runtime").JSX.Element;
36
+ export default FileAttachment;
@@ -0,0 +1 @@
1
+ export { useFilePreviewUrl } from './useFilePreviewUrl';
@@ -0,0 +1,2 @@
1
+ /** Creates an object URL for a local File/Blob and revokes it on unmount or when `content` changes, avoiding a memory leak. */
2
+ export declare const useFilePreviewUrl: (content?: File | Blob) => string | undefined;
@@ -0,0 +1,2 @@
1
+ export { default } from './FileAttachment';
2
+ export type * from './types';
@@ -0,0 +1,22 @@
1
+ import { Theme } from '@emotion/react';
2
+ export declare const iconSizeBySize: {
3
+ large: number;
4
+ small: number;
5
+ };
6
+ /** Placeholder glyph is inset ~20% on each side of its box in the design (40px box -> 24px glyph). */
7
+ export declare const placeholderIconSizeBySize: {
8
+ large: number;
9
+ small: number;
10
+ };
11
+ export declare const container: (theme: Theme, size: "large" | "small") => import("@emotion/react").SerializedStyles;
12
+ export declare const disabledContainer: (theme: Theme) => import("@emotion/react").SerializedStyles;
13
+ export declare const iconWrapper: (size: "large" | "small") => import("@emotion/react").SerializedStyles;
14
+ export declare const placeholderWrapper: (theme: Theme) => import("@emotion/react").SerializedStyles;
15
+ export declare const previewImage: import("@emotion/react").SerializedStyles;
16
+ export declare const textColumn: import("@emotion/react").SerializedStyles;
17
+ export declare const title: (theme: Theme) => import("@emotion/react").SerializedStyles;
18
+ export declare const description: (theme: Theme) => import("@emotion/react").SerializedStyles;
19
+ export declare const dot: (theme: Theme) => import("@emotion/react").SerializedStyles;
20
+ export declare const progressTrack: (theme: Theme) => import("@emotion/react").SerializedStyles;
21
+ export declare const progressFill: (theme: Theme) => import("@emotion/react").SerializedStyles;
22
+ export declare const deleteButton: (theme: Theme) => import("@emotion/react").SerializedStyles;
@@ -0,0 +1,24 @@
1
+ import { Interpolation, Theme } from '@emotion/react';
2
+ import { IconProps } from '../Icon/types';
3
+ export interface FileAttachmentFile {
4
+ name: string;
5
+ size: number;
6
+ /** Local file/blob not yet uploaded — used to render an image preview via an object URL. Ignored for non-image file names. */
7
+ content?: File | Blob;
8
+ /** URL of an already-uploaded image, e.g. returned by the backend. Ignored for non-image file names. Takes precedence over `content`. */
9
+ previewUrl?: string;
10
+ }
11
+ export interface FileAttachmentProps {
12
+ file: FileAttachmentFile;
13
+ size?: 'large' | 'small';
14
+ progress?: number;
15
+ progressDisplay?: 'text' | 'bar';
16
+ uploadingText?: string;
17
+ uploadedText?: string;
18
+ showDescription?: boolean;
19
+ icon?: IconProps['name'];
20
+ isDisabled?: boolean;
21
+ onRemove?: () => void;
22
+ className?: string;
23
+ css?: Interpolation<Theme>;
24
+ }
@@ -0,0 +1,6 @@
1
+ import { IconProps } from '../Icon/types';
2
+ export declare const formatBytes: (bytes: number) => string;
3
+ /** Returns the file-type icon for a known extension, or `null` when the design's grey Placeholder look should be used instead. */
4
+ export declare const getFileTypeIcon: (fileName: string) => IconProps["name"] | null;
5
+ /** Gates image-preview rendering strictly on the file name's extension, so a pdf/php/etc. is never rendered via `<img>` even if preview data is (incorrectly) supplied for it. */
6
+ export declare const isImageFile: (fileName: string) => boolean;
@@ -4,7 +4,8 @@ import { FileUploadProps } from './types';
4
4
  *
5
5
  * Supports single and multi-file selection with built-in validation for
6
6
  * file formats and size. In multi-file mode, selected files are listed
7
- * below the input with individual remove controls.
7
+ * below the input with individual remove controls. Single-file mode can opt
8
+ * into the same list treatment via `showFileAttachment`.
8
9
  *
9
10
  * @example
10
11
  * ```tsx
@@ -32,6 +33,36 @@ import { FileUploadProps } from './types';
32
33
  * onChange={setFiles}
33
34
  * />
34
35
  * ```
36
+ *
37
+ * @example
38
+ * ```tsx
39
+ * // Multi-file with per-file upload progress, driven by the consumer's own
40
+ * // upload requests — FileUpload only handles local selection, so it has no
41
+ * // progress data of its own.
42
+ * <FileUpload
43
+ * isMultiFile
44
+ * value={files}
45
+ * onChange={setFiles}
46
+ * uploadProgress={[
47
+ * { name: 'report.pdf', progress: 50 },
48
+ * { name: 'photo.png', progress: 100 },
49
+ * ]}
50
+ * />
51
+ * ```
52
+ *
53
+ * @example
54
+ * ```tsx
55
+ * // Single file, shown as a FileAttachment card below the input (icon,
56
+ * // size, delete button, image preview) instead of inline text next to the
57
+ * // button. `uploadProgress` here can just be a single number, since there's
58
+ * // only ever one file.
59
+ * <FileUpload
60
+ * showFileAttachment
61
+ * value={file}
62
+ * onChange={(files) => setFile(files[0])}
63
+ * uploadProgress={70}
64
+ * />
65
+ * ```
35
66
  */
36
- declare const FileUpload: ({ label, placeholder, helperText, actionText, error, disabled, css, className, allowedFormats, maxFileSize, isMultiFile, maxFiles, withDropArea, uploadedSectionTitle, value, onChange, onFileRejected, }: FileUploadProps) => import("@emotion/react/jsx-runtime").JSX.Element;
67
+ declare const FileUpload: ({ label, placeholder, helperText, actionText, error, disabled, css, className, allowedFormats, maxFileSize, isMultiFile, maxFiles, withDropArea, uploadedSectionTitle, uploadProgress, showFileAttachment, value, onChange, onFileRejected, }: FileUploadProps) => import("@emotion/react/jsx-runtime").JSX.Element;
37
68
  export default FileUpload;
@@ -1,3 +1,2 @@
1
1
  export { default } from './FileUpload';
2
- export { default as FileUploadItem } from './FileUploadItem';
3
- export type { FileUploadProps, FileRejectionReason } from './types';
2
+ export type { FileUploadProps, FileRejectionReason, FileUploadProgress, FileUploadProgressEntry, } from './types';
@@ -16,9 +16,3 @@ export declare const dropAreaAction: (theme: Theme) => import("@emotion/react").
16
16
  export declare const dropAreaClearButton: (theme: Theme) => import("@emotion/react").SerializedStyles;
17
17
  export declare const filesList: import("@emotion/react").SerializedStyles;
18
18
  export declare const filesListTitle: (theme: Theme) => import("@emotion/react").SerializedStyles;
19
- export declare const fileItem: (theme: Theme) => import("@emotion/react").SerializedStyles;
20
- export declare const fileIconWrapper: import("@emotion/react").SerializedStyles;
21
- export declare const fileInfo: import("@emotion/react").SerializedStyles;
22
- export declare const fileName: (theme: Theme) => import("@emotion/react").SerializedStyles;
23
- export declare const fileSize: (theme: Theme) => import("@emotion/react").SerializedStyles;
24
- export declare const deleteButton: (theme: Theme) => import("@emotion/react").SerializedStyles;
@@ -1,5 +1,11 @@
1
1
  import { Interpolation, Theme } from '@emotion/react';
2
2
  export type FileRejectionReason = 'size' | 'format';
3
+ export interface FileUploadProgressEntry {
4
+ name: string;
5
+ progress: number;
6
+ }
7
+ /** A single percentage applies to every listed file uniformly; a list matches per-file by `name` — files with no matching entry show no progress. */
8
+ export type FileUploadProgress = number | FileUploadProgressEntry[];
3
9
  export interface FileUploadProps {
4
10
  label?: string;
5
11
  placeholder?: string;
@@ -14,6 +20,10 @@ export interface FileUploadProps {
14
20
  maxFiles?: number;
15
21
  withDropArea?: boolean;
16
22
  uploadedSectionTitle?: string;
23
+ /** Upload progress for files in the multi-file list (`isMultiFile`). FileUpload only handles local selection, not the network upload itself — pass this in as the consumer's own upload reports progress. Files with no corresponding progress show just their size. */
24
+ uploadProgress?: FileUploadProgress;
25
+ /** Single-file mode only (`!isMultiFile`, ignored when `withDropArea` is set — its own selected-file view already covers this): show the selected file as a `FileAttachment` card below the input, instead of inline text next to the button. The input row then always shows `placeholder`, matching how multi-file mode behaves. */
26
+ showFileAttachment?: boolean;
17
27
  className?: string;
18
28
  value?: File | File[];
19
29
  onChange?: (files: File[]) => void;
@@ -2,6 +2,7 @@ export { default as Button } from './Button';
2
2
  export type * from './Button/types';
3
3
  export * from './ButtonGroup';
4
4
  export * from './IconButton';
5
+ export * from './Breadcrumbs';
5
6
  export { default as Checkbox } from './Checkbox';
6
7
  export * from './Checkbox';
7
8
  export type * from './Checkbox/types';
@@ -41,8 +42,9 @@ export * from './ColorPicker';
41
42
  export * from './SearchBox';
42
43
  export type * from './SearchBox/types';
43
44
  export { default as FileUpload } from './FileUpload';
44
- export { FileUploadItem } from './FileUpload';
45
45
  export type * from './FileUpload/types';
46
+ export { default as FileAttachment } from './FileAttachment';
47
+ export type * from './FileAttachment/types';
46
48
  export * from './Field';
47
49
  export { default as Form } from './Form';
48
50
  export { default as FormAction } from './FormAction';