@ahrowe/ui 0.37.0 → 0.39.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/README.md +5 -2
- package/dist/cjs-types/common/commandPalette/commandPalette.d.ts +4 -0
- package/dist/cjs-types/common/commandPalette/commandPalette.types.d.ts +42 -0
- package/dist/cjs-types/common/commandPalette/filterCommands.d.ts +15 -0
- package/dist/cjs-types/common/commandPalette/index.d.ts +2 -0
- package/dist/cjs-types/common/configProvider/configProvider.types.d.ts +6 -0
- package/dist/cjs-types/common/copyButton/copyButton.d.ts +4 -0
- package/dist/cjs-types/common/copyButton/copyButton.types.d.ts +36 -0
- package/dist/cjs-types/common/copyButton/index.d.ts +2 -0
- package/dist/cjs-types/common/datePicker/components/datePickerMonth/datePickerMonth.types.d.ts +6 -6
- package/dist/cjs-types/common/datePicker/dateFunctions.d.ts +10 -19
- package/dist/cjs-types/common/datePicker/datePicker.types.d.ts +20 -14
- package/dist/cjs-types/common/datePicker/index.d.ts +1 -0
- package/dist/cjs-types/common/errorBoundary/errorBoundary.d.ts +0 -3
- package/dist/cjs-types/common/errorBoundary/errorBoundary.types.d.ts +2 -3
- package/dist/cjs-types/common/hooks/index.d.ts +2 -0
- package/dist/cjs-types/common/hooks/useClipboard.d.ts +16 -0
- package/dist/cjs-types/common/inputDropdown/inputDropdown.types.d.ts +7 -1
- package/dist/cjs-types/common/menu/menu.types.d.ts +2 -0
- package/dist/cjs-types/common/popover/popover.types.d.ts +5 -0
- package/dist/cjs-types/common/themeProvider/themeProvider.d.ts +8 -7
- package/dist/cjs-types/common/utils/day.d.ts +16 -0
- package/dist/cjs-types/common/weatherIcon/index.d.ts +3 -0
- package/dist/cjs-types/common/weatherIcon/parts.d.ts +26 -0
- package/dist/cjs-types/common/weatherIcon/weatherIcon.d.ts +4 -0
- package/dist/cjs-types/common/weatherIcon/weatherIcon.types.d.ts +44 -0
- package/dist/cjs-types/index.d.ts +7 -1
- package/dist/esm/common/buttonGroup/buttonGroup.module.mjs.map +1 -1
- package/dist/esm/common/commandPalette/commandPalette.mjs +2 -0
- package/dist/esm/common/commandPalette/commandPalette.mjs.map +1 -0
- package/dist/esm/common/commandPalette/commandPalette.module.mjs +2 -0
- package/dist/esm/common/commandPalette/commandPalette.module.mjs.map +1 -0
- package/dist/esm/common/commandPalette/filterCommands.mjs +2 -0
- package/dist/esm/common/commandPalette/filterCommands.mjs.map +1 -0
- package/dist/esm/common/copyButton/copyButton.mjs +2 -0
- package/dist/esm/common/copyButton/copyButton.mjs.map +1 -0
- package/dist/esm/common/copyButton/copyButton.module.mjs +2 -0
- package/dist/esm/common/copyButton/copyButton.module.mjs.map +1 -0
- package/dist/esm/common/datePicker/components/datePickerMonth/datePickerMonth.mjs +1 -1
- package/dist/esm/common/datePicker/components/datePickerMonth/datePickerMonth.mjs.map +1 -1
- package/dist/esm/common/datePicker/dateFunctions.mjs +1 -1
- package/dist/esm/common/datePicker/dateFunctions.mjs.map +1 -1
- package/dist/esm/common/datePicker/datePicker.mjs +1 -1
- package/dist/esm/common/datePicker/datePicker.mjs.map +1 -1
- package/dist/esm/common/dropdown/dropdown.mjs +1 -1
- package/dist/esm/common/dropdown/dropdown.module.mjs.map +1 -1
- package/dist/esm/common/errorBoundary/errorBoundary.mjs +2 -2
- package/dist/esm/common/errorBoundary/errorBoundary.mjs.map +1 -1
- package/dist/esm/common/errorBoundary/errorBoundary.module.mjs +1 -1
- package/dist/esm/common/errorBoundary/errorBoundary.module.mjs.map +1 -1
- package/dist/esm/common/hooks/useClipboard.mjs +2 -0
- package/dist/esm/common/hooks/useClipboard.mjs.map +1 -0
- package/dist/esm/common/hooks/useFocusBoundary.mjs +1 -1
- package/dist/esm/common/hooks/useFocusBoundary.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/inputDropdown/inputDropdown.module.mjs +1 -1
- package/dist/esm/common/inputDropdown/inputDropdown.module.mjs.map +1 -1
- package/dist/esm/common/menu/menu.mjs +1 -1
- package/dist/esm/common/menu/menu.mjs.map +1 -1
- package/dist/esm/common/menu/menu.types.mjs.map +1 -1
- package/dist/esm/common/popover/popover.mjs +1 -1
- package/dist/esm/common/popover/popover.mjs.map +1 -1
- package/dist/esm/common/popover/popover.types.mjs.map +1 -1
- package/dist/esm/common/themeProvider/themeProvider.mjs +1 -1
- package/dist/esm/common/themeProvider/themeProvider.mjs.map +1 -1
- package/dist/esm/common/timer/timer.mjs +1 -1
- package/dist/esm/common/timer/timer.mjs.map +1 -1
- package/dist/esm/common/utils/day.mjs +2 -0
- package/dist/esm/common/utils/day.mjs.map +1 -0
- package/dist/esm/common/weatherIcon/parts.mjs +2 -0
- package/dist/esm/common/weatherIcon/parts.mjs.map +1 -0
- package/dist/esm/common/weatherIcon/weatherIcon.mjs +2 -0
- package/dist/esm/common/weatherIcon/weatherIcon.mjs.map +1 -0
- package/dist/esm/common/weatherIcon/weatherIcon.module.mjs +2 -0
- package/dist/esm/common/weatherIcon/weatherIcon.module.mjs.map +1 -0
- package/dist/esm/common/weatherIcon/weatherIcon.types.mjs +2 -0
- package/dist/esm/common/weatherIcon/weatherIcon.types.mjs.map +1 -0
- package/dist/esm/index.mjs +1 -1
- package/dist/index.cjs +3 -3
- package/dist/index.cjs.map +1 -1
- package/dist/style.css +1 -1
- package/dist/types/common/commandPalette/commandPalette.d.ts +4 -0
- package/dist/types/common/commandPalette/commandPalette.types.d.ts +42 -0
- package/dist/types/common/commandPalette/filterCommands.d.ts +15 -0
- package/dist/types/common/commandPalette/index.d.ts +2 -0
- package/dist/types/common/configProvider/configProvider.types.d.ts +6 -0
- package/dist/types/common/copyButton/copyButton.d.ts +4 -0
- package/dist/types/common/copyButton/copyButton.types.d.ts +36 -0
- package/dist/types/common/copyButton/index.d.ts +2 -0
- package/dist/types/common/datePicker/components/datePickerMonth/datePickerMonth.types.d.ts +6 -6
- package/dist/types/common/datePicker/dateFunctions.d.ts +10 -19
- package/dist/types/common/datePicker/datePicker.types.d.ts +20 -14
- package/dist/types/common/datePicker/index.d.ts +1 -0
- package/dist/types/common/errorBoundary/errorBoundary.d.ts +0 -3
- package/dist/types/common/errorBoundary/errorBoundary.types.d.ts +2 -3
- package/dist/types/common/hooks/index.d.ts +2 -0
- package/dist/types/common/hooks/useClipboard.d.ts +16 -0
- package/dist/types/common/inputDropdown/inputDropdown.types.d.ts +7 -1
- package/dist/types/common/menu/menu.types.d.ts +2 -0
- package/dist/types/common/popover/popover.types.d.ts +5 -0
- package/dist/types/common/themeProvider/themeProvider.d.ts +8 -7
- package/dist/types/common/utils/day.d.ts +16 -0
- package/dist/types/common/weatherIcon/index.d.ts +3 -0
- package/dist/types/common/weatherIcon/parts.d.ts +26 -0
- package/dist/types/common/weatherIcon/weatherIcon.d.ts +4 -0
- package/dist/types/common/weatherIcon/weatherIcon.types.d.ts +44 -0
- package/dist/types/index.d.ts +7 -1
- package/docs/ButtonGroup.md +2 -0
- package/docs/CLAUDE.md +9 -2
- package/docs/CommandPalette.md +84 -0
- package/docs/ConfigProvider.md +2 -2
- package/docs/CopyButton.md +45 -0
- package/docs/DatePicker.md +72 -45
- package/docs/ErrorBoundary.md +4 -4
- package/docs/Fab.md +1 -2
- package/docs/FormValidator.md +3 -3
- package/docs/Hooks.md +39 -3
- package/docs/InputDropdown.md +9 -4
- package/docs/Menu.md +5 -3
- package/docs/Popover.md +15 -0
- package/docs/WeatherIcon.md +49 -0
- package/package.json +2 -3
package/README.md
CHANGED
|
@@ -132,9 +132,11 @@ runs where `@ahrowe/ui` is installed.
|
|
|
132
132
|
| `Checkbox` | Boolean toggle input — settings, multi-select lists, accept terms, feature flags |
|
|
133
133
|
| `Chip`, `ChipContainer`, `ChipStyleType` | Compact tag, label, or filter token — selected items, applied filters, category badges, user avatars with remove |
|
|
134
134
|
| `ColorPicker` | Hex colour selection — theme editors, annotation tools, customisation panels |
|
|
135
|
+
| `CommandPalette` | A search-first dialog for running any command or jumping anywhere in the app from the keyboard, usually opened with ⌘K / Ctrl+K |
|
|
135
136
|
| `ConfigProvider` | Set global **default props** for library components once, near the root of your app, instead of repeating the same prop on every instance |
|
|
136
137
|
| `ConfirmModal` | Confirmation dialog before destructive or irreversible actions — delete, archive, send, overwrite |
|
|
137
|
-
| `
|
|
138
|
+
| `CopyButton` | Icon-only button that copies a value to the clipboard: an invoice number, an ID in a table row, an API key or share link inside an `Input` |
|
|
139
|
+
| `DatePicker`, `dateToDay`, `dayToDate` | Date selection input — booking forms, birth date fields, date range pickers, deadline selectors |
|
|
138
140
|
| `Divider`, `DividerTextPosition`, `DividerOrientation` | A rule that separates sections of content — horizontal by default, filling the width of its parent |
|
|
139
141
|
| `Drawer` | Inline horizontal panel that collapses and expands by animating its width — side panels, navigation rails, detail/filter panes that slide open beside the main content |
|
|
140
142
|
| `DropZone`, `DropZoneReturnType`, `DropZoneStatus` | Drag-and-drop file upload area, optionally click-to-open the native picker |
|
|
@@ -146,7 +148,7 @@ runs where `@ahrowe/ui` is installed.
|
|
|
146
148
|
| `emptyFloorPlan`, `addWall`, `derivePlan` | The shared data model behind `RoomDrawer` and `RoomViewer` |
|
|
147
149
|
| `FormValidator`, `Validators`, `useFormValidator` | Track and validate a single form field's value, dirty/touched state, and errors |
|
|
148
150
|
| `useFormValidatorGroup`, `FormValidatorGroup`, `FormValidator`, `Validators` | Manage a whole form — multiple fields, a single submit handler, validate-on-submit, dirty/touched tracking across the form, and mapping server-side errors back onto the right fields |
|
|
149
|
-
| `useHotkeys`, `formatHotkey`, `useMediaQuery`, `useCoarsePointer`, `useVisualViewportSize`, `useScrollEdges`, `useSwipeDismiss`, `useOverlay`, `tabbablesIn` | Standalone React hooks the library uses internally and publishes for the same jobs in your own code: keyboard shortcuts, media queries, the mobile keyboard's viewport, scroll-edge detection, swipe-to-dismiss, and the Escape / focus-trap / scroll-lock behaviour behind a custom overlay |
|
|
151
|
+
| `useHotkeys`, `formatHotkey`, `useMediaQuery`, `useCoarsePointer`, `useVisualViewportSize`, `useScrollEdges`, `useSwipeDismiss`, `useOverlay`, `useClipboard`, `tabbablesIn` | Standalone React hooks the library uses internally and publishes for the same jobs in your own code: keyboard shortcuts, media queries, the mobile keyboard's viewport, scroll-edge detection, swipe-to-dismiss, copying to the clipboard, and the Escape / focus-trap / scroll-lock behaviour behind a custom overlay |
|
|
150
152
|
| `IconPicker` | Pick one item from a visual icon/image grid — category selectors, emoji-style pickers, avatar selectors, anything where each option is best represented by an icon or image rather than text alone |
|
|
151
153
|
| `IdleManager` | Show something only once the user has stopped interacting — a screen saver, a session-timeout warning, an "are you still there?" prompt, an idle dashboard view |
|
|
152
154
|
| `Input`, `InputType` | Text input with floating label, validation state, and type variants |
|
|
@@ -192,6 +194,7 @@ runs where `@ahrowe/ui` is installed.
|
|
|
192
194
|
| `Tooltip` | Contextual help, info icons, field explanations, error pointers |
|
|
193
195
|
| `Tree`, `flattenTree` | A hierarchical list the user can expand, collapse and pick from: categories, nested locations, folder structures, org charts |
|
|
194
196
|
| `VirtualList` | Efficiently render large lists or tables — thousands of rows rendered with a virtualised scroll window so only visible rows are in the DOM |
|
|
197
|
+
| `WeatherIcon`, `WeatherType` | An animated weather symbol for a forecast, a dashboard widget or a day selector, one per condition a forecast reports |
|
|
195
198
|
| `Wizard` | Animated step container for multi-step forms and flows |
|
|
196
199
|
|
|
197
200
|
<!-- components:end -->
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { CSSProperties } from 'react';
|
|
2
|
+
import { MenuEntry } from '../menu/menu.types.js';
|
|
3
|
+
import { Presentation } from '../configProvider/presentation.types.js';
|
|
4
|
+
import { SlotClassNames, SlotStyles, HtmlProps } from '../types/slots.types.js';
|
|
5
|
+
export type CommandPaletteSlots = 'root' | 'search' | 'input' | 'list' | 'item' | 'itemIcon' | 'itemLabel' | 'itemShortcut' | 'heading' | 'separator' | 'empty';
|
|
6
|
+
export interface CommandPaletteLabels {
|
|
7
|
+
/** Accessible name of the dialog and the search field. Default: "Search commands". */
|
|
8
|
+
label?: string;
|
|
9
|
+
/** Placeholder in the search field. Default: "Type a command or search…". */
|
|
10
|
+
placeholder?: string;
|
|
11
|
+
/** Shown when nothing matches. Default: "No results". */
|
|
12
|
+
empty?: string;
|
|
13
|
+
/** Shown while `isLoading` and nothing matches yet. Default: "Searching…". */
|
|
14
|
+
loading?: string;
|
|
15
|
+
/** Announced to screen readers as the matches change. */
|
|
16
|
+
results?: (count: number) => string;
|
|
17
|
+
}
|
|
18
|
+
export interface CommandPaletteProps extends HtmlProps<HTMLDivElement> {
|
|
19
|
+
/** The commands, in the same shape `Menu` takes. Headings group them; separators split groups. */
|
|
20
|
+
items: MenuEntry[];
|
|
21
|
+
isOpen: boolean;
|
|
22
|
+
onClose: () => void;
|
|
23
|
+
/** Called with the id of the command that was run, after its own `onClick`. */
|
|
24
|
+
onAction?: (id: string) => void;
|
|
25
|
+
/** Called on every keystroke, and with `''` each time the palette opens. */
|
|
26
|
+
onQueryChange?: (query: string) => void;
|
|
27
|
+
/**
|
|
28
|
+
* Filter `items` by the query. Default `true`. Set `false` when `items` are already the results,
|
|
29
|
+
* e.g. fetched from a server in `onQueryChange`.
|
|
30
|
+
*/
|
|
31
|
+
filter?: boolean;
|
|
32
|
+
/** Shows the `loading` label instead of `empty` while nothing matches. */
|
|
33
|
+
isLoading?: boolean;
|
|
34
|
+
/** Centred dialog, bottom sheet, or a sheet only on a small touch screen. */
|
|
35
|
+
presentation?: Presentation;
|
|
36
|
+
/** Text this component renders of its own. */
|
|
37
|
+
labels?: CommandPaletteLabels;
|
|
38
|
+
className?: string;
|
|
39
|
+
style?: CSSProperties;
|
|
40
|
+
classNames?: SlotClassNames<CommandPaletteSlots>;
|
|
41
|
+
styles?: SlotStyles<CommandPaletteSlots>;
|
|
42
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { MenuAction, MenuEntry } from '../menu/menu.types.js';
|
|
3
|
+
export interface CommandGroup {
|
|
4
|
+
heading?: ReactNode;
|
|
5
|
+
/** Whether a separator started this group, so the divider can be drawn above it. */
|
|
6
|
+
separated: boolean;
|
|
7
|
+
actions: MenuAction[];
|
|
8
|
+
}
|
|
9
|
+
/** Splits entries into groups at each heading and separator, keeping their order. */
|
|
10
|
+
export declare function groupCommands(items: MenuEntry[]): CommandGroup[];
|
|
11
|
+
/**
|
|
12
|
+
* The groups with only the actions matching `query`, best matches first within each group, and
|
|
13
|
+
* the group holding the best match first. A heading moves with its group, never away from it.
|
|
14
|
+
*/
|
|
15
|
+
export declare function filterCommands(groups: CommandGroup[], query: string): CommandGroup[];
|
|
@@ -15,6 +15,9 @@ import { SearchInputLabels } from '../searchInput/searchInput.types.js';
|
|
|
15
15
|
import { TooltipLabels } from '../tooltip/tooltip.types.js';
|
|
16
16
|
import { VirtualListLabels } from '../virtualList/virtualList.types.js';
|
|
17
17
|
import { ButtonProps } from '../button/button.types.js';
|
|
18
|
+
import { CopyButtonProps } from '../copyButton/copyButton.types.js';
|
|
19
|
+
import { CommandPaletteProps } from '../commandPalette/commandPalette.types.js';
|
|
20
|
+
import { WeatherIconProps } from '../weatherIcon/weatherIcon.types.js';
|
|
18
21
|
import { ActionButtonsProps } from '../actionButtons/actionButtons.types.js';
|
|
19
22
|
import { ConfirmModalProps } from '../confirmModal/confirmModal.types.js';
|
|
20
23
|
import { BadgeProps } from '../badge/badge.types.js';
|
|
@@ -91,6 +94,7 @@ export interface ComponentDefaults {
|
|
|
91
94
|
RadioGroup?: Partial<RadioGroupProps>;
|
|
92
95
|
DatePicker?: Partial<DatePickerProps>;
|
|
93
96
|
Button?: Partial<ButtonProps>;
|
|
97
|
+
CopyButton?: Partial<CopyButtonProps>;
|
|
94
98
|
ActionButtons?: Partial<ActionButtonsProps>;
|
|
95
99
|
ConfirmModal?: Partial<ConfirmModalProps>;
|
|
96
100
|
Badge?: Partial<BadgeProps>;
|
|
@@ -118,6 +122,8 @@ export interface ComponentDefaults {
|
|
|
118
122
|
RoomViewer?: Partial<RoomViewerProps>;
|
|
119
123
|
Popover?: Partial<PopoverProps>;
|
|
120
124
|
Modal?: Partial<ModalProps>;
|
|
125
|
+
CommandPalette?: Partial<CommandPaletteProps>;
|
|
126
|
+
WeatherIcon?: Partial<WeatherIconProps>;
|
|
121
127
|
}
|
|
122
128
|
export interface ConfigProviderProps {
|
|
123
129
|
children: React.ReactNode;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { CSSProperties, MouseEvent, Ref } from 'react';
|
|
2
|
+
import { IconContent } from '../types/icon.types.js';
|
|
3
|
+
import { SlotClassNames, SlotStyles, HtmlProps } from '../types/slots.types.js';
|
|
4
|
+
export type CopyButtonSlots = 'root' | 'icon';
|
|
5
|
+
export interface CopyButtonLabels {
|
|
6
|
+
/** Accessible name and tooltip before copying. Default: "Copy". */
|
|
7
|
+
copy?: string;
|
|
8
|
+
/** Accessible name and tooltip after a successful copy, also announced. Default: "Copied". */
|
|
9
|
+
copied?: string;
|
|
10
|
+
/** Announced when the copy fails. Default: "Could not copy". */
|
|
11
|
+
failed?: string;
|
|
12
|
+
}
|
|
13
|
+
export interface CopyButtonProps extends Omit<HtmlProps<HTMLDivElement>, 'onCopy' | 'onError'> {
|
|
14
|
+
/** Text written to the clipboard on click. */
|
|
15
|
+
value: string;
|
|
16
|
+
/** How long the copied state shows, in ms. Default: 2000. */
|
|
17
|
+
timeout?: number;
|
|
18
|
+
/** Icon before copying. Default: `faCopy`. */
|
|
19
|
+
icon?: IconContent;
|
|
20
|
+
/** Icon while the copied state shows. Default: `faCheck`. */
|
|
21
|
+
copiedIcon?: IconContent;
|
|
22
|
+
/** Called after a successful copy. */
|
|
23
|
+
onCopy?: (value: string) => void;
|
|
24
|
+
/** Called when the clipboard refuses the write, e.g. outside a secure context. */
|
|
25
|
+
onError?: () => void;
|
|
26
|
+
/** Called on every click, before the copy. */
|
|
27
|
+
onClick?: (event: MouseEvent<HTMLDivElement>) => void;
|
|
28
|
+
/** Text this component renders of its own. */
|
|
29
|
+
labels?: CopyButtonLabels;
|
|
30
|
+
/** Ref to the root element. */
|
|
31
|
+
ref?: Ref<HTMLDivElement>;
|
|
32
|
+
className?: string;
|
|
33
|
+
style?: CSSProperties;
|
|
34
|
+
classNames?: SlotClassNames<CopyButtonSlots>;
|
|
35
|
+
styles?: SlotStyles<CopyButtonSlots>;
|
|
36
|
+
}
|
package/dist/cjs-types/common/datePicker/components/datePickerMonth/datePickerMonth.types.d.ts
CHANGED
|
@@ -8,16 +8,16 @@ export interface DatePickerMonthProps {
|
|
|
8
8
|
month?: number;
|
|
9
9
|
/** Year to display. */
|
|
10
10
|
year?: number;
|
|
11
|
-
/** Called with the day that was picked
|
|
12
|
-
onSelect?: (
|
|
11
|
+
/** Called with the day that was picked, `'YYYY-MM-DD'`. */
|
|
12
|
+
onSelect?: (day: string) => void;
|
|
13
13
|
/** First day of the highlighted range, and the day that starts with the tab stop. */
|
|
14
|
-
selectionStart?:
|
|
14
|
+
selectionStart?: string | null;
|
|
15
15
|
/** Last day of the highlighted range. */
|
|
16
|
-
selectionEnd?:
|
|
16
|
+
selectionEnd?: string | null;
|
|
17
17
|
/** Days before this are not selectable. */
|
|
18
|
-
minDate?:
|
|
18
|
+
minDate?: string | null;
|
|
19
19
|
/** Days after this are not selectable. */
|
|
20
|
-
maxDate?:
|
|
20
|
+
maxDate?: string | null;
|
|
21
21
|
/** Called to shift the displayed month by ±1 when arrow navigation runs past its edge. */
|
|
22
22
|
onNavigateMonth?: (delta: 1 | -1) => void;
|
|
23
23
|
}
|
|
@@ -1,26 +1,17 @@
|
|
|
1
|
-
|
|
2
|
-
export declare function getDateFromDayMonthAndYear(day: number, month: number, year: number): Date;
|
|
1
|
+
import { DayParts } from '../utils/day.js';
|
|
3
2
|
export declare function getMonthName(locale: string, year: number, month: number, day: number, short?: boolean): string;
|
|
4
3
|
export declare function getMonthNames(locale?: string): string[];
|
|
5
4
|
export declare function getWeekDays(locale: string, short?: boolean): string[];
|
|
5
|
+
/** 1 (Monday) to 7 (Sunday). */
|
|
6
6
|
export declare function getStartWeekDayOfMonth(month: number, year: number): number;
|
|
7
|
-
/**
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
month: number;
|
|
16
|
-
year: number;
|
|
17
|
-
};
|
|
18
|
-
export declare function getDayMonthAndYearOfDate(date: Date): {
|
|
19
|
-
day: number;
|
|
20
|
-
month: number;
|
|
21
|
-
year: number;
|
|
22
|
-
};
|
|
23
|
-
export declare function getDateString(date: Date): string;
|
|
7
|
+
/** `delta` days from a day, rolling over into the months and years around it. */
|
|
8
|
+
export declare function addDays(day: number, month: number, year: number, delta: number): DayParts;
|
|
9
|
+
/** Today in the user's time zone. */
|
|
10
|
+
export declare function getToday(): DayParts;
|
|
11
|
+
/** A `'YYYY-MM-DD'` day as the field shows it, `dd.mm.yyyy`, or `''` for anything else. */
|
|
12
|
+
export declare function getDateString(value: string | null | undefined): string;
|
|
13
|
+
/** What the field holds, `dd.mm.yyyy`, as `'YYYY-MM-DD'`; `null` while incomplete, or for a day that does not exist. */
|
|
14
|
+
export declare function parseDateString(text: string): string | null;
|
|
24
15
|
export interface DateMaskSelection {
|
|
25
16
|
start: number;
|
|
26
17
|
end: number;
|
|
@@ -3,8 +3,10 @@ import { FormValidator } from '../../services/formValidation/index.js';
|
|
|
3
3
|
import { HtmlProps, SlotClassNames, SlotStyles } from '../types/slots.types.js';
|
|
4
4
|
export type DatePickerSlots = 'root' | 'input' | 'header' | 'monthDropdown' | 'yearDropdown' | 'calendar' | 'clearButton';
|
|
5
5
|
/**
|
|
6
|
-
* `onChange` and `onSelect` report a
|
|
6
|
+
* `onChange` and `onSelect` report a day rather than a DOM event, so the native
|
|
7
7
|
* handlers of those names are dropped instead of being widened to accept both.
|
|
8
|
+
*
|
|
9
|
+
* Every day is a `'YYYY-MM-DD'` string, never a `Date`: see docs/DatePicker.md.
|
|
8
10
|
*/
|
|
9
11
|
export interface DatePickerProps extends Omit<HtmlProps<HTMLDivElement>, 'onChange' | 'onSelect'> {
|
|
10
12
|
/** Class on the root element. */
|
|
@@ -12,33 +14,37 @@ export interface DatePickerProps extends Omit<HtmlProps<HTMLDivElement>, 'onChan
|
|
|
12
14
|
style?: CSSProperties;
|
|
13
15
|
classNames?: SlotClassNames<DatePickerSlots>;
|
|
14
16
|
styles?: SlotStyles<DatePickerSlots>;
|
|
15
|
-
/** Selected
|
|
16
|
-
selected?:
|
|
17
|
+
/** Selected day, `'YYYY-MM-DD'`, controlled. Ignored while a `formValidator` owns the value. */
|
|
18
|
+
selected?: string | null;
|
|
17
19
|
/** Floating label on the input. */
|
|
18
20
|
label?: string;
|
|
19
21
|
/**
|
|
20
22
|
* Called when a day is picked in the calendar, after `onChange`. Picking also
|
|
21
23
|
* closes the picker.
|
|
22
24
|
*/
|
|
23
|
-
onSelect?: (
|
|
25
|
+
onSelect?: (day: string | null) => void;
|
|
24
26
|
/**
|
|
25
27
|
* Called whenever the value changes, whether picked in the calendar or typed
|
|
26
|
-
* into the input. `null` when the field was cleared or holds no valid
|
|
28
|
+
* into the input. `null` when the field was cleared or holds no valid day.
|
|
27
29
|
*/
|
|
28
|
-
onChange?: (
|
|
29
|
-
/**
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
30
|
+
onChange?: (day: string | null) => void;
|
|
31
|
+
/**
|
|
32
|
+
* Hands the value to a validator, which then owns it. See docs/FormValidator.md. The three
|
|
33
|
+
* forms are what TypeScript infers for `new FormValidator<string | null>(null)`,
|
|
34
|
+
* `new FormValidator(null)` and `new FormValidator('')`; a `Date` validator fits none of them.
|
|
35
|
+
*/
|
|
36
|
+
formValidator?: FormValidator<string | null> | FormValidator<string> | FormValidator<null> | null;
|
|
37
|
+
/** Earliest selectable day, `'YYYY-MM-DD'`. Also bounds the year dropdown. */
|
|
38
|
+
minDate?: string | null;
|
|
39
|
+
/** Latest selectable day, `'YYYY-MM-DD'`. Also bounds the year dropdown. */
|
|
40
|
+
maxDate?: string | null;
|
|
35
41
|
/**
|
|
36
42
|
* Start of a highlighted range. Defaults to the selected date, so two pickers
|
|
37
43
|
* sharing a start and an end highlight the span between them.
|
|
38
44
|
*/
|
|
39
|
-
startDate?:
|
|
45
|
+
startDate?: string | null;
|
|
40
46
|
/** End of the highlighted range. */
|
|
41
|
-
endDate?:
|
|
47
|
+
endDate?: string | null;
|
|
42
48
|
/** Render the calendar in place instead of in a popover. */
|
|
43
49
|
isInline?: boolean;
|
|
44
50
|
/** Open the calendar in a modal, with the input read-only. */
|
|
@@ -2,13 +2,10 @@ import { default as React } from 'react';
|
|
|
2
2
|
import { ErrorBoundaryProps, ErrorBoundaryState } from './errorBoundary.types.js';
|
|
3
3
|
declare class ErrorBoundary extends React.Component<ErrorBoundaryProps, ErrorBoundaryState> {
|
|
4
4
|
state: ErrorBoundaryState;
|
|
5
|
-
private copyResetTimeout;
|
|
6
5
|
static getDerivedStateFromError(error: Error): Partial<ErrorBoundaryState>;
|
|
7
6
|
componentDidCatch(error: Error, errorInfo: React.ErrorInfo): void;
|
|
8
7
|
componentDidUpdate(prevProps: ErrorBoundaryProps): void;
|
|
9
|
-
componentWillUnmount(): void;
|
|
10
8
|
private reset;
|
|
11
|
-
private copyStackTrace;
|
|
12
9
|
render(): React.ReactNode;
|
|
13
10
|
}
|
|
14
11
|
export default ErrorBoundary;
|
|
@@ -13,9 +13,9 @@ export interface ErrorBoundaryFallbackProps {
|
|
|
13
13
|
export interface ErrorBoundaryLabels {
|
|
14
14
|
/** Accordion header for the stack trace section. Default: "Stack trace". */
|
|
15
15
|
stackTrace?: string;
|
|
16
|
-
/** Copy button
|
|
16
|
+
/** Copy button's tooltip and accessible name before copying. Default: "Copy". */
|
|
17
17
|
copy?: string;
|
|
18
|
-
/** Copy button
|
|
18
|
+
/** Copy button's tooltip and accessible name right after a successful copy. Default: "Copied". */
|
|
19
19
|
copied?: string;
|
|
20
20
|
/** Reset button label. Default: "Try again". */
|
|
21
21
|
reset?: string;
|
|
@@ -53,5 +53,4 @@ export interface ErrorBoundaryProps extends Omit<HtmlProps, 'title' | 'onError'>
|
|
|
53
53
|
export interface ErrorBoundaryState {
|
|
54
54
|
error: Error | null;
|
|
55
55
|
errorInfo: ErrorInfo | null;
|
|
56
|
-
copied: boolean;
|
|
57
56
|
}
|
|
@@ -11,3 +11,5 @@ export type { UseSwipeDismissOptions, UseSwipeDismissResult } from './useSwipeDi
|
|
|
11
11
|
export { useOverlay } from './useOverlay.js';
|
|
12
12
|
export type { UseOverlayArgs } from './useOverlay.js';
|
|
13
13
|
export { tabbablesIn } from './useFocusBoundary.js';
|
|
14
|
+
export { useClipboard } from './useClipboard.js';
|
|
15
|
+
export type { UseClipboardOptions, UseClipboardResult } from './useClipboard.js';
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export interface UseClipboardOptions {
|
|
2
|
+
/** How long `copied` stays `true` after a successful copy, in ms. Default: 2000. */
|
|
3
|
+
timeout?: number;
|
|
4
|
+
}
|
|
5
|
+
export interface UseClipboardResult {
|
|
6
|
+
/** Writes `text` to the clipboard. Resolves `true` on success, `false` on failure. */
|
|
7
|
+
copy: (text: string) => Promise<boolean>;
|
|
8
|
+
/** `true` for `timeout` ms after a successful copy. */
|
|
9
|
+
copied: boolean;
|
|
10
|
+
/** Why the last copy failed, until the next attempt. */
|
|
11
|
+
error: Error | null;
|
|
12
|
+
/** Clears `copied` and `error` early. */
|
|
13
|
+
reset: () => void;
|
|
14
|
+
}
|
|
15
|
+
export declare function useClipboard({ timeout }?: UseClipboardOptions): UseClipboardResult;
|
|
16
|
+
export default useClipboard;
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import { default as React } from 'react';
|
|
2
2
|
import { SlotClassNames, SlotStyles, HtmlProps } from '../types/slots.types.js';
|
|
3
3
|
import { FormValidator } from '../../services/formValidation/index.js';
|
|
4
|
-
export type InputDropdownSlots = 'root' | 'dropdown' | 'item';
|
|
4
|
+
export type InputDropdownSlots = 'root' | 'dropdown' | 'item' | 'empty';
|
|
5
|
+
export interface InputDropdownLabels {
|
|
6
|
+
/** Shown when nothing matches the typed text and `allowCustomValue` is off (default `No matches`). */
|
|
7
|
+
empty?: string;
|
|
8
|
+
}
|
|
5
9
|
export interface InputDropdownItem {
|
|
6
10
|
label?: string;
|
|
7
11
|
value: string;
|
|
@@ -29,6 +33,8 @@ export interface InputDropdownProps extends Omit<HtmlProps, 'onSelect'> {
|
|
|
29
33
|
onChange?: (value: unknown) => void;
|
|
30
34
|
placeholder?: string;
|
|
31
35
|
readOnly?: boolean;
|
|
36
|
+
/** Overrides the text InputDropdown renders of its own. Merged per key. */
|
|
37
|
+
labels?: InputDropdownLabels;
|
|
32
38
|
className?: string;
|
|
33
39
|
style?: React.CSSProperties;
|
|
34
40
|
classNames?: SlotClassNames<InputDropdownSlots>;
|
|
@@ -20,6 +20,8 @@ export interface MenuAction {
|
|
|
20
20
|
* into a `useHotkeys` map, so the one spelling covers both ends.
|
|
21
21
|
*/
|
|
22
22
|
shortcut?: string;
|
|
23
|
+
/** Extra search terms for `CommandPalette`, which also matches a string `label`. `Menu` ignores them. */
|
|
24
|
+
keywords?: string[];
|
|
23
25
|
disabled?: boolean;
|
|
24
26
|
/** Renders in the destructive colour. For deleting, discarding, revoking. */
|
|
25
27
|
danger?: boolean;
|
|
@@ -24,6 +24,11 @@ export type PopoverSlots = 'root' | 'trigger' | 'floating' | 'panel' | 'arrow' |
|
|
|
24
24
|
export interface PopoverProps extends Omit<HtmlProps, 'content'> {
|
|
25
25
|
/** The trigger element. */
|
|
26
26
|
children?: ReactNode;
|
|
27
|
+
/**
|
|
28
|
+
* Place the panel against this element instead of `children`, for one Popover does not wrap.
|
|
29
|
+
* Open it with `isOpen`; `null` falls back to `children`.
|
|
30
|
+
*/
|
|
31
|
+
anchor?: HTMLElement | null;
|
|
27
32
|
/** The popover body. */
|
|
28
33
|
content?: ReactNode;
|
|
29
34
|
/** Preferred side (default `Bottom`). */
|
|
@@ -9,6 +9,11 @@ interface State {
|
|
|
9
9
|
resolvedVariables: Record<string, string>;
|
|
10
10
|
colorFadeActive: boolean;
|
|
11
11
|
currentThemeColor: string | null;
|
|
12
|
+
/** What `resolvedVariables` was resolved from, to tell a theme change from any other render. */
|
|
13
|
+
resolvedFrom: {
|
|
14
|
+
themes: Theme[] | undefined;
|
|
15
|
+
currentThemeId: string | undefined;
|
|
16
|
+
};
|
|
12
17
|
}
|
|
13
18
|
declare class ThemeProvider extends Component<Props, State> {
|
|
14
19
|
state: State;
|
|
@@ -16,6 +21,7 @@ declare class ThemeProvider extends Component<Props, State> {
|
|
|
16
21
|
private wrapperRef;
|
|
17
22
|
private themeColorMeta;
|
|
18
23
|
private createdThemeColorMeta;
|
|
24
|
+
static getDerivedStateFromProps(props: Props, state: State): Partial<State> | null;
|
|
19
25
|
componentDidMount(): void;
|
|
20
26
|
componentDidUpdate(prevProps: Props, prevState: State): void;
|
|
21
27
|
componentWillUnmount(): void;
|
|
@@ -26,13 +32,8 @@ declare class ThemeProvider extends Component<Props, State> {
|
|
|
26
32
|
* (and removes it again on unmount).
|
|
27
33
|
*/
|
|
28
34
|
private syncThemeColorMeta;
|
|
29
|
-
/**
|
|
30
|
-
|
|
31
|
-
* baseThemeId chain. Returns variables ordered from deepest ancestor to
|
|
32
|
-
* the requested theme so callers can merge in order (later entries win).
|
|
33
|
-
*/
|
|
34
|
-
private resolveChain;
|
|
35
|
-
private applyTheme;
|
|
35
|
+
/** `--primary-color` as the browser resolved it, which may be a `var()` of another variable. */
|
|
36
|
+
private readThemeColor;
|
|
36
37
|
render(): React.JSX.Element;
|
|
37
38
|
}
|
|
38
39
|
export default ThemeProvider;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export interface DayParts {
|
|
2
|
+
year: number;
|
|
3
|
+
/** 1 to 12. */
|
|
4
|
+
month: number;
|
|
5
|
+
day: number;
|
|
6
|
+
}
|
|
7
|
+
export declare function daysInMonth({ year, month }: Pick<DayParts, 'year' | 'month'>): number;
|
|
8
|
+
/** The parts of a `'YYYY-MM-DD'` string, or `null` for anything else, 31 February included. */
|
|
9
|
+
export declare function parseDay(value: unknown): DayParts | null;
|
|
10
|
+
/** `value` itself when it is a `'YYYY-MM-DD'` day that exists, otherwise `null`. */
|
|
11
|
+
export declare function asDay(value: unknown): string | null;
|
|
12
|
+
export declare function formatDay({ year, month, day }: DayParts): string;
|
|
13
|
+
/** The day `date` falls on in the browser's time zone, as `'YYYY-MM-DD'`; `''` for an Invalid Date. */
|
|
14
|
+
export declare function dateToDay(date: Date): string;
|
|
15
|
+
/** The first moment of a `'YYYY-MM-DD'` day in the browser's time zone. An Invalid Date for anything else. */
|
|
16
|
+
export declare function dayToDate(day: string): Date;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { ReactElement } from 'react';
|
|
2
|
+
import { WeatherPartProps } from './weatherIcon.types.js';
|
|
3
|
+
/** Exported so a scene can clip what sits behind the cloud to this same silhouette. */
|
|
4
|
+
export declare const CLOUD_PATH = "M 26.3 62.9 C 15.4 65.0 15.0 48.5 27.8 49.8 C 23.9 43.9 34.2 34.0 43.0 39.6 C 46.0 26.2 73.9 32.0 68.9 46.3 C 85.0 44.3 84.6 64.2 72.4 62.5 Z";
|
|
5
|
+
export declare function Cloud({ className, delayed }: {
|
|
6
|
+
className?: string;
|
|
7
|
+
delayed?: boolean;
|
|
8
|
+
}): ReactElement;
|
|
9
|
+
export declare function Sun({ className }: {
|
|
10
|
+
className?: string;
|
|
11
|
+
}): ReactElement;
|
|
12
|
+
export declare function Moon({ className }: {
|
|
13
|
+
className?: string;
|
|
14
|
+
}): ReactElement;
|
|
15
|
+
export declare enum RainIntensity {
|
|
16
|
+
Light = "light",
|
|
17
|
+
Medium = "medium",
|
|
18
|
+
Heavy = "heavy"
|
|
19
|
+
}
|
|
20
|
+
export declare function Rain({ animated, intensity, }: WeatherPartProps & {
|
|
21
|
+
intensity?: RainIntensity;
|
|
22
|
+
}): ReactElement;
|
|
23
|
+
export declare function Snow({ animated }: WeatherPartProps): ReactElement;
|
|
24
|
+
export declare function Hail({ animated }: WeatherPartProps): ReactElement;
|
|
25
|
+
export declare function Fog(): ReactElement;
|
|
26
|
+
export declare function Lightning(): ReactElement;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { CSSProperties, SVGAttributes } from 'react';
|
|
2
|
+
import { DataProps } from '../types/slots.types.js';
|
|
3
|
+
export declare enum WeatherType {
|
|
4
|
+
Sunny = "sunny",
|
|
5
|
+
ClearNight = "clearNight",
|
|
6
|
+
Cloudy = "cloudy",
|
|
7
|
+
PartlyCloudy = "partlyCloudy",
|
|
8
|
+
PartlyCloudyNight = "partlyCloudyNight",
|
|
9
|
+
RainyLight = "rainyLight",
|
|
10
|
+
Rainy = "rainy",
|
|
11
|
+
RainyHeavy = "rainyHeavy",
|
|
12
|
+
Snowy = "snowy",
|
|
13
|
+
Hail = "hail",
|
|
14
|
+
Foggy = "foggy",
|
|
15
|
+
Thunderstorm = "thunderstorm"
|
|
16
|
+
}
|
|
17
|
+
/** The accessible name of each weather, read out by screen readers. */
|
|
18
|
+
export type WeatherIconLabels = Partial<Record<`${WeatherType}`, string>>;
|
|
19
|
+
/**
|
|
20
|
+
* The root is an `<svg>`, so the native attributes come from `SVGAttributes` rather than
|
|
21
|
+
* `HtmlProps`. Its `type` is the attribute of `<script>` and `<style>`, not of an `<svg>`.
|
|
22
|
+
*/
|
|
23
|
+
export interface WeatherIconProps extends DataProps, Omit<SVGAttributes<SVGSVGElement>, 'type'> {
|
|
24
|
+
/**
|
|
25
|
+
* The weather to draw. Takes the enum or its string value, so an API's own enum with the same
|
|
26
|
+
* values passes as it is.
|
|
27
|
+
*/
|
|
28
|
+
type: WeatherType | `${WeatherType}`;
|
|
29
|
+
/** Width and height, any CSS size. Default `64`. */
|
|
30
|
+
size?: number | string;
|
|
31
|
+
/**
|
|
32
|
+
* Default `true`. `false` draws a still frame, for small or repeated icons where the motion is
|
|
33
|
+
* too small to see but costs the same. Always still under `prefers-reduced-motion`.
|
|
34
|
+
*/
|
|
35
|
+
animated?: boolean;
|
|
36
|
+
/** Text this component renders of its own. */
|
|
37
|
+
labels?: WeatherIconLabels;
|
|
38
|
+
className?: string;
|
|
39
|
+
style?: CSSProperties;
|
|
40
|
+
}
|
|
41
|
+
/** What a falling part needs to know to pick its still frame. */
|
|
42
|
+
export interface WeatherPartProps {
|
|
43
|
+
animated: boolean;
|
|
44
|
+
}
|
|
@@ -31,10 +31,14 @@ export { default as Chip } from './common/chip/index.js';
|
|
|
31
31
|
export * from './common/chip/index.js';
|
|
32
32
|
export { default as ColorPicker } from './common/colorPicker/index.js';
|
|
33
33
|
export * from './common/colorPicker/index.js';
|
|
34
|
+
export { default as CommandPalette } from './common/commandPalette/index.js';
|
|
35
|
+
export * from './common/commandPalette/index.js';
|
|
34
36
|
export { default as ConfigProvider } from './common/configProvider/index.js';
|
|
35
37
|
export * from './common/configProvider/index.js';
|
|
36
38
|
export { default as ConfirmModal } from './common/confirmModal/index.js';
|
|
37
39
|
export * from './common/confirmModal/index.js';
|
|
40
|
+
export { default as CopyButton } from './common/copyButton/index.js';
|
|
41
|
+
export * from './common/copyButton/index.js';
|
|
38
42
|
export { default as DatePicker } from './common/datePicker/index.js';
|
|
39
43
|
export * from './common/datePicker/index.js';
|
|
40
44
|
export { default as Divider } from './common/divider/index.js';
|
|
@@ -146,10 +150,12 @@ export { default as Tree } from './common/tree/index.js';
|
|
|
146
150
|
export * from './common/tree/index.js';
|
|
147
151
|
export { default as VirtualList } from './common/virtualList/index.js';
|
|
148
152
|
export * from './common/virtualList/index.js';
|
|
153
|
+
export { default as WeatherIcon } from './common/weatherIcon/index.js';
|
|
154
|
+
export * from './common/weatherIcon/index.js';
|
|
149
155
|
export { default as Wizard } from './common/wizard/index.js';
|
|
150
156
|
export * from './common/wizard/index.js';
|
|
151
157
|
export * from './common/hooks/index.js';
|
|
152
158
|
export { FormValidator, FormValidatorGroup, Validators, ValidatableComponent, useFormValidator, useFormValidatorGroup, } from './services/formValidation/index.js';
|
|
153
159
|
export type { ValidationError, ValidatorFunction, ErrorParser, FormValidatorGroupOptions, InferGroupValues, MergedValues, } from './services/formValidation/index.js';
|
|
154
160
|
export { mapLocale, setLocale, getLocale } from './services/localization.js';
|
|
155
|
-
export { isNumber, isDate, isISODate, isEmail, isBic, isURL, hasEightPasswordChars, hasOnePasswordLetter, hasOnePasswordDigit, isPassword, } from '@ahrowe/form-validation';
|
|
161
|
+
export { isNumber, isDate, isDay, isISODate, isEmail, isBic, isURL, hasEightPasswordChars, hasOnePasswordLetter, hasOnePasswordDigit, isPassword, } from '@ahrowe/form-validation';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"buttonGroup.module.mjs","names":[],"sources":["../../../../package/common/buttonGroup/buttonGroup.module.pcss"],"sourcesContent":[".buttonGroup {\n display: inline-flex;\n align-items: stretch;\n\n /* Each rule below targets its position with a pseudo-class (:first-child, :last-child, or\n :not()), which contributes extra specificity beyond a plain class selector. That's what\n reliably beats a child component's own base border-radius rule (e.g. Button's), regardless\n of which CSS module happens to load first in the final bundle — a plain \".buttonGroup > *\"\n reset would tie on specificity with Button's own class and depend on load order.\n\n Alongside the direct border-radius reset (for a child whose visible border lives right on\n its own root, e.g. Button), each rule also sets --group-radius-* custom properties. Unlike\n border-radius itself, custom properties inherit through every descendant regardless of\n nesting depth, so a child whose actual border lives on a nested element (e.g. Input's\n `fieldset`, buried inside a `<label>`) can flatten correctly too, as long as that nested\n element's own border-radius reads `var(--group-radius-tl, var(--default-border-radius))`\n etc. instead of hardcoding `var(--default-border-radius)` — see input.module.pcss.\n\n A nested ButtonGroup (role=\"group\") is excluded throughout: it manages its own corners and\n spacing internally, so the outer group only arranges it as a self-contained unit rather than\n reaching into it. */\n > *:not(:first-child):not(:last-child):not([role='group']) {\n border-radius: 0;\n\n --group-radius-tl: 0;\n --group-radius-tr: 0;\n --group-radius-br: 0;\n --group-radius-bl: 0;\n }\n\n > *:hover,\n > *:focus-within {\n z-index: 1;\n }\n\n &:not(&-vertical) {\n /* A separator (e.g. a vertical Divider) is meant to stay visible between two buttons, not\n merge into one of them, so it's excluded from the border-collapsing overlap below — and\n so is whatever comes right after one, since that overlap is only meant to collapse two\n adjacent button borders, not eat into the separator itself. A nested ButtonGroup is\n excluded the same way, and given real spacing instead, rather than being squeezed 1px\n into whatever's next to it. */\n > *:not(:first-child):not([role='separator']):not([role='group']) {\n margin-left: -1px;\n }\n\n /* Matches the specificity of the collapse rule above (three :not()s deep, not two) so this\n reliably wins the override regardless of source order — the collapse rule's own three\n :not()s (:first-child, [role=separator], [role=group]) outweigh an adjacency selector with\n only one, so a fourth, redundant :not() is added here purely to close that gap. The\n trailing :not([role='group']) on both lines also keeps this from matching when the\n following element is itself a nested group — that case must fall through to the dedicated\n 8px group-spacing rule below, not get zeroed. */\n > [role='separator'] + *:not(:first-child):not([role='group']),\n > [role='group'] + *:not(:first-child):not([role='separator']):not([role='group']) {\n margin-left: 0;\n }\n\n > [role='group']:not(:first-child) {\n margin-left: 8px;\n }\n\n > *:first-child:not(:last-child):not([role='group']) {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n\n --group-radius-tr: 0;\n --group-radius-br: 0;\n }\n\n > *:last-child:not(:first-child):not([role='group']) {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n\n --group-radius-tl: 0;\n --group-radius-bl: 0;\n }\n }\n\n &-vertical {\n flex-direction: column;\n\n > *:not(:first-child):not([role='separator']):not([role='group']) {\n margin-top: -1px;\n }\n\n > [role='separator'] + *:not(:first-child):not([role='group']),\n > [role='group'] + *:not(:first-child):not([role='separator']):not([role='group']) {\n margin-top: 0;\n }\n\n > [role='group']:not(:first-child) {\n margin-top: 8px;\n }\n\n > *:first-child:not(:last-child):not([role='group']) {\n border-bottom-left-radius: 0;\n border-bottom-right-radius: 0;\n\n --group-radius-bl: 0;\n --group-radius-br: 0;\n }\n\n > *:last-child:not(:first-child):not([role='group']) {\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n\n --group-radius-tl: 0;\n --group-radius-tr: 0;\n }\n }\n}\n"],"mappings":""}
|
|
1
|
+
{"version":3,"file":"buttonGroup.module.mjs","names":[],"sources":["../../../../package/common/buttonGroup/buttonGroup.module.pcss"],"sourcesContent":[".buttonGroup {\n display: inline-flex;\n align-items: stretch;\n\n /* At a fractional scale two overlapping borders round to different device pixels, so each seam\n keeps one: the earlier child clips its shared 1px, or the next one does while the earlier has\n the focus (docs/ButtonGroup.md). Reset per group so a nested one starts clean. */\n --group-clip-start: initial;\n --group-clip-end: initial;\n\n /* Each rule below targets its position with a pseudo-class (:first-child, :last-child, or\n :not()), which contributes extra specificity beyond a plain class selector. That's what\n reliably beats a child component's own base border-radius rule (e.g. Button's), regardless\n of which CSS module happens to load first in the final bundle — a plain \".buttonGroup > *\"\n reset would tie on specificity with Button's own class and depend on load order.\n\n Alongside the direct border-radius reset (for a child whose visible border lives right on\n its own root, e.g. Button), each rule also sets --group-radius-* custom properties. Unlike\n border-radius itself, custom properties inherit through every descendant regardless of\n nesting depth, so a child whose actual border lives on a nested element (e.g. Input's\n `fieldset`, buried inside a `<label>`) can flatten correctly too, as long as that nested\n element's own border-radius reads `var(--group-radius-tl, var(--default-border-radius))`\n etc. instead of hardcoding `var(--default-border-radius)` — see input.module.pcss.\n\n A nested ButtonGroup (role=\"group\") is excluded throughout: it manages its own corners and\n spacing internally, so the outer group only arranges it as a self-contained unit rather than\n reaching into it. */\n > *:not(:first-child):not(:last-child):not([role='group']) {\n border-radius: 0;\n\n --group-radius-tl: 0;\n --group-radius-tr: 0;\n --group-radius-br: 0;\n --group-radius-bl: 0;\n }\n\n > *:hover,\n > *:focus-within {\n z-index: 1;\n }\n\n &:not(&-vertical) {\n /* A separator (e.g. a vertical Divider) is meant to stay visible between two buttons, not\n merge into one of them, so it's excluded from the border-collapsing overlap below — and\n so is whatever comes right after one, since that overlap is only meant to collapse two\n adjacent button borders, not eat into the separator itself. A nested ButtonGroup is\n excluded the same way, and given real spacing instead, rather than being squeezed 1px\n into whatever's next to it. */\n > *:not(:first-child):not([role='separator']):not([role='group']) {\n margin-left: -1px;\n }\n\n > *:not([role='separator']):not([role='group']):has(+ :not([role='separator']):not([role='group'])) {\n --group-clip-end: 1px;\n\n clip-path: inset(-100vmax var(--group-clip-end, -100vmax) -100vmax var(--group-clip-start, -100vmax));\n }\n\n > *:not([role='separator']):not([role='group']):has(+ :not([role='separator']):not([role='group'])):focus-within {\n --group-clip-end: initial;\n }\n\n > :focus-within:not([role='separator']):not([role='group']) + *:not([role='separator']):not([role='group']) {\n --group-clip-start: 1px;\n\n clip-path: inset(-100vmax var(--group-clip-end, -100vmax) -100vmax var(--group-clip-start, -100vmax));\n }\n\n /* Matches the specificity of the collapse rule above (three :not()s deep, not two) so this\n reliably wins the override regardless of source order — the collapse rule's own three\n :not()s (:first-child, [role=separator], [role=group]) outweigh an adjacency selector with\n only one, so a fourth, redundant :not() is added here purely to close that gap. The\n trailing :not([role='group']) on both lines also keeps this from matching when the\n following element is itself a nested group — that case must fall through to the dedicated\n 8px group-spacing rule below, not get zeroed. */\n > [role='separator'] + *:not(:first-child):not([role='group']),\n > [role='group'] + *:not(:first-child):not([role='separator']):not([role='group']) {\n margin-left: 0;\n }\n\n > [role='group']:not(:first-child) {\n margin-left: 8px;\n }\n\n > *:first-child:not(:last-child):not([role='group']) {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n\n --group-radius-tr: 0;\n --group-radius-br: 0;\n }\n\n > *:last-child:not(:first-child):not([role='group']) {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n\n --group-radius-tl: 0;\n --group-radius-bl: 0;\n }\n }\n\n &-vertical {\n flex-direction: column;\n\n > *:not(:first-child):not([role='separator']):not([role='group']) {\n margin-top: -1px;\n }\n\n > *:not([role='separator']):not([role='group']):has(+ :not([role='separator']):not([role='group'])) {\n --group-clip-end: 1px;\n\n clip-path: inset(var(--group-clip-start, -100vmax) -100vmax var(--group-clip-end, -100vmax) -100vmax);\n }\n\n > *:not([role='separator']):not([role='group']):has(+ :not([role='separator']):not([role='group'])):focus-within {\n --group-clip-end: initial;\n }\n\n > :focus-within:not([role='separator']):not([role='group']) + *:not([role='separator']):not([role='group']) {\n --group-clip-start: 1px;\n\n clip-path: inset(var(--group-clip-start, -100vmax) -100vmax var(--group-clip-end, -100vmax) -100vmax);\n }\n\n > [role='separator'] + *:not(:first-child):not([role='group']),\n > [role='group'] + *:not(:first-child):not([role='separator']):not([role='group']) {\n margin-top: 0;\n }\n\n > [role='group']:not(:first-child) {\n margin-top: 8px;\n }\n\n > *:first-child:not(:last-child):not([role='group']) {\n border-bottom-left-radius: 0;\n border-bottom-right-radius: 0;\n\n --group-radius-bl: 0;\n --group-radius-br: 0;\n }\n\n > *:last-child:not(:first-child):not([role='group']) {\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n\n --group-radius-tl: 0;\n --group-radius-tr: 0;\n }\n }\n}\n"],"mappings":""}
|