@leabankab/component-library 5.6.1

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.
Files changed (190) hide show
  1. package/CHANGELOG.md +408 -0
  2. package/README.md +22 -0
  3. package/dist/bankidlogo.png +0 -0
  4. package/dist/component-library.es.js +6143 -0
  5. package/dist/component-library.es.js.map +1 -0
  6. package/dist/component-library.umd.js +35 -0
  7. package/dist/component-library.umd.js.map +1 -0
  8. package/dist/components/animations/icons/index.d.ts +1 -0
  9. package/dist/components/animations/icons/status-icon.d.ts +21 -0
  10. package/dist/components/animations/illustrations/check-animation.d.ts +12 -0
  11. package/dist/components/animations/illustrations/index.d.ts +3 -0
  12. package/dist/components/animations/illustrations/pulse-animation.d.ts +12 -0
  13. package/dist/components/animations/illustrations/status-animation.d.ts +32 -0
  14. package/dist/components/animations/index.d.ts +2 -0
  15. package/dist/components/animations/shared.d.ts +67 -0
  16. package/dist/components/animations/use-animation-labels.d.ts +6 -0
  17. package/dist/components/buttons/action-button.d.ts +18 -0
  18. package/dist/components/buttons/button.d.ts +20 -0
  19. package/dist/components/buttons/download-trigger.d.ts +33 -0
  20. package/dist/components/buttons/icon-button.d.ts +12 -0
  21. package/dist/components/buttons/index.d.ts +5 -0
  22. package/dist/components/buttons/skip-link.d.ts +6 -0
  23. package/dist/components/buttons/use-download-labels.d.ts +5 -0
  24. package/dist/components/data-display/card.d.ts +6 -0
  25. package/dist/components/data-display/chip.d.ts +11 -0
  26. package/dist/components/data-display/data-field.d.ts +12 -0
  27. package/dist/components/data-display/index.d.ts +4 -0
  28. package/dist/components/data-display/tooltip.d.ts +37 -0
  29. package/dist/components/data-display/use-chip-labels.d.ts +6 -0
  30. package/dist/components/dev-panel/dev-panel-country.d.ts +26 -0
  31. package/dist/components/dev-panel/dev-panel-flow.d.ts +28 -0
  32. package/dist/components/dev-panel/dev-panel-footer.d.ts +26 -0
  33. package/dist/components/dev-panel/dev-panel-payload.d.ts +47 -0
  34. package/dist/components/dev-panel/dev-panel-status.d.ts +31 -0
  35. package/dist/components/dev-panel/dev-panel-step-state.d.ts +28 -0
  36. package/dist/components/dev-panel/dev-panel-steps.d.ts +39 -0
  37. package/dist/components/dev-panel/dev-panel-variant.d.ts +21 -0
  38. package/dist/components/dev-panel/dev-panel.d.ts +61 -0
  39. package/dist/components/dev-panel/index.d.ts +9 -0
  40. package/dist/components/dev-panel/json-highlight.d.ts +15 -0
  41. package/dist/components/dev-panel/segmented-control.d.ts +38 -0
  42. package/dist/components/dev-panel/use-copy.d.ts +9 -0
  43. package/dist/components/dev-panel/use-dev-panel-labels.d.ts +7 -0
  44. package/dist/components/dev-panel/use-roving-radio.d.ts +34 -0
  45. package/dist/components/feedback/alert.d.ts +27 -0
  46. package/dist/components/feedback/dialog.d.ts +22 -0
  47. package/dist/components/feedback/drawer.d.ts +22 -0
  48. package/dist/components/feedback/index.d.ts +3 -0
  49. package/dist/components/feedback/use-close-label.d.ts +6 -0
  50. package/dist/components/form/autocomplete.d.ts +71 -0
  51. package/dist/components/form/checkbox.d.ts +12 -0
  52. package/dist/components/form/datepicker/calendar-header.d.ts +12 -0
  53. package/dist/components/form/datepicker/datepicker.d.ts +99 -0
  54. package/dist/components/form/datepicker/drawer-toolbar.d.ts +17 -0
  55. package/dist/components/form/datepicker/index.d.ts +1 -0
  56. package/dist/components/form/datepicker/use-calendar-header-labels.d.ts +8 -0
  57. package/dist/components/form/datepicker/use-datepicker-title-labels.d.ts +5 -0
  58. package/dist/components/form/datepicker/use-view-toggle-labels.d.ts +7 -0
  59. package/dist/components/form/datepicker/view-renderers.d.ts +10 -0
  60. package/dist/components/form/datepicker/view-toggle.d.ts +21 -0
  61. package/dist/components/form/email-input.d.ts +35 -0
  62. package/dist/components/form/fields/autocomplete-field.d.ts +17 -0
  63. package/dist/components/form/fields/boolean-radio-field.d.ts +3 -0
  64. package/dist/components/form/fields/checkbox-field.d.ts +12 -0
  65. package/dist/components/form/fields/datepicker-field.d.ts +9 -0
  66. package/dist/components/form/fields/email-field.d.ts +10 -0
  67. package/dist/components/form/fields/field-types.d.ts +18 -0
  68. package/dist/components/form/fields/index.d.ts +14 -0
  69. package/dist/components/form/fields/input-field.d.ts +9 -0
  70. package/dist/components/form/fields/multi-select-field.d.ts +9 -0
  71. package/dist/components/form/fields/number-field.d.ts +10 -0
  72. package/dist/components/form/fields/phone-number-field.d.ts +11 -0
  73. package/dist/components/form/fields/radio-card-field.d.ts +22 -0
  74. package/dist/components/form/fields/radio-field.d.ts +16 -0
  75. package/dist/components/form/fields/select-field.d.ts +9 -0
  76. package/dist/components/form/fields/use-field-control.d.ts +6 -0
  77. package/dist/components/form/fields/use-tooltip-trigger-labels.d.ts +5 -0
  78. package/dist/components/form/form-control/form-control-context.d.ts +35 -0
  79. package/dist/components/form/form-control/form-control-label.d.ts +1 -0
  80. package/dist/components/form/form-control/form-control.d.ts +13 -0
  81. package/dist/components/form/form-control/form-helper-text.d.ts +9 -0
  82. package/dist/components/form/form-control/form-label.d.ts +9 -0
  83. package/dist/components/form/form-control/index.d.ts +5 -0
  84. package/dist/components/form/index.d.ts +18 -0
  85. package/dist/components/form/input-label.d.ts +9 -0
  86. package/dist/components/form/input.d.ts +19 -0
  87. package/dist/components/form/multi-select.d.ts +32 -0
  88. package/dist/components/form/number-input.d.ts +52 -0
  89. package/dist/components/form/phone-number-input/countries.d.ts +33 -0
  90. package/dist/components/form/phone-number-input/index.d.ts +2 -0
  91. package/dist/components/form/phone-number-input/phone-number-input.d.ts +53 -0
  92. package/dist/components/form/radio-card.d.ts +77 -0
  93. package/dist/components/form/radio-circle.d.ts +19 -0
  94. package/dist/components/form/radio.d.ts +36 -0
  95. package/dist/components/form/select.d.ts +46 -0
  96. package/dist/components/form/slider.d.ts +23 -0
  97. package/dist/components/form/use-autocomplete-labels.d.ts +19 -0
  98. package/dist/components/index.d.ts +11 -0
  99. package/dist/components/navigation/form-stepper.d.ts +63 -0
  100. package/dist/components/navigation/index.d.ts +4 -0
  101. package/dist/components/navigation/progress-circle.d.ts +34 -0
  102. package/dist/components/navigation/tabs.d.ts +79 -0
  103. package/dist/components/navigation/use-stepper-labels.d.ts +7 -0
  104. package/dist/components/surfaces/accordion.d.ts +15 -0
  105. package/dist/components/surfaces/index.d.ts +1 -0
  106. package/dist/components/typography/index.d.ts +3 -0
  107. package/dist/components/typography/link.d.ts +23 -0
  108. package/dist/components/typography/lists.d.ts +54 -0
  109. package/dist/components/typography/text.d.ts +18 -0
  110. package/dist/components/ui/brand-divider.d.ts +6 -0
  111. package/dist/components/ui/index.d.ts +1 -0
  112. package/dist/creditcard.png +0 -0
  113. package/dist/favicon.ico +0 -0
  114. package/dist/hooks/country/countries.d.ts +8 -0
  115. package/dist/hooks/country/country-context.d.ts +20 -0
  116. package/dist/hooks/index.d.ts +6 -0
  117. package/dist/hooks/use-format-currency.d.ts +9 -0
  118. package/dist/hooks/use-format-date.d.ts +4 -0
  119. package/dist/hooks/use-format-number.d.ts +10 -0
  120. package/dist/hooks/validation/index.d.ts +1 -0
  121. package/dist/hooks/validation/use-validation.d.ts +21 -0
  122. package/dist/i18n/create-translation.d.ts +28 -0
  123. package/dist/i18n/index.d.ts +3 -0
  124. package/dist/i18n/language-context.d.ts +9 -0
  125. package/dist/i18n/languages.d.ts +9 -0
  126. package/dist/index.d.ts +9 -0
  127. package/dist/leabank-logo-square.png +0 -0
  128. package/dist/leabank-logo.png +0 -0
  129. package/dist/provider/index.d.ts +1 -0
  130. package/dist/provider/lea-provider.d.ts +16 -0
  131. package/dist/success-icon.png +0 -0
  132. package/dist/theme/components/accordion.theme.d.ts +7 -0
  133. package/dist/theme/components/action-button.theme.d.ts +45 -0
  134. package/dist/theme/components/alert.theme.d.ts +2 -0
  135. package/dist/theme/components/autocomplete.theme.d.ts +2 -0
  136. package/dist/theme/components/baseline-css.d.ts +2 -0
  137. package/dist/theme/components/button.theme.d.ts +2 -0
  138. package/dist/theme/components/card.theme.d.ts +2 -0
  139. package/dist/theme/components/checkbox.theme.d.ts +2 -0
  140. package/dist/theme/components/chip.theme.d.ts +2 -0
  141. package/dist/theme/components/date-picker.theme.d.ts +15 -0
  142. package/dist/theme/components/dev-panel.theme.d.ts +95 -0
  143. package/dist/theme/components/dialog.theme.d.ts +2 -0
  144. package/dist/theme/components/drawer.theme.d.ts +4 -0
  145. package/dist/theme/components/field-base.d.ts +31 -0
  146. package/dist/theme/components/form-control-label.theme.d.ts +2 -0
  147. package/dist/theme/components/form-control.theme.d.ts +2 -0
  148. package/dist/theme/components/icon-button.theme.d.ts +2 -0
  149. package/dist/theme/components/index.d.ts +2 -0
  150. package/dist/theme/components/input.theme.d.ts +3 -0
  151. package/dist/theme/components/link.theme.d.ts +2 -0
  152. package/dist/theme/components/menu-item.theme.d.ts +2 -0
  153. package/dist/theme/components/number-input.theme.d.ts +23 -0
  154. package/dist/theme/components/phone-number-input.theme.d.ts +43 -0
  155. package/dist/theme/components/radio.theme.d.ts +2 -0
  156. package/dist/theme/components/select.theme.d.ts +2 -0
  157. package/dist/theme/components/slider.theme.d.ts +2 -0
  158. package/dist/theme/components/tabs.theme.d.ts +34 -0
  159. package/dist/theme/components/tooltip.theme.d.ts +110 -0
  160. package/dist/theme/components/typography.theme.d.ts +2 -0
  161. package/dist/theme/index.d.ts +6 -0
  162. package/dist/theme/mui-augmentation.d.ts +147 -0
  163. package/dist/theme/sx-config.d.ts +10 -0
  164. package/dist/theme/token-types.d.ts +11 -0
  165. package/dist/theme/tokens/colors.d.ts +95 -0
  166. package/dist/theme/tokens/font-sizes.d.ts +12 -0
  167. package/dist/theme/tokens/font-weights.d.ts +9 -0
  168. package/dist/theme/tokens/index.d.ts +9 -0
  169. package/dist/theme/tokens/palette.d.ts +2 -0
  170. package/dist/theme/tokens/shadows.d.ts +9 -0
  171. package/dist/theme/tokens/shape.d.ts +12 -0
  172. package/dist/theme/tokens/spacing.d.ts +1 -0
  173. package/dist/theme/tokens/transitions.d.ts +10 -0
  174. package/dist/theme/tokens/typography.d.ts +43 -0
  175. package/dist/theme/types.d.ts +80 -0
  176. package/dist/theme/utils/focus-visible-styles.d.ts +6 -0
  177. package/dist/theme/utils/index.d.ts +1 -0
  178. package/dist/utils/downloadFile.d.ts +4 -0
  179. package/dist/utils/formatDecimal.d.ts +16 -0
  180. package/dist/utils/formatDecimalString.d.ts +12 -0
  181. package/dist/utils/formatPercentage.d.ts +1 -0
  182. package/dist/utils/index.d.ts +5 -0
  183. package/dist/utils/parseExpirationDate.d.ts +4 -0
  184. package/dist/validation/bank-account.d.ts +29 -0
  185. package/dist/validation/email.d.ts +24 -0
  186. package/dist/validation/index.d.ts +5 -0
  187. package/dist/validation/national-id.d.ts +30 -0
  188. package/dist/validation/phone.d.ts +16 -0
  189. package/dist/validation/types.d.ts +10 -0
  190. package/package.json +107 -0
