@ssa-ui-kit/core 3.25.0 → 3.26.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/ai/source-map.md +76 -23
- package/dist/components/Breadcrumbs/styles.d.ts +1 -1
- package/dist/components/Chip/helpers.d.ts +2 -2
- package/dist/components/Chip/types.d.ts +10 -3
- package/dist/components/ContextMenu/ContextMenu.d.ts +74 -0
- package/dist/components/ContextMenu/ContextMenuOption.d.ts +18 -0
- package/dist/components/ContextMenu/index.d.ts +3 -0
- package/dist/components/ContextMenu/styles.d.ts +17 -0
- package/dist/components/ContextMenu/types.d.ts +153 -0
- package/dist/components/ContextMenu/utils.d.ts +79 -0
- package/dist/components/Dropdown/Dropdown.d.ts +1 -1
- package/dist/components/Dropdown/types.d.ts +14 -0
- package/dist/components/DropdownOptions/DropdownOptions.d.ts +5 -5
- package/dist/components/DropdownOptions/useToggleListKeys.d.ts +33 -0
- package/dist/components/DropdownOptions/utils.d.ts +9 -0
- package/dist/components/FiltersMultiSelect/FiltersMultiSelectProvider.d.ts +9 -0
- package/dist/components/FiltersMultiSelect/components/FiltersMultiSelectOption.d.ts +31 -1
- package/dist/components/FiltersMultiSelect/components/FiltersMultiSelectOptions.d.ts +29 -2
- package/dist/components/FiltersMultiSelect/utils.d.ts +15 -0
- package/dist/components/Footer/Footer.d.ts +42 -0
- package/dist/components/Footer/index.d.ts +1 -0
- package/dist/components/Footer/styles.d.ts +53 -0
- package/dist/components/Footer/types.d.ts +110 -0
- package/dist/components/Header/Header.d.ts +4 -4
- package/dist/components/Header/HeaderMobileMenu.d.ts +4 -3
- package/dist/components/Header/styles.d.ts +15 -4
- package/dist/components/Label/Label.d.ts +11 -1
- package/dist/components/Label/index.d.ts +1 -0
- package/dist/components/Label/types.d.ts +36 -1
- package/dist/components/MultipleDropdown/MultipleDropdown.d.ts +4 -1
- package/dist/components/MultipleDropdown/types.d.ts +8 -0
- package/dist/components/MultipleDropdownOptions/MultipleDropdownOptions.d.ts +27 -0
- package/dist/components/Table/ColumnFreezeMenu.d.ts +2 -0
- package/dist/components/TextField/TextField.d.ts +1 -1
- package/dist/components/TextField/types.d.ts +7 -0
- package/dist/components/Textarea/types.d.ts +4 -0
- package/dist/components/Typeahead/Typeahead.context.d.ts +10 -1
- package/dist/components/Typeahead/Typeahead.d.ts +1 -1
- package/dist/components/Typeahead/components/TypeaheadOptions.d.ts +13 -1
- package/dist/components/Typeahead/styles.d.ts +5 -0
- package/dist/components/Typeahead/types.d.ts +14 -1
- package/dist/components/Typeahead/useTypeahead.d.ts +12 -2
- package/dist/components/index.d.ts +5 -0
- package/dist/index.js +3593 -2167
- package/dist/index.mjs +3588 -2168
- package/dist/tsbuildcache +1 -1
- package/package.json +3 -3
|
@@ -4,6 +4,7 @@ import { Interpolation, Theme } from '@emotion/react';
|
|
|
4
4
|
import { DropdownOptionProps } from '../DropdownOptions';
|
|
5
5
|
import { CommonProps } from '../../types/emotion';
|
|
6
6
|
import { IconProps } from '../Icon/types';
|
|
7
|
+
import { LabelBadge } from '../Label/types';
|
|
7
8
|
export declare enum DropdownPositions {
|
|
8
9
|
top = "top",
|
|
9
10
|
bottom = "bottom",
|
|
@@ -108,6 +109,12 @@ export interface DropdownProps<P extends DropdownOptionProps> extends CommonProp
|
|
|
108
109
|
* Label text displayed above the dropdown
|
|
109
110
|
*/
|
|
110
111
|
label?: string;
|
|
112
|
+
/**
|
|
113
|
+
* Status badge to the right of the label, e.g.
|
|
114
|
+
* `{ text: 'default', color: 'grey' }`. Announced as the toggle's
|
|
115
|
+
* description. Needs a `label`.
|
|
116
|
+
*/
|
|
117
|
+
labelBadge?: LabelBadge;
|
|
111
118
|
/**
|
|
112
119
|
* Helper text displayed below the dropdown
|
|
113
120
|
* Shown when no errors are present
|
|
@@ -232,4 +239,11 @@ export interface DropdownContextType {
|
|
|
232
239
|
* Computed by Dropdown based on dropdownPosition prop and available viewport space
|
|
233
240
|
*/
|
|
234
241
|
placement?: 'top' | 'bottom';
|
|
242
|
+
/**
|
|
243
|
+
* Option highlighted by the keyboard or the pointer. Focus stays on the
|
|
244
|
+
* toggle, so the list is driven from there.
|
|
245
|
+
*/
|
|
246
|
+
activeValue?: string | number | null;
|
|
247
|
+
/** Moves the highlight; called by the list on pointer moves. */
|
|
248
|
+
setActiveValue?: (value: string | number | null) => void;
|
|
235
249
|
}
|
|
@@ -2,8 +2,9 @@ import { DropdownItemsListProps } from './types';
|
|
|
2
2
|
/**
|
|
3
3
|
* DropdownOptions - Options menu container for Dropdown component
|
|
4
4
|
*
|
|
5
|
-
* Renders the
|
|
6
|
-
*
|
|
5
|
+
* Renders the `DropdownOption` children as a `ContextMenu` placed under (or
|
|
6
|
+
* above) the Dropdown toggle. Focus stays on the toggle; the highlighted
|
|
7
|
+
* option is driven from there and announced through `aria-activedescendant`.
|
|
7
8
|
*
|
|
8
9
|
* Placement (opening upward or downward) is driven entirely by the parent
|
|
9
10
|
* Dropdown via context — this component does not calculate position itself.
|
|
@@ -31,9 +32,8 @@ import { DropdownItemsListProps } from './types';
|
|
|
31
32
|
* @see {@link DropdownOption} - Individual option components
|
|
32
33
|
*
|
|
33
34
|
* @accessibility
|
|
34
|
-
* - Uses role="listbox"
|
|
35
|
-
* -
|
|
36
|
-
* - Screen reader friendly
|
|
35
|
+
* - Uses role="listbox" with role="option" rows
|
|
36
|
+
* - Arrow keys, Home, End, Enter, Space and Escape on the toggle
|
|
37
37
|
*/
|
|
38
38
|
declare const DropdownOptions: ({ "aria-labelledby": ariaLabelledbyNative, ariaLabelledby, id, children, }: DropdownItemsListProps) => import("@emotion/react/jsx-runtime").JSX.Element;
|
|
39
39
|
export default DropdownOptions;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { KeyboardEvent } from 'react';
|
|
2
|
+
import { ContextMenuItem } from '../ContextMenu';
|
|
3
|
+
import { OptionValue } from './utils';
|
|
4
|
+
/** Options of {@link useToggleListKeys}. */
|
|
5
|
+
export interface UseToggleListKeysOptions {
|
|
6
|
+
/** Id of the ContextMenu the toggle controls. */
|
|
7
|
+
listId: string;
|
|
8
|
+
isOpen: boolean;
|
|
9
|
+
disabled?: boolean;
|
|
10
|
+
menuItems: ContextMenuItem<OptionValue>[];
|
|
11
|
+
/** Highlighted option. */
|
|
12
|
+
activeValue: OptionValue | null;
|
|
13
|
+
setActiveValue: (value: OptionValue | null) => void;
|
|
14
|
+
/** Opens the list; `key` is the arrow that opened it. */
|
|
15
|
+
open: (key: string) => void;
|
|
16
|
+
close: () => void;
|
|
17
|
+
/** Enter or Space on the highlighted option. */
|
|
18
|
+
onPick: (value: OptionValue) => void;
|
|
19
|
+
/** Consumer handlers, run first; `preventDefault()` skips the built-in keys. */
|
|
20
|
+
onKeyDown?: (event: KeyboardEvent<HTMLButtonElement>) => void;
|
|
21
|
+
onKeyUp?: (event: KeyboardEvent<HTMLButtonElement>) => void;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Keyboard for a dropdown toggle that keeps focus while it drives its list:
|
|
25
|
+
* arrows open it, then Arrow/Home/End move the highlight, Enter/Space pick,
|
|
26
|
+
* Escape/Tab close. Returns the toggle's handlers and its
|
|
27
|
+
* `aria-activedescendant`.
|
|
28
|
+
*/
|
|
29
|
+
export declare const useToggleListKeys: ({ listId, isOpen, disabled, menuItems, activeValue, setActiveValue, open, close, onPick, onKeyDown, onKeyUp, }: UseToggleListKeysOptions) => {
|
|
30
|
+
onKeyDown: (event: KeyboardEvent<HTMLButtonElement>) => void;
|
|
31
|
+
onKeyUp: (event: KeyboardEvent<HTMLButtonElement>) => void;
|
|
32
|
+
'aria-activedescendant': string | undefined;
|
|
33
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { ContextMenuItem } from '../ContextMenu';
|
|
3
|
+
/** Value of a Dropdown option as the list sees it. */
|
|
4
|
+
export type OptionValue = string | number;
|
|
5
|
+
/**
|
|
6
|
+
* Reads `DropdownOption` children into ContextMenu items. The label resolves
|
|
7
|
+
* as `children` → `label` → `value`, as it always has.
|
|
8
|
+
*/
|
|
9
|
+
export declare const toDropdownMenuItems: (children: React.ReactNode) => ContextMenuItem<OptionValue>[];
|
|
@@ -1,7 +1,16 @@
|
|
|
1
|
+
import { MutableRefObject } from 'react';
|
|
1
2
|
import { UseFiltersMultiSelectStore } from './useFiltersMultiSelect';
|
|
3
|
+
import type { FilterMenuItem } from './utils';
|
|
2
4
|
export interface FiltersMultiSelectContextValue {
|
|
3
5
|
store: UseFiltersMultiSelectStore;
|
|
4
6
|
emptyNode?: React.ReactNode;
|
|
7
|
+
/** Id of the options list, referenced by the search input. */
|
|
8
|
+
listId?: string;
|
|
9
|
+
/** Highlighted option, driven from the search input and the pointer. */
|
|
10
|
+
activeValue?: string | null;
|
|
11
|
+
setActiveValue?: (value: string | null) => void;
|
|
12
|
+
/** The rendered options, kept here for the search input's keyboard. */
|
|
13
|
+
itemsRef?: MutableRefObject<FilterMenuItem[]>;
|
|
5
14
|
}
|
|
6
15
|
export declare const FiltersMultiSelectProvider: ({ children, value, }: {
|
|
7
16
|
value: FiltersMultiSelectContextValue;
|
|
@@ -1,7 +1,37 @@
|
|
|
1
1
|
import { Filter } from '../useFiltersMultiSelect';
|
|
2
2
|
export interface FiltersMultiSelectOptionProps {
|
|
3
|
+
/** The filter this row adds. `group: true` makes it a select-only row. */
|
|
3
4
|
filter: Filter;
|
|
5
|
+
/** Row content. */
|
|
4
6
|
children: React.ReactNode;
|
|
7
|
+
/**
|
|
8
|
+
* @deprecated Ignored — the row's state comes from the store's selected
|
|
9
|
+
* filters. Removed in the next major release.
|
|
10
|
+
*/
|
|
5
11
|
selected?: boolean;
|
|
6
12
|
}
|
|
7
|
-
|
|
13
|
+
/**
|
|
14
|
+
* FiltersMultiSelectOption - One filter row of a `FiltersMultiSelect`.
|
|
15
|
+
*
|
|
16
|
+
* Declarative: `FiltersMultiSelectOptions` reads its props and renders the
|
|
17
|
+
* row, so it renders nothing on its own. Regular filters get + (include) and
|
|
18
|
+
* − (exclude) controls; `group` filters get a single check-circle.
|
|
19
|
+
*
|
|
20
|
+
* @category Form Controls
|
|
21
|
+
* @subcategory Selection
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```tsx
|
|
25
|
+
* <FiltersMultiSelectOptions>
|
|
26
|
+
* <FiltersMultiSelectOption filter={{ id: '1', label: 'Active' }}>
|
|
27
|
+
* Active
|
|
28
|
+
* </FiltersMultiSelectOption>
|
|
29
|
+
* <FiltersMultiSelectOption filter={{ id: 'g', label: 'Saved', group: true }}>
|
|
30
|
+
* Saved
|
|
31
|
+
* </FiltersMultiSelectOption>
|
|
32
|
+
* </FiltersMultiSelectOptions>
|
|
33
|
+
* ```
|
|
34
|
+
*
|
|
35
|
+
* @see {@link FiltersMultiSelectOptions} - The list that renders it
|
|
36
|
+
*/
|
|
37
|
+
export declare const FiltersMultiSelectOption: (_props: FiltersMultiSelectOptionProps) => null;
|
|
@@ -1,4 +1,31 @@
|
|
|
1
1
|
import React, { type HTMLAttributes } from 'react';
|
|
2
|
-
|
|
2
|
+
/**
|
|
3
|
+
* FiltersMultiSelectOptions - The options list of a `FiltersMultiSelect`.
|
|
4
|
+
*
|
|
5
|
+
* Renders its `FiltersMultiSelectOption` children as an include / exclude
|
|
6
|
+
* `ContextMenu`: + and − on each row (one check-circle on group rows), Enter
|
|
7
|
+
* in the search input cycles the highlighted row. Shows the
|
|
8
|
+
* `FiltersMultiSelect` `emptyNode` when it has no options.
|
|
9
|
+
*
|
|
10
|
+
* @category Form Controls
|
|
11
|
+
* @subcategory Selection
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```tsx
|
|
15
|
+
* <FiltersMultiSelect store={store}>
|
|
16
|
+
* <FiltersMultiSelectOptions>
|
|
17
|
+
* {filters.map((filter) => (
|
|
18
|
+
* <FiltersMultiSelectOption key={filter.id} filter={filter}>
|
|
19
|
+
* {filter.label}
|
|
20
|
+
* </FiltersMultiSelectOption>
|
|
21
|
+
* ))}
|
|
22
|
+
* </FiltersMultiSelectOptions>
|
|
23
|
+
* </FiltersMultiSelect>
|
|
24
|
+
* ```
|
|
25
|
+
*
|
|
26
|
+
* @see {@link FiltersMultiSelect} - Parent component
|
|
27
|
+
* @see {@link FiltersMultiSelectOption} - One filter row
|
|
28
|
+
*/
|
|
29
|
+
export declare const FiltersMultiSelectOptions: ({ children, onMouseDown, ...props }: {
|
|
3
30
|
children: React.ReactNode;
|
|
4
|
-
} & HTMLAttributes<
|
|
31
|
+
} & Omit<HTMLAttributes<HTMLUListElement>, "onChange" | "defaultValue" | "children">) => import("@emotion/react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { ContextMenuIncludeExcludeEntry, ContextMenuIncludeExcludeType, ContextMenuItem } from '../ContextMenu';
|
|
3
|
+
import { Filter, SelectedFilter, UseFiltersMultiSelectStore } from './useFiltersMultiSelect';
|
|
4
|
+
/** A ContextMenu row together with the filter it stands for. */
|
|
5
|
+
export type FilterMenuItem = ContextMenuItem<string> & {
|
|
6
|
+
filter: Filter;
|
|
7
|
+
};
|
|
8
|
+
/** Reads `FiltersMultiSelectOption` children into ContextMenu items. */
|
|
9
|
+
export declare const toFilterMenuItems: (children: React.ReactNode) => FilterMenuItem[];
|
|
10
|
+
/** The store's selection in ContextMenu's `includeExclude` shape. */
|
|
11
|
+
export declare const toMenuSelection: (selectedFilters: SelectedFilter[]) => ContextMenuIncludeExcludeEntry<string>[];
|
|
12
|
+
/** The store's current type for a filter, in ContextMenu's terms. */
|
|
13
|
+
export declare const getMenuType: (store: UseFiltersMultiSelectStore, id: string) => ContextMenuIncludeExcludeType | undefined;
|
|
14
|
+
/** Selects `filter` as `type`, or unselects it when `type` is undefined. */
|
|
15
|
+
export declare const setFilterType: (store: UseFiltersMultiSelectStore, { id, label }: Filter, type: ContextMenuIncludeExcludeType | undefined) => void;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { FooterProps } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Footer - The page's bottom bar: a copyright line and legal links, and
|
|
4
|
+
* optionally a logo, a short description and navigation columns above them.
|
|
5
|
+
*
|
|
6
|
+
* ### Default and extended
|
|
7
|
+
* With only `copyright` and `links` the Footer is a single bar in one of
|
|
8
|
+
* three sizes. Passing `logo`, `description` or `columns` makes it extended:
|
|
9
|
+
* the brand block and columns sit above the same bar. The design has the
|
|
10
|
+
* extended footer in medium only, so it ignores `size`.
|
|
11
|
+
*
|
|
12
|
+
* ### Links
|
|
13
|
+
* A link with a `path` renders as a react-router link, so the Footer must
|
|
14
|
+
* then sit inside a router; a link with an `href` renders as a plain anchor.
|
|
15
|
+
* Each column is its own navigation landmark, named by its title.
|
|
16
|
+
*
|
|
17
|
+
* ### Layout
|
|
18
|
+
* The layout follows the Footer's own width, not the window's. Below 900px
|
|
19
|
+
* the bottom bar stacks the copyright over the links, and the extended
|
|
20
|
+
* footer puts the brand block above its columns, two per row.
|
|
21
|
+
*
|
|
22
|
+
* @category Navigation
|
|
23
|
+
* @example
|
|
24
|
+
* ```tsx
|
|
25
|
+
* <Footer
|
|
26
|
+
* copyright="Acme © 2007-2026. All rights reserved."
|
|
27
|
+
* links={[
|
|
28
|
+
* { id: 'privacy', label: 'Privacy Policy', path: '/privacy' },
|
|
29
|
+
* { id: 'terms', label: 'Terms & Conditions', path: '/terms' },
|
|
30
|
+
* ]}
|
|
31
|
+
* logo={<img src="/logo.svg" alt="Acme" height={64} />}
|
|
32
|
+
* columns={[
|
|
33
|
+
* {
|
|
34
|
+
* id: 'company',
|
|
35
|
+
* title: 'Company',
|
|
36
|
+
* links: [{ id: 'about', label: 'About us', path: '/about' }],
|
|
37
|
+
* },
|
|
38
|
+
* ]}
|
|
39
|
+
* />
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
export declare const Footer: import("react").ForwardRefExoticComponent<FooterProps & import("react").RefAttributes<HTMLElement>>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './Footer';
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { Theme } from '@emotion/react';
|
|
2
|
+
import { FooterSize, FooterTheme } from './types';
|
|
3
|
+
export declare const TYPOGRAPHY: Record<FooterSize, {
|
|
4
|
+
fontSize: number;
|
|
5
|
+
lineHeight: number;
|
|
6
|
+
fontWeight: number;
|
|
7
|
+
}>;
|
|
8
|
+
/** From this footer width up the design layout; below it, everything stacks. */
|
|
9
|
+
export declare const DESKTOP_MIN_WIDTH = 900;
|
|
10
|
+
export declare const resolvePalette: (theme: Theme, footerTheme: FooterTheme) => {
|
|
11
|
+
background: string;
|
|
12
|
+
text: `rgb${string}` | undefined;
|
|
13
|
+
accent: `rgb${string}` | undefined;
|
|
14
|
+
} | {
|
|
15
|
+
background: `rgb${string}` | "transparent";
|
|
16
|
+
text: `rgb${string}` | undefined;
|
|
17
|
+
accent: `rgb${string}` | "transparent";
|
|
18
|
+
};
|
|
19
|
+
export type FooterPalette = ReturnType<typeof resolvePalette>;
|
|
20
|
+
/**
|
|
21
|
+
* The query container. It is the footer itself, so consumer styles land on
|
|
22
|
+
* the outermost element; the padding the query switches lives on the inner
|
|
23
|
+
* wrapper, as a container cannot query its own width. The kit's global reset
|
|
24
|
+
* gives every element its own color, hence the explicit inherit inside.
|
|
25
|
+
*/
|
|
26
|
+
export declare const container: (palette: FooterPalette) => import("@emotion/react").SerializedStyles;
|
|
27
|
+
export declare const inner: import("@emotion/react").SerializedStyles;
|
|
28
|
+
/**
|
|
29
|
+
* Design: 24px above the content, 40px between it and the bottom bar. The
|
|
30
|
+
* container already pads 12px, so this adds the other 12px on top.
|
|
31
|
+
*/
|
|
32
|
+
export declare const extended: import("@emotion/react").SerializedStyles;
|
|
33
|
+
export declare const content: import("@emotion/react").SerializedStyles;
|
|
34
|
+
export declare const brand: import("@emotion/react").SerializedStyles;
|
|
35
|
+
/**
|
|
36
|
+
* Fixed height, as in the design's placeholder; width follows the logo so
|
|
37
|
+
* wordmarks fit.
|
|
38
|
+
*/
|
|
39
|
+
export declare const logo: import("@emotion/react").SerializedStyles;
|
|
40
|
+
export declare const description: import("@emotion/react").SerializedStyles;
|
|
41
|
+
/**
|
|
42
|
+
* Two columns side by side on phones. On desktop the design's 160px gaps,
|
|
43
|
+
* shrinking with the footer so a fourth column still fits.
|
|
44
|
+
*/
|
|
45
|
+
export declare const columns: import("@emotion/react").SerializedStyles;
|
|
46
|
+
export declare const column: import("@emotion/react").SerializedStyles;
|
|
47
|
+
export declare const columnTitle: import("@emotion/react").SerializedStyles;
|
|
48
|
+
export declare const linkList: import("@emotion/react").SerializedStyles;
|
|
49
|
+
/** Stacked on phones; copyright left and links right from 900px. */
|
|
50
|
+
export declare const bottomBar: (size: FooterSize) => import("@emotion/react").SerializedStyles;
|
|
51
|
+
export declare const copyright: import("@emotion/react").SerializedStyles;
|
|
52
|
+
export declare const legalList: import("@emotion/react").SerializedStyles;
|
|
53
|
+
export declare const link: (theme: Theme, palette: FooterPalette) => import("@emotion/react").SerializedStyles;
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { HTMLAttributes, ReactNode } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Footer size: the text size of the bottom bar — 14px, 16px or 20px — and so
|
|
4
|
+
* its height, 42px, 48px or 52px. The extended footer is always medium.
|
|
5
|
+
*/
|
|
6
|
+
export type FooterSize = 'small' | 'medium' | 'large';
|
|
7
|
+
/**
|
|
8
|
+
* Footer color scheme: the light grey bar, or the dark graphite gradient the
|
|
9
|
+
* Header uses.
|
|
10
|
+
*/
|
|
11
|
+
export type FooterTheme = 'light' | 'dark';
|
|
12
|
+
/**
|
|
13
|
+
* One link of the Footer — a legal link in the bottom bar, or a line of a
|
|
14
|
+
* navigation column.
|
|
15
|
+
*
|
|
16
|
+
* Give it a `path` to render a react-router link (the Footer must then sit
|
|
17
|
+
* inside a router), or an `href` for a plain anchor — a page on another site,
|
|
18
|
+
* a `mailto:`. With neither it renders as plain text.
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```tsx
|
|
22
|
+
* const links: FooterLink[] = [
|
|
23
|
+
* { id: 'privacy', label: 'Privacy Policy', path: '/privacy' },
|
|
24
|
+
* { id: 'terms', label: 'Terms & Conditions', href: 'https://example.com/terms' },
|
|
25
|
+
* ];
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
export interface FooterLink {
|
|
29
|
+
/** Unique key of the link within its list */
|
|
30
|
+
id: string;
|
|
31
|
+
/** Visible label */
|
|
32
|
+
label: ReactNode;
|
|
33
|
+
/** In-app route, rendered as a react-router link. Wins over `href`. */
|
|
34
|
+
path?: string;
|
|
35
|
+
/** Address of a plain anchor, for links outside the app */
|
|
36
|
+
href?: string;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* A navigation column of the extended Footer: a bold title over a list of
|
|
40
|
+
* links.
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* ```tsx
|
|
44
|
+
* const column: FooterColumn = {
|
|
45
|
+
* id: 'company',
|
|
46
|
+
* title: 'Company',
|
|
47
|
+
* links: [
|
|
48
|
+
* { id: 'about', label: 'About us', path: '/about' },
|
|
49
|
+
* { id: 'careers', label: 'Careers', path: '/careers' },
|
|
50
|
+
* ],
|
|
51
|
+
* };
|
|
52
|
+
* ```
|
|
53
|
+
*/
|
|
54
|
+
export interface FooterColumn {
|
|
55
|
+
/** Unique key of the column */
|
|
56
|
+
id: string;
|
|
57
|
+
/** Column title; also names the column's navigation landmark */
|
|
58
|
+
title: ReactNode;
|
|
59
|
+
/** Links listed under the title */
|
|
60
|
+
links: FooterLink[];
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Props for the Footer component.
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* ```tsx
|
|
67
|
+
* <Footer
|
|
68
|
+
* copyright="Acme © 2007-2026. All rights reserved."
|
|
69
|
+
* links={[{ id: 'privacy', label: 'Privacy Policy', path: '/privacy' }]}
|
|
70
|
+
* />
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
73
|
+
export interface FooterProps extends Omit<HTMLAttributes<HTMLElement>, 'children'> {
|
|
74
|
+
/** Copyright line, on the left of the bottom bar */
|
|
75
|
+
copyright?: ReactNode;
|
|
76
|
+
/** Legal links — privacy policy, terms — on the right of the bottom bar */
|
|
77
|
+
links?: FooterLink[];
|
|
78
|
+
/**
|
|
79
|
+
* Project logo, at the top left of the extended footer, in a 64px high box.
|
|
80
|
+
* Passing it makes the footer extended.
|
|
81
|
+
*/
|
|
82
|
+
logo?: ReactNode;
|
|
83
|
+
/**
|
|
84
|
+
* Short text under the logo — a tagline, the company name. Passing it makes
|
|
85
|
+
* the footer extended.
|
|
86
|
+
*/
|
|
87
|
+
description?: ReactNode;
|
|
88
|
+
/**
|
|
89
|
+
* Navigation columns on the right of the extended footer. Passing any makes
|
|
90
|
+
* the footer extended.
|
|
91
|
+
*/
|
|
92
|
+
columns?: FooterColumn[];
|
|
93
|
+
/**
|
|
94
|
+
* Color scheme. Named after the kit's other light/dark components (Header,
|
|
95
|
+
* TreeView) — not the Emotion theme.
|
|
96
|
+
* @default 'light'
|
|
97
|
+
*/
|
|
98
|
+
theme?: FooterTheme;
|
|
99
|
+
/**
|
|
100
|
+
* Text size and height of the bottom bar. Ignored by the extended footer,
|
|
101
|
+
* which the design only has in medium.
|
|
102
|
+
* @default 'small'
|
|
103
|
+
*/
|
|
104
|
+
size?: FooterSize;
|
|
105
|
+
/**
|
|
106
|
+
* Accessible name of the legal links' navigation landmark
|
|
107
|
+
* @default 'Legal'
|
|
108
|
+
*/
|
|
109
|
+
linksLabel?: string;
|
|
110
|
+
}
|
|
@@ -11,10 +11,10 @@ import { HeaderProps } from './types';
|
|
|
11
11
|
* further. Following a link closes them.
|
|
12
12
|
*
|
|
13
13
|
* ### Layout
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* stays as it is.
|
|
14
|
+
* The layout follows the Header's own width, not the window's. From 900px
|
|
15
|
+
* the navigation is centred between the logo and the right side, and scrolls
|
|
16
|
+
* sideways when it does not fit. Below 900px it moves into a drawer opened
|
|
17
|
+
* by a burger button, the logo is centred and `rightSide` stays as it is.
|
|
18
18
|
*
|
|
19
19
|
* ### Selected state
|
|
20
20
|
* The design sets the selected item in bold. The kit marks it by color
|
|
@@ -10,9 +10,10 @@ interface HeaderMobileMenuProps {
|
|
|
10
10
|
navLabel: string;
|
|
11
11
|
}
|
|
12
12
|
/**
|
|
13
|
-
* The navigation below 900px: a
|
|
14
|
-
* same engine as CollapsibleNavBar's menu. The tree owns
|
|
15
|
-
* the group holding the current page; this module owns
|
|
13
|
+
* The navigation below 900px: a 400px drawer (full width on phones) holding
|
|
14
|
+
* a `TreeView`, the same engine as CollapsibleNavBar's menu. The tree owns
|
|
15
|
+
* expansion and opens the group holding the current page; this module owns
|
|
16
|
+
* the routing.
|
|
16
17
|
*/
|
|
17
18
|
export declare const HeaderMobileMenu: ({ store, items, headerTheme, palette, pathname, navLabel, }: HeaderMobileMenuProps) => import("@emotion/react/jsx-runtime").JSX.Element;
|
|
18
19
|
export {};
|
|
@@ -5,6 +5,8 @@ export declare const SIZES: Record<HeaderSize, {
|
|
|
5
5
|
logo: number;
|
|
6
6
|
}>;
|
|
7
7
|
export declare const MENU_WIDTH = 164;
|
|
8
|
+
/** From this header width up the bar shows the nav; below it, the burger. */
|
|
9
|
+
export declare const DESKTOP_MIN_WIDTH = 900;
|
|
8
10
|
/** Design: dropdowns sit 6px below their trigger and flyouts 6px aside. */
|
|
9
11
|
export declare const MENU_OFFSET = 6;
|
|
10
12
|
export declare const resolvePalette: (theme: Theme, headerTheme: HeaderTheme) => {
|
|
@@ -33,10 +35,16 @@ export declare const resolvePalette: (theme: Theme, headerTheme: HeaderTheme) =>
|
|
|
33
35
|
drawerBackground: `rgb${string}` | "transparent";
|
|
34
36
|
};
|
|
35
37
|
export type HeaderPalette = ReturnType<typeof resolvePalette>;
|
|
36
|
-
|
|
38
|
+
/**
|
|
39
|
+
* The query container. It is the `header` itself, so consumer styles such
|
|
40
|
+
* as `position: sticky` land on the outermost element; the layout that
|
|
41
|
+
* the query switches lives on the bar inside.
|
|
42
|
+
*/
|
|
43
|
+
export declare const container: (palette: HeaderPalette) => import("@emotion/react").SerializedStyles;
|
|
44
|
+
export declare const bar: (size: HeaderSize) => import("@emotion/react").SerializedStyles;
|
|
37
45
|
export declare const burger: (theme: Theme, palette: HeaderPalette) => import("@emotion/react").SerializedStyles;
|
|
38
46
|
/** Holds the burger's column when there is no menu, so the logo stays centred. */
|
|
39
|
-
export declare const burgerPlaceholder:
|
|
47
|
+
export declare const burgerPlaceholder: import("@emotion/react").SerializedStyles;
|
|
40
48
|
/**
|
|
41
49
|
* Fixed height from the size; width follows the logo so wordmarks fit, but
|
|
42
50
|
* never drops below a square, so an empty box still holds its place.
|
|
@@ -46,7 +54,7 @@ export declare const logo: (size: HeaderSize) => import("@emotion/react").Serial
|
|
|
46
54
|
* The scroll container. Dropdowns are portalled, so the overflow here does
|
|
47
55
|
* not clip them.
|
|
48
56
|
*/
|
|
49
|
-
export declare const nav:
|
|
57
|
+
export declare const nav: import("@emotion/react").SerializedStyles;
|
|
50
58
|
/** `margin: auto` centres the list while it fits and lets it scroll after. */
|
|
51
59
|
export declare const navList: import("@emotion/react").SerializedStyles;
|
|
52
60
|
export declare const rightSide: import("@emotion/react").SerializedStyles;
|
|
@@ -59,5 +67,8 @@ export declare const navItem: (theme: Theme, palette: HeaderPalette, active: boo
|
|
|
59
67
|
export declare const menu: (theme: Theme, palette: HeaderPalette) => import("@emotion/react").SerializedStyles;
|
|
60
68
|
export declare const menuItem: (theme: Theme, palette: HeaderPalette, active: boolean) => import("@emotion/react").SerializedStyles;
|
|
61
69
|
export declare const drawerContent: (palette: HeaderPalette) => import("@emotion/react").SerializedStyles;
|
|
62
|
-
/**
|
|
70
|
+
/**
|
|
71
|
+
* Chevron of a mobile group row; flips while the group is open. Pushed to the
|
|
72
|
+
* row's end so every chevron shares one vertical line.
|
|
73
|
+
*/
|
|
63
74
|
export declare const mobileToggle: (expanded: boolean) => import("@emotion/react").SerializedStyles;
|
|
@@ -1,3 +1,13 @@
|
|
|
1
1
|
import { LabelProps } from './types';
|
|
2
|
-
|
|
2
|
+
/**
|
|
3
|
+
* Builds the default badge id for a label's `htmlFor`, so a field can point
|
|
4
|
+
* its control's `aria-describedby` at the badge.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```tsx
|
|
8
|
+
* <input id="email" aria-describedby={getLabelBadgeId('email')} />
|
|
9
|
+
* ```
|
|
10
|
+
*/
|
|
11
|
+
export declare const getLabelBadgeId: (htmlFor: string) => string;
|
|
12
|
+
declare const Label: ({ children, htmlFor, id, badge, className, disabled, isDisabled, onMouseEnter, onMouseLeave, }: LabelProps) => import("@emotion/react/jsx-runtime").JSX.Element;
|
|
3
13
|
export default Label;
|
|
@@ -1,8 +1,43 @@
|
|
|
1
|
-
import { MouseEventHandler } from 'react';
|
|
1
|
+
import { MouseEventHandler, ReactNode } from 'react';
|
|
2
2
|
import { CommonProps } from '../../types/emotion';
|
|
3
|
+
import { ChipProps } from '../Chip/types';
|
|
4
|
+
/**
|
|
5
|
+
* A small status pill shown to the right of a field label — "mapped",
|
|
6
|
+
* "default", "not present in the CV". Rendered as an outlined Chip.
|
|
7
|
+
*
|
|
8
|
+
* The badge sits next to the `<label>` element, not inside it, so it does
|
|
9
|
+
* not become part of the field's accessible name. Point the control's
|
|
10
|
+
* `aria-describedby` at its `id` to have it announced as a description —
|
|
11
|
+
* the kit's fields with a `labelBadge` prop do this for you.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```tsx
|
|
15
|
+
* const badge: LabelBadge = { text: 'mapped', color: 'primary' };
|
|
16
|
+
* const custom: LabelBadge = { text: 'not present in the CV', color: '#ff8a00' };
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
export interface LabelBadge {
|
|
20
|
+
/** Badge text */
|
|
21
|
+
text: ReactNode;
|
|
22
|
+
/**
|
|
23
|
+
* A Chip color: `primary`, `success`, `warning`… , any theme color key
|
|
24
|
+
* (e.g. `'purple'`) or a CSS color (e.g. `'#ff8a00'`).
|
|
25
|
+
* @default 'default'
|
|
26
|
+
*/
|
|
27
|
+
color?: ChipProps['color'];
|
|
28
|
+
/**
|
|
29
|
+
* `id` of the badge element, for the control's `aria-describedby`
|
|
30
|
+
* @default `${htmlFor}-badge`, or a generated id without `htmlFor`
|
|
31
|
+
*/
|
|
32
|
+
id?: string;
|
|
33
|
+
}
|
|
3
34
|
export interface LabelProps extends CommonProps {
|
|
4
35
|
htmlFor?: string;
|
|
36
|
+
/** `id` of the `<label>` element, e.g. for a control's `aria-labelledby` */
|
|
37
|
+
id?: string;
|
|
5
38
|
children: React.ReactNode;
|
|
39
|
+
/** Status badge shown to the right of the label text */
|
|
40
|
+
badge?: LabelBadge;
|
|
6
41
|
/** Renders the label in its muted, disabled state. */
|
|
7
42
|
disabled?: boolean;
|
|
8
43
|
/**
|
|
@@ -68,7 +68,10 @@ import { DropdownProps } from './types';
|
|
|
68
68
|
*
|
|
69
69
|
* @accessibility
|
|
70
70
|
* - ARIA attributes set according to WAI-ARIA combobox pattern
|
|
71
|
-
* -
|
|
71
|
+
* - Focus stays on the toggle, which points at the highlighted option with
|
|
72
|
+
* `aria-activedescendant`
|
|
73
|
+
* - Arrow keys, Home and End move the highlight; Enter or Space toggles it
|
|
74
|
+
* (picks and closes in single-select mode); Escape and Tab close
|
|
72
75
|
* - Click outside to close
|
|
73
76
|
* - Screen reader friendly with aria-expanded and aria-controls
|
|
74
77
|
*
|
|
@@ -119,4 +119,12 @@ export interface DropdownContextType<T extends DropdownOptionProps> {
|
|
|
119
119
|
* Max height (px) of the options list
|
|
120
120
|
*/
|
|
121
121
|
maxHeight?: number;
|
|
122
|
+
/**
|
|
123
|
+
* Highlighted option, driven by the toggle's keyboard and the pointer
|
|
124
|
+
*/
|
|
125
|
+
activeValue?: string | number | null;
|
|
126
|
+
/**
|
|
127
|
+
* Updates the highlighted option
|
|
128
|
+
*/
|
|
129
|
+
setActiveValue?: (value: string | number | null) => void;
|
|
122
130
|
}
|
|
@@ -1,3 +1,30 @@
|
|
|
1
1
|
import { DropdownItemsListProps } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* MultipleDropdownOptions - Options menu container for MultipleDropdown
|
|
4
|
+
*
|
|
5
|
+
* Renders the `DropdownOption` children as a `ContextMenu` under the
|
|
6
|
+
* MultipleDropdown toggle: a checkbox per row in multi-select mode, a check
|
|
7
|
+
* mark on the selected row otherwise. Focus stays on the toggle; the
|
|
8
|
+
* highlighted option is driven from there and announced through
|
|
9
|
+
* `aria-activedescendant`.
|
|
10
|
+
*
|
|
11
|
+
* @category Form Controls
|
|
12
|
+
* @subcategory Selection
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```tsx
|
|
16
|
+
* // Rendered by MultipleDropdown from its DropdownOption children
|
|
17
|
+
* <MultipleDropdown label="Fruits" onChange={handleChange}>
|
|
18
|
+
* <DropdownOption value="apple">Apple</DropdownOption>
|
|
19
|
+
* <DropdownOption value="banana">Banana</DropdownOption>
|
|
20
|
+
* </MultipleDropdown>
|
|
21
|
+
* ```
|
|
22
|
+
*
|
|
23
|
+
* @see {@link MultipleDropdown} - Parent component
|
|
24
|
+
*
|
|
25
|
+
* @accessibility
|
|
26
|
+
* - Uses role="listbox" (multi-selectable in multi-select mode) with role="option" rows
|
|
27
|
+
* - Arrow keys, Home, End, Enter, Space and Escape on the toggle
|
|
28
|
+
*/
|
|
2
29
|
declare const MultipleDropdownOptions: ({ "aria-labelledby": ariaLabelledbyNative, ariaLabelledby, id, children, }: DropdownItemsListProps) => import("@emotion/react/jsx-runtime").JSX.Element;
|
|
3
30
|
export default MultipleDropdownOptions;
|
|
@@ -27,6 +27,8 @@ import { ColumnFreezeMenuProps } from './types';
|
|
|
27
27
|
*
|
|
28
28
|
* @accessibility
|
|
29
29
|
* - The trigger is a labelled button, reachable by keyboard even while hidden
|
|
30
|
+
* - Opening moves focus into the menu (`role="menu"`): arrows, Home, End and
|
|
31
|
+
* type-to-find move the highlight, Enter or Space picks, Escape closes
|
|
30
32
|
* - Clicks inside the menu do not reach the header cell, so they never sort
|
|
31
33
|
*/
|
|
32
34
|
export declare const ColumnFreezeMenu: ({ columnId }: ColumnFreezeMenuProps) => import("@emotion/react/jsx-runtime").JSX.Element;
|
|
@@ -75,5 +75,5 @@ import { TextFieldProps } from './types';
|
|
|
75
75
|
* - ARIA attributes via React Hook Form (when register is provided)
|
|
76
76
|
* - Error messages announced to screen readers
|
|
77
77
|
*/
|
|
78
|
-
declare const TextField: ({ multirow, name, label, errors, helperText, success, disabled, maxLength, ...props }: TextFieldProps) => import("@emotion/react/jsx-runtime").JSX.Element;
|
|
78
|
+
declare const TextField: ({ multirow, name, label, labelBadge, errors, helperText, success, disabled, maxLength, ...props }: TextFieldProps) => import("@emotion/react/jsx-runtime").JSX.Element;
|
|
79
79
|
export default TextField;
|