@ahrowe/ui 0.4.2 → 0.4.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/common/accordion/accordion.mjs +1 -1
- package/dist/esm/common/accordion/accordion.mjs.map +1 -1
- package/dist/esm/common/actionButtons/actionButtons.mjs +1 -1
- package/dist/esm/common/actionButtons/actionButtons.mjs.map +1 -1
- package/dist/esm/common/badge/badge.mjs +1 -1
- package/dist/esm/common/badge/badge.mjs.map +1 -1
- package/dist/esm/common/button/button.mjs +1 -1
- package/dist/esm/common/button/button.mjs.map +1 -1
- package/dist/esm/common/card/Card.mjs +1 -1
- package/dist/esm/common/card/Card.mjs.map +1 -1
- package/dist/esm/common/card/card.types.mjs.map +1 -1
- package/dist/esm/common/checkbox/checkbox.mjs +1 -1
- package/dist/esm/common/checkbox/checkbox.mjs.map +1 -1
- package/dist/esm/common/chip/chip.mjs +1 -1
- package/dist/esm/common/chip/chip.mjs.map +1 -1
- package/dist/esm/common/configProvider/configProvider.mjs +2 -0
- package/dist/esm/common/configProvider/configProvider.mjs.map +1 -0
- package/dist/esm/common/configProvider/useComponentDefaults.mjs +2 -0
- package/dist/esm/common/configProvider/useComponentDefaults.mjs.map +1 -0
- package/dist/esm/common/datePicker/datePicker.mjs +1 -1
- package/dist/esm/common/datePicker/datePicker.mjs.map +1 -1
- package/dist/esm/common/divider/divider.mjs +2 -0
- package/dist/esm/common/divider/divider.mjs.map +1 -0
- package/dist/esm/common/divider/divider.module.mjs +2 -0
- package/dist/esm/common/divider/divider.module.mjs.map +1 -0
- package/dist/esm/common/divider/divider.types.mjs +2 -0
- package/dist/esm/common/divider/divider.types.mjs.map +1 -0
- package/dist/esm/common/dropdown/dropdown.mjs +1 -1
- package/dist/esm/common/dropdown/dropdown.mjs.map +1 -1
- package/dist/esm/common/dropdown/dropdown.module.mjs.map +1 -1
- package/dist/esm/common/input/input.mjs +1 -1
- package/dist/esm/common/input/input.mjs.map +1 -1
- package/dist/esm/common/input/input.module.mjs.map +1 -1
- package/dist/esm/common/input/input.types.mjs.map +1 -1
- package/dist/esm/common/inputDropdown/inputDropdown.mjs +1 -1
- package/dist/esm/common/inputDropdown/inputDropdown.mjs.map +1 -1
- package/dist/esm/common/numberInput/numberInput.mjs +1 -1
- package/dist/esm/common/numberInput/numberInput.mjs.map +1 -1
- package/dist/esm/common/sectionHeader/sectionHeader.mjs +2 -0
- package/dist/esm/common/sectionHeader/sectionHeader.mjs.map +1 -0
- package/dist/esm/common/sectionHeader/sectionHeader.module.mjs +2 -0
- package/dist/esm/common/sectionHeader/sectionHeader.module.mjs.map +1 -0
- package/dist/esm/common/sectionHeader/sectionHeader.types.mjs +2 -0
- package/dist/esm/common/sectionHeader/sectionHeader.types.mjs.map +1 -0
- package/dist/esm/common/skeleton/skeleton.mjs +1 -1
- package/dist/esm/common/skeleton/skeleton.mjs.map +1 -1
- package/dist/esm/common/switch/switch.mjs +1 -1
- package/dist/esm/common/switch/switch.mjs.map +1 -1
- package/dist/esm/common/textarea/textarea.mjs +1 -1
- package/dist/esm/common/textarea/textarea.mjs.map +1 -1
- package/dist/esm/index.mjs +1 -1
- package/dist/index.cjs +4 -4
- package/dist/index.cjs.map +1 -1
- package/dist/style.css +1 -1
- package/dist/types/package/common/accordion/accordion.d.ts +1 -1
- package/dist/types/package/common/actionButtons/actionButtons.d.ts +1 -1
- package/dist/types/package/common/badge/badge.d.ts +1 -1
- package/dist/types/package/common/button/button.d.ts +1 -1
- package/dist/types/package/common/card/Card.d.ts +1 -1
- package/dist/types/package/common/card/card.types.d.ts +2 -6
- package/dist/types/package/common/checkbox/checkbox.d.ts +1 -1
- package/dist/types/package/common/chip/chip.d.ts +1 -1
- package/dist/types/package/common/configProvider/configProvider.d.ts +5 -0
- package/dist/types/package/common/configProvider/configProvider.types.d.ts +56 -0
- package/dist/types/package/common/configProvider/index.d.ts +3 -0
- package/dist/types/package/common/configProvider/useComponentDefaults.d.ts +17 -0
- package/dist/types/package/common/datePicker/datePicker.d.ts +2 -3
- package/dist/types/package/common/divider/divider.d.ts +4 -0
- package/dist/types/package/common/divider/divider.types.d.ts +16 -0
- package/dist/types/package/common/divider/index.d.ts +2 -0
- package/dist/types/package/common/dropdown/dropdown.d.ts +1 -1
- package/dist/types/package/common/dropdown/dropdown.types.d.ts +1 -0
- package/dist/types/package/common/input/input.d.ts +1 -1
- package/dist/types/package/common/input/input.types.d.ts +1 -0
- package/dist/types/package/common/inputDropdown/inputDropdown.d.ts +1 -1
- package/dist/types/package/common/numberInput/numberInput.d.ts +2 -2
- package/dist/types/package/common/sectionHeader/index.d.ts +2 -0
- package/dist/types/package/common/sectionHeader/sectionHeader.d.ts +4 -0
- package/dist/types/package/common/sectionHeader/sectionHeader.types.d.ts +27 -0
- package/dist/types/package/common/skeleton/skeleton.d.ts +1 -1
- package/dist/types/package/common/switch/switch.d.ts +1 -1
- package/dist/types/package/common/themeProvider/theme.types.d.ts +2 -0
- package/dist/types/package/common/types/actions.types.d.ts +7 -0
- package/dist/types/package/index.d.ts +6 -0
- package/docs/CLAUDE.md +3 -0
- package/docs/ConfigProvider.md +81 -0
- package/docs/Divider.md +33 -0
- package/docs/Dropdown.md +1 -0
- package/docs/Input.md +1 -0
- package/docs/SectionHeader.md +90 -0
- package/docs/ThemeProvider.md +2 -0
- package/package.json +3 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { ReactElement } from 'react';
|
|
2
2
|
import { SkeletonProps } from './skeleton.types';
|
|
3
|
-
declare function Skeleton(
|
|
3
|
+
declare function Skeleton(props: SkeletonProps): ReactElement;
|
|
4
4
|
export default Skeleton;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { ReactElement } from 'react';
|
|
2
2
|
import { SwitchProps } from './switch.types';
|
|
3
|
-
declare function Switch(
|
|
3
|
+
declare function Switch(props: SwitchProps): ReactElement;
|
|
4
4
|
export default Switch;
|
|
@@ -53,6 +53,8 @@ export interface ThemeVariables {
|
|
|
53
53
|
'--input-background'?: string;
|
|
54
54
|
'--input-icon-color'?: string;
|
|
55
55
|
'--error-border-color'?: string;
|
|
56
|
+
'--input-label-resting-color'?: string;
|
|
57
|
+
'--input-label-floating-color'?: string;
|
|
56
58
|
'--default-border-radius'?: string;
|
|
57
59
|
'--padding-sides'?: string;
|
|
58
60
|
'--margin-top'?: string;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { IconDefinition } from '@fortawesome/free-solid-svg-icons';
|
|
2
|
+
/** A single icon-triggered action, rendered as an `ActionIcon` */
|
|
3
|
+
export interface IconAction {
|
|
4
|
+
title?: string;
|
|
5
|
+
onClick?: (e: React.MouseEvent<HTMLDivElement>) => void;
|
|
6
|
+
icon: IconDefinition;
|
|
7
|
+
}
|
|
@@ -19,10 +19,14 @@ export { default as Chip } from './common/chip';
|
|
|
19
19
|
export * from './common/chip';
|
|
20
20
|
export { default as ColorPicker } from './common/colorPicker';
|
|
21
21
|
export * from './common/colorPicker';
|
|
22
|
+
export { default as ConfigProvider } from './common/configProvider';
|
|
23
|
+
export * from './common/configProvider';
|
|
22
24
|
export { default as ConfirmModal } from './common/confirmModal';
|
|
23
25
|
export * from './common/confirmModal';
|
|
24
26
|
export { default as DatePicker } from './common/datePicker';
|
|
25
27
|
export * from './common/datePicker';
|
|
28
|
+
export { default as Divider } from './common/divider';
|
|
29
|
+
export * from './common/divider';
|
|
26
30
|
export { default as Drawer } from './common/drawer';
|
|
27
31
|
export * from './common/drawer';
|
|
28
32
|
export { default as DropZone } from './common/dropZone';
|
|
@@ -72,6 +76,8 @@ export { default as ScrollbarProvider } from './common/scrollbarProvider';
|
|
|
72
76
|
export * from './common/scrollbarProvider';
|
|
73
77
|
export { default as SearchInput } from './common/searchInput';
|
|
74
78
|
export * from './common/searchInput';
|
|
79
|
+
export { default as SectionHeader } from './common/sectionHeader';
|
|
80
|
+
export * from './common/sectionHeader';
|
|
75
81
|
export { default as Skeleton } from './common/skeleton';
|
|
76
82
|
export * from './common/skeleton';
|
|
77
83
|
export { default as Stepper } from './common/stepper';
|
package/docs/CLAUDE.md
CHANGED
|
@@ -103,8 +103,10 @@ Slot keys per component are documented in each component's doc file below.
|
|
|
103
103
|
@Checkbox.md
|
|
104
104
|
@Chip.md
|
|
105
105
|
@ColorPicker.md
|
|
106
|
+
@ConfigProvider.md
|
|
106
107
|
@ConfirmModal.md
|
|
107
108
|
@DatePicker.md
|
|
109
|
+
@Divider.md
|
|
108
110
|
@Drawer.md
|
|
109
111
|
@Dropdown.md
|
|
110
112
|
@DropZone.md
|
|
@@ -132,6 +134,7 @@ Slot keys per component are documented in each component's doc file below.
|
|
|
132
134
|
@RoomViewer.md
|
|
133
135
|
@ScrollbarProvider.md
|
|
134
136
|
@SearchInput.md
|
|
137
|
+
@SectionHeader.md
|
|
135
138
|
@Skeleton.md
|
|
136
139
|
@Stepper.md
|
|
137
140
|
@Sticky.md
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# ConfigProvider
|
|
2
|
+
|
|
3
|
+
**When to use:** Set global **default props** for library components once, near the root of your app, instead of repeating the same prop on every instance. If your app always wants floating labels, set `Input.alwaysFloatLabel` here and every `Input` picks it up.
|
|
4
|
+
|
|
5
|
+
**Import:** `import { ConfigProvider } from '@ahrowe/ui'`
|
|
6
|
+
**Types:** `import type { ComponentDefaults, ConfigProviderProps } from '@ahrowe/ui'`
|
|
7
|
+
|
|
8
|
+
Place it inside `ThemeProvider` (it's a separate concern from theming — theme = CSS variables, config = default props):
|
|
9
|
+
|
|
10
|
+
```tsx
|
|
11
|
+
import { ThemeProvider, ConfigProvider } from '@ahrowe/ui';
|
|
12
|
+
|
|
13
|
+
<ThemeProvider>
|
|
14
|
+
<ConfigProvider defaultProps={{ Input: { alwaysFloatLabel: true } }}>
|
|
15
|
+
<App />
|
|
16
|
+
</ConfigProvider>
|
|
17
|
+
</ThemeProvider>
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## How defaults resolve
|
|
21
|
+
|
|
22
|
+
For each prop, the value is chosen in this order (first that's set wins):
|
|
23
|
+
|
|
24
|
+
1. The prop **explicitly passed** to the component instance
|
|
25
|
+
2. The matching **global default** from the nearest `ConfigProvider`
|
|
26
|
+
3. The component's own **built-in default**
|
|
27
|
+
|
|
28
|
+
So a global default only fills in props a given instance left out — any instance can still override it:
|
|
29
|
+
|
|
30
|
+
```tsx
|
|
31
|
+
<ConfigProvider defaultProps={{ Input: { alwaysFloatLabel: true } }}>
|
|
32
|
+
<Input label="Name" /> {/* floats — inherits the global default */}
|
|
33
|
+
<Input label="Note" alwaysFloatLabel={false} />{/* opts out — explicit prop wins */}
|
|
34
|
+
</ConfigProvider>
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Nesting
|
|
38
|
+
|
|
39
|
+
`ConfigProvider`s compose. A nested provider extends the outer one per component, overriding only the keys it sets:
|
|
40
|
+
|
|
41
|
+
```tsx
|
|
42
|
+
<ConfigProvider defaultProps={{ Input: { alwaysFloatLabel: true, useMatLabelStyle: true } }}>
|
|
43
|
+
{/* Inputs here float and use the material label */}
|
|
44
|
+
<ConfigProvider defaultProps={{ Input: { alwaysFloatLabel: false } }}>
|
|
45
|
+
{/* Inputs here don't float, but still use the material label from the outer provider */}
|
|
46
|
+
</ConfigProvider>
|
|
47
|
+
</ConfigProvider>
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Key props
|
|
51
|
+
|
|
52
|
+
| Prop | Type | Description |
|
|
53
|
+
|------|------|-------------|
|
|
54
|
+
| `defaultProps` | `ComponentDefaults` | Default props keyed by component name, e.g. `{ Input: { alwaysFloatLabel: true } }` |
|
|
55
|
+
| `children` | `ReactNode` | Your app content |
|
|
56
|
+
|
|
57
|
+
## Supported components
|
|
58
|
+
|
|
59
|
+
Each entry is a `Partial<...Props>`, so any of that component's props can be defaulted:
|
|
60
|
+
|
|
61
|
+
- **Form inputs:** `Input` · `Textarea` · `NumberInput` · `Dropdown` · `InputDropdown` · `Checkbox` · `Switch` · `DatePicker`
|
|
62
|
+
- **Display:** `Button` · `ActionButtons` · `Badge` · `Chip` · `Card` · `SectionHeader` · `Skeleton` · `Accordion` · `Divider`
|
|
63
|
+
|
|
64
|
+
```tsx
|
|
65
|
+
<ConfigProvider
|
|
66
|
+
defaultProps={{
|
|
67
|
+
Input: { alwaysFloatLabel: true },
|
|
68
|
+
Dropdown: { useMatLabelStyle: true },
|
|
69
|
+
NumberInput: { decimalScale: 2, thousandSeparator: '.' },
|
|
70
|
+
Button: { styleType: ButtonStyleType.Primary },
|
|
71
|
+
Card: { styleType: CardStyleType.Outlined },
|
|
72
|
+
Skeleton: { animation: SkeletonAnimation.Pulse },
|
|
73
|
+
}}
|
|
74
|
+
>
|
|
75
|
+
<App />
|
|
76
|
+
</ConfigProvider>
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
`Textarea`, `NumberInput`, and `DatePicker` are built on top of `Input`, so they **also** inherit `Input` defaults for the props they forward to it. Their own component-keyed defaults take precedence for props they handle themselves. Example: with `Input: { alwaysFloatLabel: true }` set, every `Textarea` / `NumberInput` / `DatePicker` floats its label too, without needing a separate entry.
|
|
80
|
+
|
|
81
|
+
The `ComponentDefaults` type is the source of truth for which keys are currently supported — more components adopt it over time.
|
package/docs/Divider.md
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Divider
|
|
2
|
+
|
|
3
|
+
**When to use:** A horizontal rule that fills the width of its parent — separating sections of content. Optionally label it with text (e.g. "OR", a date, a section name); the line splits around the text, leaving a gap for it.
|
|
4
|
+
|
|
5
|
+
**Import:** `import { Divider, DividerTextPosition } from '@ahrowe/ui'`
|
|
6
|
+
|
|
7
|
+
**Text position:** `DividerTextPosition.Left` | `DividerTextPosition.Center` (default) | `DividerTextPosition.Right`
|
|
8
|
+
|
|
9
|
+
```tsx
|
|
10
|
+
import { Divider, DividerTextPosition } from '@ahrowe/ui';
|
|
11
|
+
|
|
12
|
+
// Plain line
|
|
13
|
+
<Divider />
|
|
14
|
+
|
|
15
|
+
// Centered text (default)
|
|
16
|
+
<Divider text="OR" />
|
|
17
|
+
|
|
18
|
+
// Text near the left edge
|
|
19
|
+
<Divider text="Section title" textPosition={DividerTextPosition.Left} />
|
|
20
|
+
|
|
21
|
+
// Text near the right edge
|
|
22
|
+
<Divider text="March 2026" textPosition={DividerTextPosition.Right} />
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
**Key props:**
|
|
26
|
+
|
|
27
|
+
| Prop | Type | Description |
|
|
28
|
+
|------|------|-------------|
|
|
29
|
+
| `text` | `ReactNode` | Text (or any node) rendered on the line. Omit for a plain full-width line |
|
|
30
|
+
| `textPosition` | `DividerTextPosition` | Where `text` sits along the line (default `Center`) |
|
|
31
|
+
| `className` / `style` | | Root element |
|
|
32
|
+
|
|
33
|
+
**Slots:** `root` `line` (the line segment(s) either side of `text`) `content` (the `text` wrapper)
|
package/docs/Dropdown.md
CHANGED
|
@@ -53,5 +53,6 @@ const statusValidator = new FormValidator('', [Validators.required()]);
|
|
|
53
53
|
| `placeholder` | `string` | Placeholder when no selection |
|
|
54
54
|
| `onScroll` | `() => Promise<void>` | Load more on list scroll |
|
|
55
55
|
| `useMatLabelStyle` | `boolean` | Material-style floating label |
|
|
56
|
+
| `alwaysFloatLabel` | `boolean` | Keep the material label floated in the border notch even when nothing is selected, so an empty dropdown reads as blank instead of showing the label as if it were the selected value. Only applies with `useMatLabelStyle` (default) |
|
|
56
57
|
|
|
57
58
|
The list is rendered through a portal and tracks the trigger across scroll, so it always escapes clipping ancestors (cards, scroll containers, virtualized lists). It flips to open upward automatically when there's no room below, and hides (without closing) if the trigger itself scrolls behind a clipping ancestor, reappearing once it's back in view.
|
package/docs/Input.md
CHANGED
|
@@ -66,6 +66,7 @@ const emailValidator = new FormValidator('', [Validators.required(), Validators.
|
|
|
66
66
|
| `onClearClicked` | `() => void` | Clear button handler |
|
|
67
67
|
| `isRow` | `boolean` | Horizontal layout |
|
|
68
68
|
| `labelInBorder` | `boolean` | Label inside fieldset border |
|
|
69
|
+
| `alwaysFloatLabel` | `boolean` | Keep the material label floated in the border notch even when empty and unfocused, so an empty field reads as blank instead of showing the label as if it were a value. Only applies with `useMatLabelStyle` (default) |
|
|
69
70
|
| `readOnly` | `boolean` | |
|
|
70
71
|
| `autoFocus` | `boolean` | |
|
|
71
72
|
| `placeholder` | `string` | |
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# SectionHeader
|
|
2
|
+
|
|
3
|
+
**When to use:** A reusable heading block for the top of a page, panel, card, or any section — a title with an optional subtitle, a leading icon or thumbnail, and a trailing actions area. Use it wherever you'd otherwise hand-roll a `<h2>` + subtitle + buttons row. Inside a `Card`, the card-scoped `CardHeader` remains available; `SectionHeader` is the standalone, fully slot-customisable version.
|
|
4
|
+
|
|
5
|
+
**Import:** `import { SectionHeader, SectionHeaderSize } from '@ahrowe/ui'`
|
|
6
|
+
**Types:** `import type { SectionHeaderProps, SectionHeaderAction } from '@ahrowe/ui'`
|
|
7
|
+
|
|
8
|
+
**Style variants:** `SectionHeaderSize.Small` | `SectionHeaderSize.Medium` (default) | `SectionHeaderSize.Large`
|
|
9
|
+
|
|
10
|
+
```tsx
|
|
11
|
+
import { SectionHeader, SectionHeaderSize } from '@ahrowe/ui';
|
|
12
|
+
import { faFolder, faPen, faTrash } from '@fortawesome/free-solid-svg-icons';
|
|
13
|
+
|
|
14
|
+
// Title + subtitle
|
|
15
|
+
<SectionHeader title="Account settings" subtitle="Manage your profile and preferences" />
|
|
16
|
+
|
|
17
|
+
// Leading icon
|
|
18
|
+
<SectionHeader icon={faFolder} title="Documents" subtitle="12 files" />
|
|
19
|
+
|
|
20
|
+
// Leading thumbnail (URL → background image; any other ReactNode → rendered inside)
|
|
21
|
+
<SectionHeader thumbnail="https://example.com/avatar.jpg" title="Jane Doe" subtitle="Designer" />
|
|
22
|
+
|
|
23
|
+
// Trailing actions — array renders ActionIcons, or pass any ReactNode
|
|
24
|
+
<SectionHeader
|
|
25
|
+
title="Integrations"
|
|
26
|
+
actions={[
|
|
27
|
+
{ title: 'Edit', icon: faPen, onClick: handleEdit },
|
|
28
|
+
{ title: 'Delete', icon: faTrash, onClick: handleDelete },
|
|
29
|
+
]}
|
|
30
|
+
/>
|
|
31
|
+
<SectionHeader title="Reports" actions={<Button>Export</Button>} />
|
|
32
|
+
|
|
33
|
+
// Larger scale, a bottom divider, and a semantic heading level for a11y
|
|
34
|
+
<SectionHeader
|
|
35
|
+
size={SectionHeaderSize.Large}
|
|
36
|
+
level={1}
|
|
37
|
+
divider
|
|
38
|
+
title="Dashboard"
|
|
39
|
+
subtitle="Your workspace at a glance"
|
|
40
|
+
/>
|
|
41
|
+
|
|
42
|
+
// left / center — the title stays fixed to the left; everything else (left,
|
|
43
|
+
// center, actions) lives in a separate trailing block laid out with
|
|
44
|
+
// space-between, so `center` is centered within that block, not the whole header
|
|
45
|
+
<SectionHeader
|
|
46
|
+
title="Team members"
|
|
47
|
+
left={<Chip text="12 active" />}
|
|
48
|
+
center={<SearchInput value={query} onChange={setQuery} />}
|
|
49
|
+
actions={[{ title: 'Invite', icon: faPlus, onClick: handleInvite }]}
|
|
50
|
+
/>
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
**Enums:**
|
|
54
|
+
|
|
55
|
+
- `SectionHeaderSize`: `Small` | `Medium` (default) | `Large`
|
|
56
|
+
|
|
57
|
+
**Key props:**
|
|
58
|
+
|
|
59
|
+
| Prop | Type | Description |
|
|
60
|
+
|------|------|-------------|
|
|
61
|
+
| `title` | `ReactNode` | Main heading |
|
|
62
|
+
| `subtitle` | `ReactNode` | Secondary text below the title |
|
|
63
|
+
| `icon` | `IconDefinition` | FontAwesome icon shown on the left; ignored when `thumbnail` is set |
|
|
64
|
+
| `thumbnail` | `string \| ReactNode` | URL → background image; any other ReactNode → rendered inside the leading circle |
|
|
65
|
+
| `left` | `ReactNode` | Leftmost content of the trailing block (title stays fixed to the left of it) |
|
|
66
|
+
| `center` | `ReactNode` | Center content of the trailing block, e.g. a search box or tabs |
|
|
67
|
+
| `actions` | `SectionHeaderAction[] \| ReactNode` | Rightmost content of the trailing block: array → `ActionIcon`s; ReactNode → rendered as-is |
|
|
68
|
+
| `level` | `1 \| 2 \| 3 \| 4 \| 5 \| 6` | Semantic heading level for the title element (default `2`) |
|
|
69
|
+
| `size` | `SectionHeaderSize` | Visual scale (default `Medium`) |
|
|
70
|
+
| `divider` | `boolean` | Render a `Divider` below the header (default `false`) |
|
|
71
|
+
|
|
72
|
+
**SectionHeaderAction:**
|
|
73
|
+
|
|
74
|
+
```ts
|
|
75
|
+
interface SectionHeaderAction {
|
|
76
|
+
title?: string;
|
|
77
|
+
icon: IconDefinition;
|
|
78
|
+
onClick?: (e: React.MouseEvent<HTMLDivElement>) => void;
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
**Global defaults:** adopts `ConfigProvider` — set defaults app-wide via `defaultProps={{ SectionHeader: { size: SectionHeaderSize.Large } }}`. See [ConfigProvider.md](ConfigProvider.md).
|
|
83
|
+
|
|
84
|
+
**Theming:** title size/weight per `size` variant come from the theme, with local fallbacks — `SectionHeaderSize.Large` uses `--header-font-size` (falls back `24px`), `Medium` uses `--header-medium-font-size` (falls back `18px`), `Small` uses `--header-small-font-size` (falls back `16px`); all three use `--header-font-weight` for the title's font weight (falls back `600`). The leading icon/thumbnail is sized at `2.2×` the title size, so it scales automatically with the theme; the subtitle size is fixed per `size` variant (not derived), since it doesn't track the title proportionally at the `Large` size. See [ThemeProvider.md](ThemeProvider.md).
|
|
85
|
+
|
|
86
|
+
**Layout:** the title (with its leading icon/thumbnail) is fixed to the left and only takes the width its content needs. Everything after it — `left`, `center`, `actions` — lives in a separate `trailing` flex block laid out with `space-between`, so `center` is centered within that block (not the whole header) regardless of how wide `left`/`actions` are.
|
|
87
|
+
|
|
88
|
+
**Responsive:** the header wraps — if `trailing` (`left`/`center`/`actions`) doesn't fit next to the title, it drops to its own row; if `trailing` itself doesn't fit as one row, its own children wrap too. Below `640px` viewport width, `center` additionally takes a full-width row of its own, so a wide `center` element (e.g. a `SearchInput`) isn't squeezed alongside `left`/`actions` on small screens.
|
|
89
|
+
|
|
90
|
+
**Slots:** `root` `leading` `titles` `title` `subtitle` `trailing` `left` `center` `actions`
|
package/docs/ThemeProvider.md
CHANGED
|
@@ -70,6 +70,8 @@ interface Theme {
|
|
|
70
70
|
| `--error-color` / `--success-color` / `--warn-color` / `--info-color` | Semantic colours |
|
|
71
71
|
| `--default-border-radius` | Border radii |
|
|
72
72
|
| `--avatar-radius` | `Avatar` corner radius — falls back to `--default-border-radius` when unset (set to `50%` theme-wide for fully circular avatars) |
|
|
73
|
+
| `--input-label-resting-color` | Resting (not-floated) material label colour for `Input` & `Dropdown` — falls back to `--text-light` when unset |
|
|
74
|
+
| `--input-label-floating-color` | Floating (active) material label colour for `Input` & `Dropdown` — falls back to `--text-color` when unset |
|
|
73
75
|
| `--card-shadow` | Elevation shadows |
|
|
74
76
|
|
|
75
77
|
**Key props:**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ahrowe/ui",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.4",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -55,6 +55,7 @@
|
|
|
55
55
|
"preview": "vite preview",
|
|
56
56
|
"gen-barrel": "tsx scripts/gen-barrel.ts",
|
|
57
57
|
"gc": "bash src/scripts/generateComponent.sh $INIT_CWD process.argv",
|
|
58
|
+
"changeset": "changeset",
|
|
58
59
|
"lint": "eslint .",
|
|
59
60
|
"lint:fix": "eslint . --fix",
|
|
60
61
|
"format": "prettier --write .",
|
|
@@ -86,6 +87,7 @@
|
|
|
86
87
|
"zod": "^4.4.3"
|
|
87
88
|
},
|
|
88
89
|
"devDependencies": {
|
|
90
|
+
"@changesets/cli": "^2.31.0",
|
|
89
91
|
"@eslint/js": "^9.39.4",
|
|
90
92
|
"@fortawesome/fontawesome-svg-core": "^7.2.0",
|
|
91
93
|
"@fortawesome/free-solid-svg-icons": "^7.2.0",
|