asma-ui-core 3.108.4 → 3.110.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.
Files changed (58) hide show
  1. package/dist/asma-ui-core.css +1 -1
  2. package/dist/components/data-display/interactive-chip/StyledInteractiveChip.js +18 -18
  3. package/dist/components/feedback/minimizable-dialog/MinimizableDialog.js +17 -15
  4. package/dist/components/feedback/minimizable-dialog/v2/MinimizableDialogV2.js +26 -24
  5. package/dist/components/inputs/dynamic-select/components/DynamicInteractiveChipGroup.js +59 -55
  6. package/dist/components/inputs/dynamic-select/components/DynamicSelectAutocomplete.js +88 -84
  7. package/dist/components/inputs/dynamic-select/components/DynamicSelectReadOnlyValue.js +15 -11
  8. package/dist/components/inputs/dynamic-select/components/DynamicSelectTitle.js +9 -0
  9. package/dist/components/inputs/field-styles.js +16 -6
  10. package/dist/components/inputs/form-layout/StyledFieldPair.js +22 -0
  11. package/dist/components/inputs/form-layout/StyledFieldPair.module.js +8 -0
  12. package/dist/components/inputs/form-layout/StyledFormColumn.js +13 -0
  13. package/dist/components/inputs/input-field/StyledInputField.js +235 -198
  14. package/dist/components/inputs/phone-field/StyledPhoneField.js +41 -39
  15. package/dist/components/inputs/search-field/StyledSearchField.js +22 -20
  16. package/dist/components/inputs/select/StyledSelect.js +110 -108
  17. package/dist/components/inputs/select-autocomplete/StyledSelectAutocomplete.js +111 -108
  18. package/dist/components/inputs/slider/StyledSlider.js +2 -2
  19. package/dist/components/inputs/textarea/StyledTextarea.js +50 -52
  20. package/dist/components/inputs/textarea/StyledTextarea.module.js +3 -3
  21. package/dist/components/miscellaneous/StyledFormControl.js +29 -25
  22. package/dist/components/miscellaneous/StyledInputLabel.js +28 -18
  23. package/dist/datetime/components/date-picker/components/BaseDatePickerInput.js +137 -122
  24. package/dist/datetime/components/date-picker/components/DatePickerInputRangeCompact.js +17 -15
  25. package/dist/datetime/components/date-picker/components/DatePickerInputRangeCompact.module.js +2 -2
  26. package/dist/datetime/components/date-picker/components/DatePickerInputSingle.js +9 -8
  27. package/dist/datetime/components/date-picker/components/StyledCalendarPickerSelectMonth.js +17 -14
  28. package/dist/datetime/components/date-picker/components/StyledCalendarPickerSelectYear.js +14 -9
  29. package/dist/datetime/components/time-picker/StyledTimePicker.js +78 -74
  30. package/dist/datetime/components/time-picker/TimePickerInput.js +43 -41
  31. package/dist/datetime/components/time-picker/helpers/timePickerWidth.js +12 -0
  32. package/dist/helpers/CharacterCounter.js +21 -0
  33. package/dist/index.js +219 -211
  34. package/dist/src/components/inputs/dynamic-select/components/DynamicSelectReadOnlyValue.d.ts +2 -2
  35. package/dist/src/components/inputs/dynamic-select/components/DynamicSelectTitle.d.ts +14 -0
  36. package/dist/src/components/inputs/dynamic-select/types.d.ts +11 -2
  37. package/dist/src/components/inputs/field-styles.d.ts +22 -0
  38. package/dist/src/components/inputs/form-layout/StyledFieldPair.d.ts +18 -0
  39. package/dist/src/components/inputs/form-layout/StyledFormColumn.d.ts +12 -0
  40. package/dist/src/components/inputs/form-layout/index.d.ts +4 -0
  41. package/dist/src/components/inputs/input-field/StyledInputField.d.ts +19 -4
  42. package/dist/src/components/inputs/select/StyledSelect.d.ts +7 -2
  43. package/dist/src/components/inputs/select-autocomplete/StyledSelectAutocomplete.d.ts +5 -1
  44. package/dist/src/components/inputs/textarea/StyledTextarea.d.ts +6 -0
  45. package/dist/src/components/miscellaneous/StyledFormControl.d.ts +5 -2
  46. package/dist/src/components/miscellaneous/StyledInputLabel.d.ts +7 -5
  47. package/dist/src/datetime/components/date-picker/components/BaseDatePickerInput.d.ts +2 -0
  48. package/dist/src/datetime/components/date-picker/types.d.ts +3 -0
  49. package/dist/src/datetime/components/time-picker/helpers/timePickerWidth.d.ts +7 -0
  50. package/dist/src/datetime/components/time-picker/types.d.ts +3 -1
  51. package/dist/src/helpers/CharacterCounter.d.ts +16 -0
  52. package/dist/src/helpers/CharacterCounter.test.d.ts +1 -0
  53. package/dist/src/index.d.ts +1 -0
  54. package/dist/tailwind.config.d.ts +14 -0
  55. package/package.json +1 -1
  56. package/src/styles/fieldWidthTokens.css +8 -0
  57. package/src/styles/index.css +1 -0
  58. package/tw-configs/twConfigs.json +14 -0