@@ -0,0 +1,10 @@
1
+ import { FieldValues } from 'react-hook-form';
2
+ import { EmailInputProps } from '../email-input';
3
+ import { BaseFieldProps } from './field-types';
4
+ export type EmailFieldProps<T extends FieldValues> = BaseFieldProps<T> & Omit<EmailInputProps, "name" | "value" | "defaultValue" | "onChange" | "error">;
5
+ /**
6
+ * `EmailInput` (with `@` domain autocomplete) connected to react-hook-form via
7
+ * `Controller`. Reads `control` from the nearest `FormProvider` when the prop is
8
+ * omitted.
9
+ */
10
+ export declare const EmailField: <T extends FieldValues>({ name, control, rules, disabled, label, helperText, ...rest }: EmailFieldProps<T>) => import("react").JSX.Element;
@@ -0,0 +1,18 @@
1
+ import { ReactNode } from 'react';
2
+ import { Control, FieldPath, FieldValues, RegisterOptions } from 'react-hook-form';
3
+ export interface BaseFieldProps<T extends FieldValues> {
4
+ name: FieldPath<T>;
5
+ control?: Control<T>;
6
+ rules?: RegisterOptions<T, FieldPath<T>>;
7
+ disabled?: boolean;
8
+ }
9
+ export type FieldOption = {
10
+ value: string;
11
+ label: ReactNode;
12
+ };
13
+ export type FieldValueTransform = {
14
+ /** Maps the form value to the string the control displays. */
15
+ format?: (value: unknown) => string;
16
+ /** Maps the control's string value back to the form value. */
17
+ parse?: (value: string) => unknown;
18
+ };
@@ -0,0 +1,14 @@
1
+ export * from './autocomplete-field';
2
+ export * from './boolean-radio-field';
3
+ export * from './checkbox-field';
4
+ export * from './datepicker-field';
5
+ export * from './email-field';
6
+ export * from './field-types';
7
+ export * from './input-field';
8
+ export * from './multi-select-field';
9
+ export * from './number-field';
10
+ export * from './phone-number-field';
11
+ export * from './radio-card-field';
12
+ export * from './radio-field';
13
+ export * from './select-field';
14
+ export * from './use-field-control';
@@ -0,0 +1,9 @@
1
+ import { FieldValues } from 'react-hook-form';
2
+ import { InputProps } from '../input';
3
+ import { BaseFieldProps } from './field-types';
4
+ export type InputFieldProps<T extends FieldValues> = BaseFieldProps<T> & Omit<InputProps, "name" | "value" | "defaultValue" | "error">;
5
+ /**
6
+ * `Input` connected to react-hook-form via `Controller`. Reads `control` from
7
+ * the nearest `FormProvider` when the prop is omitted.
8
+ */
9
+ export declare const InputField: <T extends FieldValues>({ name, control, rules, disabled, label, helperText, ...rest }: InputFieldProps<T>) => import("react").JSX.Element;
@@ -0,0 +1,9 @@
1
+ import { FieldValues } from 'react-hook-form';
2
+ import { MultiSelectProps } from '../multi-select';
3
+ import { BaseFieldProps } from './field-types';
4
+ export type MultiSelectFieldProps<T extends FieldValues> = BaseFieldProps<T> & Omit<MultiSelectProps, "name" | "value" | "defaultValue" | "error">;
5
+ /**
6
+ * `MultiSelect` connected to react-hook-form via `Controller`. Reads `control` from
7
+ * the nearest `FormProvider` when the prop is omitted.
8
+ */
9
+ export declare const MultiSelectField: <T extends FieldValues>({ name, control, rules, disabled, label, helperText, options, ...rest }: MultiSelectFieldProps<T>) => import("react").JSX.Element;
@@ -0,0 +1,10 @@
1
+ import { FieldValues } from 'react-hook-form';
2
+ import { NumberInputProps } from '../number-input';
3
+ import { BaseFieldProps } from './field-types';
4
+ export type NumberFieldProps<T extends FieldValues> = BaseFieldProps<T> & Omit<NumberInputProps, "name" | "value" | "defaultValue" | "error" | "onValueChange">;
5
+ /**
6
+ * `NumberInput` connected to react-hook-form via `Controller`. Reads `control`
7
+ * from the nearest `FormProvider` when the prop is omitted. The form value is
8
+ * the raw `number | null` from the field.
9
+ */
10
+ export declare const NumberField: <T extends FieldValues>({ name, control, rules, disabled, label, helperText, ...rest }: NumberFieldProps<T>) => import("react").JSX.Element;
@@ -0,0 +1,11 @@
1
+ import { FieldValues } from 'react-hook-form';
2
+ import { PhoneNumberInputProps } from '../phone-number-input';
3
+ import { BaseFieldProps } from './field-types';
4
+ export type PhoneNumberFieldProps<T extends FieldValues> = BaseFieldProps<T> & Omit<PhoneNumberInputProps, "name" | "value" | "defaultValue" | "onChange" | "error">;
5
+ /**
6
+ * `PhoneNumberInput` connected to react-hook-form via `Controller`. Reads
7
+ * `control` from the nearest `FormProvider` when the prop is omitted. The form
8
+ * value is the formatted national number string; pass `defaultCountry` (or a
9
+ * controlled `country` + `onCountryChange`) to drive the country.
10
+ */
11
+ export declare const PhoneNumberField: <T extends FieldValues>({ name, control, rules, disabled, label, helperText, ...rest }: PhoneNumberFieldProps<T>) => import("react").JSX.Element;
@@ -0,0 +1,22 @@
1
+ import { ReactNode } from 'react';
2
+ import { FieldValues } from 'react-hook-form';
3
+ import { RadioGroupProps } from '../radio';
4
+ import { BaseFieldProps, FieldOption, FieldValueTransform } from './field-types';
5
+ export type RadioCardFieldProps<T extends FieldValues> = BaseFieldProps<T> & FieldValueTransform & {
6
+ label: ReactNode;
7
+ options: FieldOption[];
8
+ /** CSS grid-template-columns for the option layout. Defaults to two equal columns. */
9
+ gridColumns?: string;
10
+ /** Size passed to each `RadioCard`. */
11
+ cardSize?: "sm" | "lg";
12
+ /** Tooltip content to display when hovering over the field. */
13
+ tooltip?: ReactNode;
14
+ } & Omit<RadioGroupProps, "value" | "onChange" | "name" | "defaultValue">;
15
+ /**
16
+ * `RadioGroup` of `RadioCard` options connected to react-hook-form via
17
+ * `Controller`. Reads `control` from the nearest `FormProvider` when the prop
18
+ * is omitted.
19
+ *
20
+ * Pass optional `format` / `parse` to coerce values (e.g. boolean <-> string).
21
+ */
22
+ export declare const RadioCardField: <T extends FieldValues>({ name, control, rules, disabled, label, options, format, parse, gridColumns, cardSize, tooltip, size, ...rest }: RadioCardFieldProps<T>) => import("react").JSX.Element;
@@ -0,0 +1,16 @@
1
+ import { ReactNode } from 'react';
2
+ import { FieldValues } from 'react-hook-form';
3
+ import { RadioGroupProps } from '../radio';
4
+ import { BaseFieldProps, FieldOption, FieldValueTransform } from './field-types';
5
+ export type RadioFieldProps<T extends FieldValues> = BaseFieldProps<T> & FieldValueTransform & {
6
+ label: ReactNode;
7
+ options: FieldOption[];
8
+ } & Omit<RadioGroupProps, "value" | "onChange" | "name" | "defaultValue">;
9
+ /**
10
+ * `RadioGroup` connected to react-hook-form via `Controller`, rendering each
11
+ * option as a `FormControlLabel` + `Radio`. Reads `control` from the nearest
12
+ * `FormProvider` when the prop is omitted.
13
+ *
14
+ * Pass optional `format` / `parse` to coerce values (e.g. boolean <-> string).
15
+ */
16
+ export declare const RadioField: <T extends FieldValues>({ name, control, rules, disabled, label, options, format, parse, size, ...rest }: RadioFieldProps<T>) => import("react").JSX.Element;
@@ -0,0 +1,9 @@
1
+ import { FieldValues } from 'react-hook-form';
2
+ import { SelectProps } from '../select';
3
+ import { BaseFieldProps } from './field-types';
4
+ export type SelectFieldProps<T extends FieldValues> = BaseFieldProps<T> & Omit<SelectProps, "name" | "value" | "defaultValue" | "error">;
5
+ /**
6
+ * `Select` connected to react-hook-form via `Controller`. Reads `control` from
7
+ * the nearest `FormProvider` when the prop is omitted.
8
+ */
9
+ export declare const SelectField: <T extends FieldValues>({ name, control, rules, disabled, label, helperText, options, children, ...rest }: SelectFieldProps<T>) => import("react").JSX.Element;
@@ -0,0 +1,6 @@
1
+ import { Control, FieldValues } from 'react-hook-form';
2
+ /**
3
+ * Resolves the `control` instance for a field component. Uses the explicit
4
+ * `control` prop when provided, otherwise reads from the nearest `FormProvider`.
5
+ */
6
+ export declare function useResolvedControl<T extends FieldValues>(control?: Control<T>): Control<T>;
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Translated accessible name for the info trigger a field renders next to its
3
+ * label when given a `tooltip`.
4
+ */
5
+ export declare const useTooltipTriggerLabels: () => Record<"moreInformation", string>;
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Ids shared between a `FormControl` and its label / control / helper text so
3
+ * they stay wired together for assistive technology without the consumer ever
4
+ * writing `htmlFor` or `aria-describedby` by hand.
5
+ */
6
+ export interface FormFieldIds {
7
+ /** Id of the focusable control (input / select). */
8
+ control: string;
9
+ /** Id of the label element. */
10
+ label: string;
11
+ /** Id of the helper text element. */
12
+ helperText: string;
13
+ }
14
+ export interface FormFieldContextValue {
15
+ ids: FormFieldIds;
16
+ /** Whether a `FormHelperText` is currently rendered, so the control knows to link it. */
17
+ hasHelperText: boolean;
18
+ /** Called by `FormHelperText` on mount / unmount to register its presence. */
19
+ setHasHelperText: (present: boolean) => void;
20
+ /**
21
+ * Whether the control currently holds a value that should float the label
22
+ * even when a start adornment is present (e.g. multi-select chips). A plain
23
+ * leading icon leaves this `false` so it doesn't float the label on its own.
24
+ */
25
+ hasValue: boolean;
26
+ /** Called by a value-bearing control to keep `hasValue` in sync. */
27
+ setHasValue: (present: boolean) => void;
28
+ }
29
+ export declare const FormFieldProvider: import('react').Provider<FormFieldContextValue | null>;
30
+ /**
31
+ * Reads the field context provided by the surrounding `FormControl`. Returns
32
+ * `null` when a control is rendered outside our `FormControl`, which lets a
33
+ * standalone control provision its own wrapper and ids.
34
+ */
35
+ export declare const useFormField: () => FormFieldContextValue | null;
@@ -0,0 +1 @@
1
+ export { FormControlLabel, type FormControlLabelProps, } from '@mui/material';
@@ -0,0 +1,13 @@
1
+ import { FormControlProps } from '@mui/material';
2
+ export type { FormControlProps };
3
+ /**
4
+ * Wrapper around MUI's `FormControl` that generates a unique base id (via
5
+ * `useId`, overridable with the `id` prop) and shares the derived label /
6
+ * control / helper-text ids with its children through context. This lets
7
+ * `Input`, `Select`, `InputLabel` and `FormHelperText` wire `htmlFor`, `id` and
8
+ * `aria-describedby` automatically — the consumer never writes them.
9
+ *
10
+ * MUI's own `FormControl` context still propagates `error` / `required` /
11
+ * `disabled` / focused state to children; we only layer the ids on top.
12
+ */
13
+ export declare const FormControl: ({ id, fullWidth, focused: focusedProp, onFocus, onBlur, children, ...rest }: FormControlProps) => import("react").JSX.Element;
@@ -0,0 +1,9 @@
1
+ import { FormHelperTextProps } from '@mui/material';
2
+ export type { FormHelperTextProps };
3
+ /**
4
+ * Supplementary / error text for a field. When rendered inside our
5
+ * `FormControl` it takes the helper-text id from context and registers its
6
+ * presence, so the control links to it via `aria-describedby` automatically.
7
+ * Pass `error` to render it in the error colour.
8
+ */
9
+ export declare const FormHelperText: (props: FormHelperTextProps) => import("react").JSX.Element;
@@ -0,0 +1,9 @@
1
+ import { FormLabelProps } from '@mui/material';
2
+ /**
3
+ * Group label for non-floating controls (e.g. a `RadioGroup`). When rendered
4
+ * inside our `FormControl` it claims the shared label id, so a sibling
5
+ * `RadioGroup` can point its `aria-labelledby` at it automatically — the
6
+ * consumer never wires the ids by hand. Reads required / error / focus state
7
+ * from the surrounding `FormControl` like MUI's own `FormLabel`.
8
+ */
9
+ export declare const FormLabel: (props: FormLabelProps) => import("react").JSX.Element;
@@ -0,0 +1,5 @@
1
+ export * from './form-control';
2
+ export * from './form-control-context';
3
+ export * from './form-control-label';
4
+ export * from './form-label';
5
+ export * from './form-helper-text';
@@ -0,0 +1,18 @@
1
+ export * from './autocomplete';
2
+ export * from './checkbox';
3
+ export * from './datepicker';
4
+ export * from './email-input';
5
+ export * from './fields';
6
+ export * from './form-control';
7
+ export * from './form-control/form-helper-text';
8
+ export * from './input';
9
+ export * from './input-label';
10
+ export * from './multi-select';
11
+ export * from './number-input';
12
+ export * from './phone-number-input';
13
+ export * from './radio';
14
+ export * from './radio-card';
15
+ export * from './radio-circle';
16
+ export * from './select';
17
+ export * from './slider';
18
+ export { FormControlLabel, InputAdornment, type FormControlLabelProps, type InputAdornmentProps, } from '@mui/material';
@@ -0,0 +1,9 @@
1
+ import { InputLabelProps } from '@mui/material';
2
+ export type { InputLabelProps };
3
+ /**
4
+ * Floating label for a field. When rendered inside our `FormControl` it links
5
+ * itself to the control automatically via `htmlFor` / `id`, so the consumer
6
+ * never has to wire them. MUI appends the required asterisk and reads focus /
7
+ * error / required state from the surrounding `FormControl` on its own.
8
+ */
9
+ export declare const InputLabel: (props: InputLabelProps) => import("react").JSX.Element;
@@ -0,0 +1,19 @@
1
+ import { OutlinedInputProps } from '@mui/material';
2
+ import { ReactNode } from 'react';
3
+ export type InputProps = OutlinedInputProps & {
4
+ /** Floating label. Rendered as an `InputLabel` and linked automatically. */
5
+ label?: ReactNode;
6
+ /** Helper / error text shown below the control and linked via `aria-describedby`. */
7
+ helperText?: ReactNode;
8
+ };
9
+ /**
10
+ * Text input built on MUI's `OutlinedInput`.
11
+ *
12
+ * Works two ways:
13
+ * - **Standalone (all-in-one):** pass `label` / `helperText` and it renders its
14
+ * own `FormControl`, label and helper text, generating and wiring all ids for
15
+ * you. Pass `multiline` (+ `minRows`) for a textarea.
16
+ * - **Composed:** drop it inside a `FormControl` next to `InputLabel` /
17
+ * `FormHelperText` and it picks up the shared ids from context.
18
+ */
19
+ export declare const Input: import('react').ForwardRefExoticComponent<Omit<InputProps, "ref"> & import('react').RefAttributes<HTMLInputElement>>;
@@ -0,0 +1,32 @@
1
+ import { SelectChangeEvent } from '@mui/material';
2
+ import { ReactNode } from 'react';
3
+ import { SelectOption, SelectProps } from './select';
4
+ export type MultiSelectProps = Omit<SelectProps, "multiple" | "value" | "defaultValue" | "onChange" | "renderValue" | "children"> & {
5
+ /** Options rendered as checkbox menu items. */
6
+ options: SelectOption[];
7
+ /** Currently selected values (controlled). */
8
+ value?: string[];
9
+ /** Initially selected values (uncontrolled). */
10
+ defaultValue?: string[];
11
+ /** Called with the next array of selected values. */
12
+ onChange?: (value: string[], event: SelectChangeEvent<string[]>) => void;
13
+ /** Minimum number of values that must stay selected. @default 1 */
14
+ min?: number;
15
+ /** Maximum number of values that can be selected. Unlimited when omitted. */
16
+ max?: number;
17
+ /** Override how the selected values are summarised in the closed control. */
18
+ renderValue?: (selected: string[]) => ReactNode;
19
+ };
20
+ /**
21
+ * Multi-select built on our `Select` (so it inherits the auto-wired ids and the
22
+ * standalone / composed `FormControl` behaviour). Each option renders as a
23
+ * checkbox menu item, and the closed control shows the selection as removable
24
+ * chips by default.
25
+ *
26
+ * The selection is bounded by `min` (default 1, so the last value can't be
27
+ * removed) and `max` (unlimited by default): options that would breach either
28
+ * bound are disabled, and the constraints are also enforced on change.
29
+ *
30
+ * Works controlled (`value`) or uncontrolled (`defaultValue`).
31
+ */
32
+ export declare const MultiSelect: import('react').ForwardRefExoticComponent<Omit<MultiSelectProps, "ref"> & import('react').RefAttributes<HTMLDivElement>>;
@@ -0,0 +1,52 @@
1
+ import { NumberField as BaseNumberField } from '@base-ui/react/number-field';
2
+ import { ReactNode } from 'react';
3
+ export type NumberInputProps = BaseNumberField.Root.Props & {
4
+ /** Floating label. Rendered as an `InputLabel` and linked automatically. */
5
+ label?: ReactNode;
6
+ /** Where the label sits when this component renders one itself. @default "inside" */
7
+ labelPlacement?: "inside" | "outside";
8
+ /** Helper / error text shown below the control and linked via `aria-describedby`. */
9
+ helperText?: ReactNode;
10
+ /** Renders the field in its error state (border, label and helper colour). */
11
+ error?: boolean;
12
+ /** Reflects `required` onto the control and the label asterisk. */
13
+ required?: boolean;
14
+ /** Disables the input and the stepper buttons. */
15
+ disabled?: boolean;
16
+ /** Control density. @default "medium" */
17
+ size?: "small" | "medium";
18
+ /** Placeholder shown while the field is empty. */
19
+ placeholder?: string;
20
+ /**
21
+ * Decorative leading icon (e.g. a category glyph). Rendered `aria-hidden`, so
22
+ * the visible label must carry the meaning.
23
+ */
24
+ startIcon?: ReactNode;
25
+ /**
26
+ * Trailing unit shown inside the field (e.g. `kr`, `kr/mnd`). Rendered as real
27
+ * text linked to the input via `aria-describedby` — not a placeholder — so it
28
+ * is announced and survives typing.
29
+ */
30
+ unit?: ReactNode;
31
+ /**
32
+ * Whether to render the increment / decrement stepper buttons.
33
+ * @default true
34
+ */
35
+ showSteppers?: boolean;
36
+ };
37
+ /**
38
+ * Numeric input built on Base UI's `NumberField` (value / min / max / step /
39
+ * formatting) and MUI's `OutlinedInput` (look), with stacked increment /
40
+ * decrement buttons.
41
+ *
42
+ * Works two ways, like `Input`:
43
+ * - **Standalone (all-in-one):** pass `label` / `helperText` and it renders its
44
+ * own `FormControl`, label and helper text, wiring all ids.
45
+ * - **Composed:** drop it inside a `FormControl` and it picks up the shared ids
46
+ * and state from context.
47
+ *
48
+ * For money and other open-ended amounts, set `showSteppers={false}` and use a
49
+ * `unit` (e.g. `kr`) instead — a stepper is only helpful for small bounded
50
+ * counts.
51
+ */
52
+ export declare function NumberInput({ label, labelPlacement, helperText, error, required, disabled, id, size, placeholder, startIcon, unit, showSteppers, ...rest }: NumberInputProps): import("react").JSX.Element;
@@ -0,0 +1,33 @@
1
+ import { CountryCode } from 'libphonenumber-js';
2
+ export type { CountryCode };
3
+ /**
4
+ * Countries surfaced at the top of the country-code select. Lea Bank's core
5
+ * markets, in priority order. The rest of the world follows, sorted by their
6
+ * localised name.
7
+ */
8
+ export declare const PINNED_COUNTRIES: readonly CountryCode[];
9
+ export interface CountryOption {
10
+ /** ISO 3166-1 alpha-2 code, e.g. `"FI"`. */
11
+ code: CountryCode;
12
+ /** International dialling code without the leading `+`, e.g. `"358"`. */
13
+ dialCode: string;
14
+ /** Localised country name, e.g. `"Finland"`. */
15
+ name: string;
16
+ /** Flag emoji derived from the ISO code. Purely decorative. */
17
+ flag: string;
18
+ /** Whether this is one of the pinned core-market countries. */
19
+ pinned: boolean;
20
+ }
21
+ /**
22
+ * Turns a two-letter ISO country code into its flag emoji by mapping each
23
+ * letter to the matching Unicode regional-indicator symbol. No asset library
24
+ * needed — the platform renders the pair as a flag.
25
+ */
26
+ export declare function flagEmoji(code: string): string;
27
+ /**
28
+ * Builds the ordered country list for the select: the pinned core markets
29
+ * first, then every remaining country sorted by its name in the given locale.
30
+ * Country names come from `Intl.DisplayNames`, so they follow the active locale
31
+ * with no hand-maintained list.
32
+ */
33
+ export declare function getCountryOptions(locale: string): CountryOption[];
@@ -0,0 +1,2 @@
1
+ export * from './phone-number-input';
2
+ export { PINNED_COUNTRIES, flagEmoji, getCountryOptions, type CountryCode, type CountryOption, } from './countries';
@@ -0,0 +1,53 @@
1
+ import { OutlinedInputProps } from '@mui/material';
2
+ import { ReactNode } from 'react';
3
+ import { CountryCode } from './countries';
4
+ /** Details reported alongside every change so the consumer can react to validity. */
5
+ export interface PhoneNumberMeta {
6
+ /** The selected country. */
7
+ country: CountryCode;
8
+ /** Canonical E.164 number when valid (e.g. `"+358401234567"`), otherwise `undefined`. */
9
+ e164?: string;
10
+ /** Whether the current number is a valid phone number for the country. */
11
+ isValid: boolean;
12
+ }
13
+ export type PhoneNumberInputProps = Omit<OutlinedInputProps, "value" | "defaultValue" | "onChange" | "type" | "startAdornment"> & {
14
+ /** Floating label. Rendered as an `InputLabel` and linked automatically. */
15
+ label?: ReactNode;
16
+ /** Helper / error text shown below the control and linked via `aria-describedby`. */
17
+ helperText?: ReactNode;
18
+ /** Selected country (controlled). Pair with `onCountryChange`. */
19
+ country?: CountryCode;
20
+ /** Initial country when uncontrolled. Defaults to the country for the active locale. */
21
+ defaultCountry?: CountryCode;
22
+ /** Fired when the user picks a different country. */
23
+ onCountryChange?: (country: CountryCode) => void;
24
+ /** The national number as displayed (controlled). Pair with `onChange`. */
25
+ value?: string;
26
+ /** Initial national number when uncontrolled. */
27
+ defaultValue?: string;
28
+ /** Fired on every keystroke with the formatted national number and validity meta. */
29
+ onChange?: (value: string, meta: PhoneNumberMeta) => void;
30
+ /**
31
+ * Show a built-in "invalid number" error once the field is blurred with a
32
+ * non-empty, invalid value. Ignored when the consumer drives `error`.
33
+ * @default true
34
+ */
35
+ validateOnBlur?: boolean;
36
+ };
37
+ /**
38
+ * Phone number input with a searchable country-code picker on the left, built
39
+ * on MUI's `OutlinedInput`. The number is formatted as you type and validated
40
+ * with `libphonenumber-js`. Lea Bank's core markets (Finland, Sweden, Norway,
41
+ * Spain) are pinned to the top of the country list; the default country follows
42
+ * the active locale.
43
+ *
44
+ * Works two ways, like `Input`:
45
+ * - **Standalone (all-in-one):** pass `label` / `helperText` and it renders its
46
+ * own `FormControl`, floating label and helper text, wiring all ids.
47
+ * - **Composed:** drop it inside a `FormControl` and it picks up the shared ids.
48
+ *
49
+ * Both country and number can be **controlled** (`country` + `onCountryChange`,
50
+ * `value` + `onChange`) or left **uncontrolled** (`defaultCountry` /
51
+ * `defaultValue`).
52
+ */
53
+ export declare function PhoneNumberInput({ label, helperText, error, required, disabled, id, country, defaultCountry, onCountryChange, value, defaultValue, onChange, onBlur, validateOnBlur, ...rest }: PhoneNumberInputProps): import("react").JSX.Element;
@@ -0,0 +1,77 @@
1
+ import { SxProps, Theme } from '@mui/material';
2
+ import { LucideIcon } from 'lucide-react';
3
+ import { ReactNode } from 'react';
4
+ export type RadioCardProps = {
5
+ /** Value submitted to the surrounding `RadioGroup` when this card is chosen. */
6
+ value: string | number | boolean;
7
+ /** `"horizontal"` (indicator + text in a row) or `"vertical"` (icon stacked above text). */
8
+ orientation?: "horizontal" | "vertical";
9
+ disabled?: boolean;
10
+ /** Controlled checked state for standalone use (ignored inside a `RadioGroup`). */
11
+ checked?: boolean;
12
+ /** Change handler for standalone use (ignored inside a `RadioGroup`). */
13
+ onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void;
14
+ sx?: SxProps<Theme>;
15
+ children?: ReactNode;
16
+ size?: "sm" | "lg";
17
+ };
18
+ /**
19
+ * A selectable card. Not a MUI component — it wraps our `Radio` for the actual
20
+ * selection (group membership, keyboard, a11y) and renders a styled, fully
21
+ * clickable surface around composable pieces: `RadioCardContent` (wraps the
22
+ * text), `RadioCardIndicator` (optional), `RadioCardIcon`, `RadioCardLabel`,
23
+ * `RadioCardDescription`.
24
+ *
25
+ * Children are laid out as plain flex items, so the indicator is just another
26
+ * child — place it before or after `RadioCardContent` and it sits at that edge
27
+ * (the content grows to fill the row, pushing the indicator to the side).
28
+ *
29
+ * Place cards inside a `RadioGroup` so selection stays mutually exclusive; the
30
+ * card derives its checked styling from the group automatically.
31
+ *
32
+ * ```tsx
33
+ * <RadioGroup value={value} onChange={(_, v) => setValue(v)}>
34
+ * <RadioCard value="10">
35
+ * <RadioCardContent>
36
+ * <RadioCardLabel>1316 kr/mnd</RadioCardLabel>
37
+ * <RadioCardDescription>Over 10 år</RadioCardDescription>
38
+ * </RadioCardContent>
39
+ * <RadioCardIndicator />
40
+ * </RadioCard>
41
+ * </RadioGroup>
42
+ * ```
43
+ */
44
+ export declare const RadioCard: import('react').ForwardRefExoticComponent<RadioCardProps & import('react').RefAttributes<HTMLDivElement>>;
45
+ /**
46
+ * Optional radio dot for a `RadioCard`. Reuses the shared `RadioCircle` and
47
+ * reflects the card's checked state. Omit it for icon-only cards.
48
+ */
49
+ export declare const RadioCardIndicator: () => import("react").JSX.Element;
50
+ export type RadioCardIconProps = {
51
+ /** Icon box size (predefined, overridable). */
52
+ size?: number | string;
53
+ icon: LucideIcon;
54
+ };
55
+ /**
56
+ * Fixed-size icon slot so every card's icon renders at the same size regardless
57
+ * of the icon passed in.
58
+ */
59
+ export declare const RadioCardIcon: ({ size, icon }: RadioCardIconProps) => import("react").JSX.Element;
60
+ /**
61
+ * Wraps the text lines (`RadioCardLabel` / `RadioCardDescription`) into a column.
62
+ * Grows to fill the row in `horizontal` orientation — so a sibling
63
+ * `RadioCardIndicator` is pushed to the opposite edge — and centers in
64
+ * `vertical`.
65
+ */
66
+ export declare const RadioCardContent: ({ children, sx, }: {
67
+ children: ReactNode;
68
+ sx?: SxProps<Theme>;
69
+ }) => import("react").JSX.Element;
70
+ /** Primary line of a `RadioCard`. */
71
+ export declare const RadioCardLabel: ({ children }: {
72
+ children: ReactNode;
73
+ }) => import("react").JSX.Element;
74
+ /** Secondary, muted line of a `RadioCard`. */
75
+ export declare const RadioCardDescription: ({ children }: {
76
+ children: ReactNode;
77
+ }) => import("react").JSX.Element;
@@ -0,0 +1,19 @@
1
+ import { SxProps, Theme } from '@mui/material';
2
+ export type RadioSize = "small" | "medium";
3
+ export type RadioCircleProps = {
4
+ /** When true, fills the circle and springs the dot in. */
5
+ checked?: boolean;
6
+ size?: RadioSize;
7
+ sx?: SxProps<Theme>;
8
+ };
9
+ /**
10
+ * The bare radio visual — a bordered circle with a dot that springs in when
11
+ * `checked`. Single source of truth shared by `Radio` (as its `icon` /
12
+ * `checkedIcon`) and `RadioCardIndicator`, so the look stays identical wherever a
13
+ * radio appears.
14
+ *
15
+ * Self-styled (not a MUI theme override) because it renders outside `MuiRadio`
16
+ * too. When used as `Radio`'s icons, swapping `<RadioCircle />` ⇄
17
+ * `<RadioCircle checked />` reconciles in place, so the dot animates.
18
+ */
19
+ export declare const RadioCircle: ({ checked, size, sx, }: RadioCircleProps) => import("react").JSX.Element;
@@ -0,0 +1,36 @@
1
+ import { RadioProps as MuiRadioProps, RadioGroupProps as MuiRadioGroupProps } from '@mui/material';
2
+ import { RadioSize } from './radio-circle';
3
+ export type { RadioSize };
4
+ /** Reads the `size` set on the surrounding `RadioGroup`, if any. */
5
+ export declare const useRadioGroupSize: () => RadioSize | undefined;
6
+ export type RadioProps = Omit<MuiRadioProps, "color" | "size"> & {
7
+ size?: RadioSize;
8
+ };
9
+ export type RadioGroupProps = MuiRadioGroupProps & {
10
+ /** Size applied to all child `Radio` components unless overridden per-item. */
11
+ size?: RadioSize;
12
+ };
13
+ /**
14
+ * Radio built on MUI's `Radio`, styled by the global theme (`radio.theme.ts`).
15
+ * Kept composite — pair it with `FormControlLabel` for a label instead of
16
+ * forwarding label / typography props, and place it inside a `RadioGroup` so
17
+ * selection stays mutually exclusive:
18
+ *
19
+ * ```tsx
20
+ * <RadioGroup value={value} onChange={(_, v) => setValue(v)}>
21
+ * <FormControlLabel value="a" control={<Radio />} label="A" />
22
+ * <FormControlLabel value="b" control={<Radio />} label="B" />
23
+ * </RadioGroup>
24
+ * ```
25
+ */
26
+ export declare const Radio: import('react').ForwardRefExoticComponent<Omit<RadioProps, "ref"> & import('react').RefAttributes<HTMLButtonElement>>;
27
+ /**
28
+ * Thin wrapper around MUI's `RadioGroup`. Radios are only meaningful as a
29
+ * mutually-exclusive set, so reach for this rather than placing a bare `Radio`.
30
+ *
31
+ * When rendered inside our `FormControl` it points its `aria-labelledby` at the
32
+ * surrounding `FormLabel` automatically (via the shared label id), so the group
33
+ * gets an accessible name without the consumer wiring it. Also applies a default
34
+ * gap between rows, overridable via `sx`.
35
+ */
36
+ export declare const RadioGroup: import('react').ForwardRefExoticComponent<Omit<RadioGroupProps, "ref"> & import('react').RefAttributes<HTMLDivElement>>;