@@ -1,5 +1,5 @@
1
1
  import { DynamicSelectOption, StyledDynamicSelectProps } from '../types';
2
- type DynamicSelectReadOnlyValueProps<TOption extends DynamicSelectOption> = Pick<StyledDynamicSelectProps<TOption>, 'dataTest' | 'options' | 'title' | 'valueKey' | 'labelKey' | 'renderLabel'> & {
2
+ type DynamicSelectReadOnlyValueProps<TOption extends DynamicSelectOption> = Pick<StyledDynamicSelectProps<TOption>, 'dataTest' | 'options' | 'title' | 'titleSize' | 'width' | 'valueKey' | 'labelKey' | 'renderLabel'> & {
3
3
  value: TOption | null;
4
4
  };
5
5
  /**
@@ -11,5 +11,5 @@ type DynamicSelectReadOnlyValueProps<TOption extends DynamicSelectOption> = Pick
11
11
  * buttons, and read-only draws neither. No value → `-`, the same placeholder the chip variant shows.
12
12
  * Multiple selects never reach this component.
13
13
  */
14
- export declare const DynamicSelectReadOnlyValue: <TOption extends DynamicSelectOption>({ dataTest, options, value, title, valueKey, labelKey, renderLabel, }: DynamicSelectReadOnlyValueProps<TOption>) => JSX.Element;
14
+ export declare const DynamicSelectReadOnlyValue: <TOption extends DynamicSelectOption>({ dataTest, options, value, title, titleSize, width, valueKey, labelKey, renderLabel, }: DynamicSelectReadOnlyValueProps<TOption>) => JSX.Element;
15
15
  export {};
@@ -0,0 +1,14 @@
1
+ import { DynamicSelectOption, StyledDynamicSelectProps } from '../types';
2
+ type DynamicSelectTitleProps = Pick<StyledDynamicSelectProps<DynamicSelectOption>, 'title' | 'titleSize'> & {
3
+ id?: string;
4
+ };
5
+ /**
6
+ * The title above every dynamic select variant — chips, autocomplete and the read-only value — so all
7
+ * three read the same and a consumer never stacks its own form label (with its input-title bottom
8
+ * padding) on top of the select.
9
+ *
10
+ * `base` = Body Base SemiBold 16/24; `lg` = Section title SemiBold 18/28 — both `text-icon/title-label`
11
+ * (delta-800), the `StyledFormLabel` sizes of the same names.
12
+ */
13
+ export declare const DynamicSelectTitle: ({ title, titleSize, id }: DynamicSelectTitleProps) => JSX.Element | null;
14
+ export {};
@@ -1,3 +1,4 @@
1
+ import { FieldWidth } from '../field-styles';
1
2
  import { StyledSelectAutocompleteProps } from '../select-autocomplete';
2
3
  import { default as React } from 'react';
3
4
  export type DynamicSelectOptionPrimitive = string | number | boolean;
@@ -34,8 +35,16 @@ interface DynamicSelectCommonProps<TOption extends DynamicSelectOption> {
34
35
  readOnly?: boolean;
35
36
  /** Prevents the built-in clear button from appearing even when a value is set. Applies to autocomplete only. */
36
37
  disableClearable?: boolean;
37
- /** @figmaProp Title (Body Base SemiBold 16, text-icon/title-label delta-800) above the control. */
38
- title?: string;
38
+ /**
39
+ * @figmaProp Title (text-icon/title-label delta-800) above the control. A node, so a title can carry
40
+ * an icon or a required marker. Prefer it over a separate form label stacked on the select: the
41
+ * select owns the title-to-control gap, which is tighter in read-only (title over plain text).
42
+ */
43
+ title?: React.ReactNode;
44
+ /** @figmaProp none — title typography: `'base'` Body Base SemiBold 16/24 (default), `'lg'` Section title 18/28. */
45
+ titleSize?: 'base' | 'lg';
46
+ /** Field width pattern step. The pattern keeps a dynamic select Full (WID-5); Full is the default. */
47
+ width?: FieldWidth;
39
48
  /** @figmaProp none — app size (chips/buttons). Defaults to `'medium'`. */
40
49
  size?: 'small' | 'medium';
41
50
  /**
@@ -11,6 +11,28 @@ export interface SingleLineInputLayoutOptions {
11
11
  export declare const singleLineInputLayoutStyle: ({ paddingLeft, paddingRight, }?: SingleLineInputLayoutOptions) => CSSProperties;
12
12
  /** Label vertical anchor — inline so duplicate Tailwind `top-*` utilities cannot shift it. */
13
13
  export declare const floatingLabelLayoutStyle: (shrink: boolean) => CSSProperties;
14
+ /** Field width pattern (ASMA-8489): XS 8rem, S 12.5rem, M 20rem, Full up to the 37.5rem form column. */
15
+ export type FieldWidth = 'xs' | 's' | 'm' | 'full';
16
+ /** `width: 100%; max-width: <step>`, so a field shrinks in a narrower container and never overflows it. */
17
+ export declare const fieldWidthStyle: (width: FieldWidth) => CSSProperties;
18
+ /**
19
+ * Full screen is the one place a field may be wider than 600 px (WID-10): Full fields and the form
20
+ * column fill the dialog's content width, while XS, S and M keep their step.
21
+ */
22
+ export declare const fullScreenFieldWidthVars: {
23
+ '--field-width-full': string;
24
+ '--form-column-width': string;
25
+ };
26
+ /** The step a character limit picks (WID-2): up to 9 characters XS, 15 S, 27 M, longer Full. */
27
+ export declare const fieldWidthForMaxLength: (maxLength: number) => FieldWidth;
28
+ export type FieldLabelPlacement = 'above' | 'floating';
29
+ /**
30
+ * The label above a field, as `StyledPhoneField` draws it. It wraps and is never truncated (TRUNC-4).
31
+ * Put it on a wrapper around the `<label>`: apps in the shell ship `label { padding: 0 !important }`.
32
+ */
33
+ export declare const fieldLabelAboveClass: ({ disabled }?: {
34
+ disabled?: boolean;
35
+ }) => string;
14
36
  /**
15
37
  * Shared outlined-field styling so `StyledInputField`, `StyledInputLabel` (+ `StyledFormControl`)
16
38
  * and `StyledSelect` render an identical border + floating label without MUI. TASK-401.
@@ -0,0 +1,18 @@
1
+ import { ReactNode } from 'react';
2
+ export interface StyledFieldPairProps {
3
+ /** The two fields, first field first, so focus and screen readers reach it first. */
4
+ children: ReactNode;
5
+ /**
6
+ * A group label for parts that only make sense together, such as country code and number.
7
+ * Renders the pair as a `fieldset` with this `legend`; each field still keeps its own label.
8
+ */
9
+ legend?: ReactNode;
10
+ className?: string;
11
+ dataTest?: string;
12
+ }
13
+ /**
14
+ * Two fields that are parts of one answer, side by side (field width pattern WID-9): first name + last
15
+ * name, postal code + city, date + time, from + to, a value + its unit. Each field keeps its width step;
16
+ * a Full field fills the rest of the row and is never narrower than S. Stacks when the row is too narrow.
17
+ */
18
+ export declare const StyledFieldPair: ({ children, legend, className, dataTest }: StyledFieldPairProps) => JSX.Element;
@@ -0,0 +1,12 @@
1
+ import { ReactNode } from 'react';
2
+ export interface StyledFormColumnProps {
3
+ children?: ReactNode;
4
+ className?: string;
5
+ dataTest?: string;
6
+ }
7
+ /**
8
+ * The one form column (field width pattern WID-1): at most 37.5rem (600 px), left-aligned, and as wide
9
+ * as its container when that is narrower. Fields, labels, hints and errors all sit inside it.
10
+ * A full-screen `MinimizableDialog` widens it to the dialog (WID-10).
11
+ */
12
+ export declare const StyledFormColumn: ({ children, className, dataTest }: StyledFormColumnProps) => JSX.Element;
@@ -0,0 +1,4 @@
1
+ export * from './StyledFieldPair';
2
+ export * from './StyledFormColumn';
3
+ export { fieldLabelAboveClass, fieldWidthForMaxLength, fieldWidthStyle } from '../field-styles';
4
+ export type { FieldLabelPlacement, FieldWidth } from '../field-styles';
@@ -1,5 +1,6 @@
1
1
  import { ChangeEvent, CSSProperties, FocusEvent, HTMLAttributes, InputHTMLAttributes, ReactNode, Ref } from 'react';
2
- import { FieldSize } from '../field-styles';
2
+ import { UiCoreLocale } from '../../../helpers/uiCoreLocale';
3
+ import { FieldLabelPlacement, FieldSize, FieldWidth } from '../field-styles';
3
4
  interface InputSlot {
4
5
  startAdornment?: ReactNode;
5
6
  endAdornment?: ReactNode;
@@ -21,8 +22,13 @@ type HtmlInputSlot = InputHTMLAttributes<HTMLInputElement> & {
21
22
  export interface StyledInputFieldProps {
22
23
  /** @figmaProp none — test hook */
23
24
  dataTest: string;
24
- /** @figmaProp Label element (floating) */
25
+ /** @figmaProp Label element */
25
26
  label?: ReactNode;
27
+ /**
28
+ * `above` (default): the label sits above the field and wraps. `floating`: inside the field, only
29
+ * where a label above has no room, such as the search field (field width pattern §10).
30
+ */
31
+ labelPlacement?: FieldLabelPlacement;
26
32
  /** @figmaProp Filled = (value != '')→"on" | else→"off" */
27
33
  value?: string | number;
28
34
  /** @figmaProp Filled = (defaultValue != '')→"on" | else→"off" */
@@ -36,6 +42,12 @@ export interface StyledInputFieldProps {
36
42
  helperText?: ReactNode;
37
43
  reserveHelperText?: boolean;
38
44
  expandHelperText?: boolean;
45
+ /** Character limit; also readable from `slotProps.htmlInput.maxLength`. */
46
+ maxLength?: number;
47
+ /** Shows the count against `maxLength` as the user types, for free text with a limit. */
48
+ counter?: boolean;
49
+ /** Language of the counter text. */
50
+ locale?: UiCoreLocale;
39
51
  /** @figmaProp State = true→"Disabled" */
40
52
  disabled?: boolean;
41
53
  /** @figmaProp State = true→"Read only" */
@@ -61,6 +73,9 @@ export interface StyledInputFieldProps {
61
73
  size?: FieldSize;
62
74
  /** Accepted for API parity; the design always renders outlined. */
63
75
  variant?: string;
76
+ /** Field width pattern step, `width: 100%; max-width: <step>`. Full fills the form column. */
77
+ width?: FieldWidth;
78
+ /** @deprecated Fields are Full by default; use `width`. */
64
79
  fullWidth?: boolean;
65
80
  className?: string;
66
81
  style?: CSSProperties;
@@ -83,7 +98,7 @@ export interface StyledInputFieldProps {
83
98
  onClick?: (event: React.MouseEvent<HTMLDivElement>) => void;
84
99
  }
85
100
  /**
86
- * Outlined text field with a floating label (replaces MUI `TextField`). Self-contained: manages its
101
+ * Outlined text field with its label above it (replaces MUI `TextField`). Self-contained: manages its
87
102
  * own focus/value state to drive the shared field styling ([[field-styles]]); supports multiline,
88
103
  * start/end adornments, an optional clear button, and error/helper text. Public props preserved
89
104
  *
@@ -91,5 +106,5 @@ export interface StyledInputFieldProps {
91
106
  * the visual gate. Multiline auto-grows between `minRows` and `maxRows` (a fixed `rows` pins the height)
92
107
  * and scrolls once the content exceeds the cap; `readOnly` ignores the cap and shows the whole value.
93
108
  */
94
- export declare const StyledInputField: ({ dataTest, label, value, defaultValue, onChange, onBlur, onFocus, error, helperText, reserveHelperText, expandHelperText, disabled, readOnly, required, allowClear, onClear, type, placeholder, name, id, autoComplete, autoFocus, multiline, rows, minRows, maxRows, size, fullWidth, className, style, sx, inputRef, slotProps, InputProps, onKeyDown, onClick, variant: _variant, }: StyledInputFieldProps) => JSX.Element;
109
+ export declare const StyledInputField: ({ dataTest, label, labelPlacement, value, defaultValue, onChange, onBlur, onFocus, error, helperText, reserveHelperText, expandHelperText, maxLength, counter, locale, disabled, readOnly, required, allowClear, onClear, type, placeholder, name, id, autoComplete, autoFocus, multiline, rows, minRows, maxRows, size, width, fullWidth: _fullWidth, className, style, sx, inputRef, slotProps, InputProps, onKeyDown, onClick, variant: _variant, }: StyledInputFieldProps) => JSX.Element;
95
110
  export {};
@@ -1,5 +1,5 @@
1
1
  import { CSSProperties, FocusEventHandler, ReactNode } from 'react';
2
- import { FieldSize } from '../field-styles';
2
+ import { FieldSize, FieldWidth } from '../field-styles';
3
3
  export interface SelectChangeEvent<T = unknown> {
4
4
  target: {
5
5
  value: T;
@@ -44,6 +44,9 @@ export interface StyledSelectProps {
44
44
  displayEmpty?: boolean;
45
45
  multiple?: boolean;
46
46
  renderValue?: (value: unknown) => ReactNode;
47
+ /** Field width pattern step; Full by default. `variant="standard"` keeps its content width. */
48
+ width?: FieldWidth;
49
+ /** @deprecated Fields are Full by default; use `width`. */
47
50
  fullWidth?: boolean;
48
51
  className?: string;
49
52
  style?: CSSProperties;
@@ -57,6 +60,8 @@ export interface StyledSelectProps {
57
60
  * above). Without it (and no `name`/placeholder/value text), the trigger has no accessible name
58
61
  * at all — a common gap when a floating/external label isn't referenced. */
59
62
  labelId?: string;
63
+ /** Marks the trigger `aria-required`; also read from a surrounding `StyledFormControl`. */
64
+ required?: boolean;
60
65
  children?: ReactNode;
61
66
  MenuProps?: {
62
67
  className?: string;
@@ -70,4 +75,4 @@ export interface StyledSelectProps {
70
75
  * portalled `role="listbox"`. Reports open/filled into a surrounding `StyledFormControl` so its
71
76
  * TASK-402.
72
77
  */
73
- export declare const StyledSelect: ({ dataTest, value, defaultValue, onChange, error, errorText, helperText, reserveHelperText, expandHelperText, allowClear, disabled, readOnly, name, placeholder, displayEmpty, multiple, renderValue, fullWidth, className, style, sx, variant, children, MenuProps, onFocus, onBlur, labelId, }: StyledSelectProps) => JSX.Element;
78
+ export declare const StyledSelect: ({ dataTest, value, defaultValue, onChange, error, errorText, helperText, reserveHelperText, expandHelperText, allowClear, disabled, readOnly, name, placeholder, displayEmpty, multiple, renderValue, width, fullWidth: _fullWidth, className, style, sx, variant, children, MenuProps, onFocus, onBlur, labelId, required, }: StyledSelectProps) => JSX.Element;
@@ -1,4 +1,5 @@
1
1
  import { CSSProperties, HTMLAttributes, KeyboardEvent, ReactNode, SyntheticEvent } from 'react';
2
+ import { FieldWidth } from '../field-styles';
2
3
  export type AutocompleteChangeReason = 'createOption' | 'selectOption' | 'removeOption' | 'clear' | 'blur';
3
4
  export type AutocompleteInputChangeReason = 'input' | 'reset' | 'clear';
4
5
  export interface AutocompleteRenderOptionState {
@@ -105,6 +106,9 @@ export interface StyledSelectAutocompleteProps<T, Multiple extends boolean | und
105
106
  multiple?: Multiple;
106
107
  allowSelectAll?: boolean;
107
108
  selectAllLabel?: string;
109
+ /** Field width pattern step; Full by default. */
110
+ width?: FieldWidth;
111
+ /** @deprecated Fields are Full by default; use `width`. */
108
112
  fullWidth?: boolean;
109
113
  /** Accepted for MUI parity; single-select already omits selected options via filtering. */
110
114
  filterSelectedOptions?: boolean;
@@ -132,5 +136,5 @@ export interface StyledSelectAutocompleteProps<T, Multiple extends boolean | und
132
136
  * ponytail: `freeSolo` is accepted (arbitrary input is emitted via onInputChange) but not turned
133
137
  * into option values; exact keyboard-parity edge cases are Chromatic/axe-gated.
134
138
  */
135
- export declare function StyledSelectAutocomplete<T, Multiple extends boolean | undefined = false, DisableClearable extends boolean | undefined = false, FreeSolo extends boolean | undefined = false>({ dataTest, options, renderInput, value, onChange, getOptionLabel, getOptionKey, isOptionEqualToValue, renderOption, renderValue, filterOptions, loading, loadingText, noOptionsText, disabled, readOnly, error, helperText, size, rowSize, disableClearable, disableCloseOnSelect, popupIcon, autoHeight, multiple, allowSelectAll, selectAllLabel, fullWidth, classes, inputValue: controlledInput, onInputChange, open: controlledOpen, onOpen, onClose, className, wrapperClassName, getOptionDisabled, slotProps, }: StyledSelectAutocompleteProps<T, Multiple, DisableClearable, FreeSolo>): JSX.Element;
139
+ export declare function StyledSelectAutocomplete<T, Multiple extends boolean | undefined = false, DisableClearable extends boolean | undefined = false, FreeSolo extends boolean | undefined = false>({ dataTest, options, renderInput, value, onChange, getOptionLabel, getOptionKey, isOptionEqualToValue, renderOption, renderValue, filterOptions, loading, loadingText, noOptionsText, disabled, readOnly, error, helperText, size, rowSize, disableClearable, disableCloseOnSelect, popupIcon, autoHeight, multiple, allowSelectAll, selectAllLabel, width, fullWidth: _fullWidth, classes, inputValue: controlledInput, onInputChange, open: controlledOpen, onOpen, onClose, className, wrapperClassName, getOptionDisabled, slotProps, }: StyledSelectAutocompleteProps<T, Multiple, DisableClearable, FreeSolo>): JSX.Element;
136
140
  export {};
@@ -1,4 +1,6 @@
1
1
  import { default as React, ChangeEvent, MutableRefObject, ReactNode } from 'react';
2
+ import { UiCoreLocale } from '../../../helpers/uiCoreLocale';
3
+ import { FieldWidth } from '../field-styles';
2
4
  export interface TextareaCommonProps {
3
5
  id?: string;
4
6
  /** @figmaProp Filled — the field text (Body Base 16/lh24, delta-800). */
@@ -12,6 +14,10 @@ export interface TextareaCommonProps {
12
14
  containerClassName?: string;
13
15
  className?: string;
14
16
  dataTest?: string;
17
+ /** Field width pattern step; a text area is Full. */
18
+ width?: FieldWidth;
19
+ /** Language of the character counter. */
20
+ locale?: UiCoreLocale;
15
21
  }
16
22
  export interface TextAreaNotEditableProps {
17
23
  variant?: 'not_editable' | 'view_only';
@@ -1,11 +1,14 @@
1
1
  import { CSSProperties, FocusEventHandler, MouseEventHandler, ReactNode } from 'react';
2
- import { FieldSize } from '../inputs/field-styles';
2
+ import { FieldSize, FieldWidth } from '../inputs/field-styles';
3
3
  export interface FormControlProps {
4
4
  children?: ReactNode;
5
5
  error?: boolean;
6
6
  disabled?: boolean;
7
7
  required?: boolean;
8
8
  size?: FieldSize;
9
+ /** Field width pattern step of the field it wraps; Full by default. */
10
+ width?: FieldWidth;
11
+ /** @deprecated Fields are Full by default; use `width`. */
9
12
  fullWidth?: boolean;
10
13
  /** Accepted for API parity; the design always renders outlined. */
11
14
  variant?: string;
@@ -24,4 +27,4 @@ export interface FormControlProps {
24
27
  * focus/filled state so `StyledInputLabel` can float and `StyledFormHelperText` can colour itself;
25
28
  * `StyledSelect` reports its state into this context. Public props preserved (DEC-003). TASK-401.
26
29
  */
27
- export declare const StyledFormControl: ({ children, error, disabled, required, size, fullWidth, className, style, sx, id, onFocus, onBlur, onClick, }: FormControlProps) => JSX.Element;
30
+ export declare const StyledFormControl: ({ children, error, disabled, required, size, width, fullWidth: _fullWidth, className, style, sx, id, onFocus, onBlur, onClick, }: FormControlProps) => JSX.Element;
@@ -1,5 +1,5 @@
1
1
  import { ReactNode } from 'react';
2
- import { FieldSize } from '../inputs/field-styles';
2
+ import { FieldLabelPlacement, FieldSize } from '../inputs/field-styles';
3
3
  export interface InputLabelProps {
4
4
  children?: ReactNode;
5
5
  htmlFor?: string;
@@ -10,11 +10,13 @@ export interface InputLabelProps {
10
10
  size?: FieldSize;
11
11
  /** Force the shrunk (floated) state; otherwise derived from the surrounding FormControl. */
12
12
  shrink?: boolean;
13
+ /** `above` (default) or `floating`, as on `StyledInputField`. */
14
+ labelPlacement?: FieldLabelPlacement;
13
15
  className?: string;
14
16
  }
15
17
  /**
16
- * Floating field label (replaces MUI `InputLabel`). Reads focus/filled/error/size from the
17
- * surrounding `StyledFormControl`; `shrink` lifts it onto the border. Public props preserved
18
- * (DEC-003). TASK-401.
18
+ * Field label (replaces MUI `InputLabel`), above the field by default. The `floating` placement reads
19
+ * focus/filled/error/size from the surrounding `StyledFormControl`; `shrink` lifts it onto the border.
20
+ * Public props preserved (DEC-003). TASK-401.
19
21
  */
20
- export declare const StyledInputLabel: ({ children, htmlFor, id, required, disabled, error, size, shrink, className, }: InputLabelProps) => JSX.Element;
22
+ export declare const StyledInputLabel: ({ children, htmlFor, id, required, disabled, error, size, shrink, labelPlacement, className, }: InputLabelProps) => JSX.Element;
@@ -1,3 +1,4 @@
1
+ import { FieldWidth } from '../../../../components/inputs/field-styles';
1
2
  import { AriaAttributes } from 'react';
2
3
  import { DayPickerProps as ReactDayPickerProps, Matcher } from 'react-day-picker';
3
4
  export interface IBaseDatePickerInput {
@@ -25,5 +26,6 @@ export interface IBaseDatePickerInput {
25
26
  required?: boolean;
26
27
  minDate?: Date;
27
28
  inputAriaProps?: AriaAttributes;
29
+ width?: FieldWidth;
28
30
  }
29
31
  export declare const BaseDatePickerInput: React.FC<IBaseDatePickerInput>;
@@ -1,5 +1,6 @@
1
1
  import { AriaAttributes } from 'react';
2
2
  import { DayPicker, Matcher } from 'react-day-picker';
3
+ import { FieldWidth } from '../../../components/inputs/field-styles';
3
4
  export type CalendarProps = React.ComponentProps<typeof DayPicker>;
4
5
  type CommonDatePickerProps = {
5
6
  dateFormat?: string;
@@ -13,6 +14,8 @@ type CommonDatePickerProps = {
13
14
  validateOnCalendarClose?: boolean;
14
15
  onValidatedOnce?: () => void;
15
16
  required?: boolean;
17
+ /** Field width pattern step of each date field, calendar button included. Defaults to S. */
18
+ width?: FieldWidth;
16
19
  } & CalendarProps;
17
20
  export interface DatePickerSingleFieldProps {
18
21
  label?: string;
@@ -0,0 +1,7 @@
1
+ import { CSSProperties } from 'react';
2
+ import { StyledTimePickerProps } from '../types';
3
+ /** The step box of the picker root; a legacy numeric `width` is applied on the input instead. */
4
+ export declare const timePickerWidthProps: (width: StyledTimePickerProps["width"]) => {
5
+ "data-field-width"?: string;
6
+ style?: CSSProperties;
7
+ };
@@ -1,4 +1,5 @@
1
1
  import { AriaAttributes, ReactNode } from 'react';
2
+ import { FieldWidth } from '../../../components/inputs/field-styles';
2
3
  /**
3
4
  * @param notBeforeTime - Start time of the range. Selected time must be after this value.
4
5
  */
@@ -10,7 +11,8 @@ export interface StyledTimePickerProps {
10
11
  readOnly?: boolean;
11
12
  inputClassName?: string;
12
13
  dataTest: string;
13
- width?: number;
14
+ /** Field width pattern step; defaults to XS. A number (a fixed `px` width) is deprecated: use a step. */
15
+ width?: FieldWidth | number;
14
16
  error?: boolean;
15
17
  helperText?: ReactNode;
16
18
  label?: string;
@@ -0,0 +1,16 @@
1
+ import { UiCoreLocale } from './uiCoreLocale';
2
+ /** Screen readers hear the count only once the user is close to the limit, not on every keystroke. */
3
+ export declare const isNearCharacterLimit: (length: number, limit: number) => boolean;
4
+ export interface CharacterCounterProps {
5
+ /** Id of the visible count, for the field's `aria-describedby`. */
6
+ id: string;
7
+ length: number;
8
+ limit: number;
9
+ locale?: UiCoreLocale;
10
+ className?: string;
11
+ }
12
+ /**
13
+ * The count of a free-text field with a character limit, such as *12 av 100 tegn* (field width
14
+ * pattern WID-2, Q12), so typed text is never cut without notice.
15
+ */
16
+ export declare const CharacterCounter: ({ id, length, limit, locale, className }: CharacterCounterProps) => JSX.Element;
@@ -0,0 +1 @@
1
+ export {};
@@ -27,6 +27,7 @@ export * from './components/inputs/radio-button';
27
27
  export * from './components/inputs/label';
28
28
  export * from './components/inputs/dynamic-select';
29
29
  export * from './components/inputs/phone-field';
30
+ export * from './components/inputs/form-layout';
30
31
  export * from './datetime/components/date-picker';
31
32
  export * from './datetime/components/time-picker';
32
33
  export * from './datetime/helpers/date.helper';
@@ -170,6 +170,20 @@ declare const _default: {
170
170
  };
171
171
  };
172
172
  };
173
+ width: {
174
+ "field-xs": string;
175
+ "field-s": string;
176
+ "field-m": string;
177
+ "field-full": string;
178
+ "form-column": string;
179
+ };
180
+ maxWidth: {
181
+ "field-xs": string;
182
+ "field-s": string;
183
+ "field-m": string;
184
+ "field-full": string;
185
+ "form-column": string;
186
+ };
173
187
  };
174
188
  };
175
189
  darkMode: "media";
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "3.108.4",
6
+ "version": "3.110.0",
7
7
  "type": "module",
8
8
  "sideEffects": [
9
9
  "**/*.css",
@@ -0,0 +1,8 @@
1
+ :root {
2
+ /* Field width pattern (ASMA-8489, WID-1/WID-3): four widths only, in rem so they grow with text. */
3
+ --field-width-xs: 8rem; /* 128px: postal code, year, age, time */
4
+ --field-width-s: 12.5rem; /* 200px: date, phone number, national ID, amount */
5
+ --field-width-m: 20rem; /* 320px: IBAN, long codes */
6
+ --form-column-width: 37.5rem; /* 600px: the one form column */
7
+ --field-width-full: var(--form-column-width);
8
+ }
@@ -4,6 +4,7 @@
4
4
  @import 'color-variables/fretexTokens.css';
5
5
  @import 'color-variables/jadeTokens.css';
6
6
  @import 'typographyTokens.css';
7
+ @import 'fieldWidthTokens.css';
7
8
 
8
9
  @tailwind base;
9
10
  @tailwind components;
@@ -163,5 +163,19 @@
163
163
  "transform": "rotate(360deg)"
164
164
  }
165
165
  }
166
+ },
167
+ "width": {
168
+ "field-xs": "var(--field-width-xs)",
169
+ "field-s": "var(--field-width-s)",
170
+ "field-m": "var(--field-width-m)",
171
+ "field-full": "var(--field-width-full)",
172
+ "form-column": "var(--form-column-width)"
173
+ },
174
+ "maxWidth": {
175
+ "field-xs": "var(--field-width-xs)",
176
+ "field-s": "var(--field-width-s)",
177
+ "field-m": "var(--field-width-m)",
178
+ "field-full": "var(--field-width-full)",
179
+ "form-column": "var(--form-column-width)"
166
180
  }
167
181
  }