Kontur UI

repository·master·Indexed 43 days ago

https://github.com/skbkontur/retail-ui

A collection of React components, templates, and design principles for building predictable user interfaces. Includes the @skbkontur/colors library for semantic color tokens, react-ui-codemod for automated library upgrades, and @skbkontur/react-ui-validations for form validation using ValidationContainer and ValidationWrapper.

Tokens
93.8K
Snippets
302
Records
503
Agent score
54%

What's inside Kontur UI

  1. Implement filtering and sorting in Table components

    master

    The @skbkontur/table package provides a suite of components and hooks to implement column-based filtering, sorting from the header, and displaying active filter tokens.

    Core Components

    • Table.DropdownFilter: A basic dropdown filter.
    • Table.DropdownSortableFilter: A dropdown filter that also supports sorting.
    • Table.Filter, Table.FilterItem, Table.FilterSearch: Components used to construct complex dropdown filters.
    • Table.FilterResultRow, Table.FilterResultCell, Table.Token: Components used to display active filters as removable tokens.

    Core Hooks

    • useTableFilters(data, columnConfig): Manages the state of filters, providing functions to set filters, retrieve unique values for options, get filtered rows, convert active filters to tokens, and reset filters.
    • useTableSort(filteredRows): Manages the sorting state based on the currently filtered data.
  2. TimePicker accessibility and keyboard navigation

    master

    The TimePicker is designed with accessibility in mind, using textbox for the input and listbox for the dropdown menu.

    Keyboard Shortcuts

    • Navigation:
      • ArrowLeft / ArrowRight: Switch between time segments (e.g., from hours to minutes).
      • ArrowUp / ArrowDown: Change the value of the active segment or navigate items in the dropdown menu.
    • Editing:
      • Backspace / Delete: Clear the active segment.
      • Ctrl + A: Select the entire field value.
    • Selection & Closing:
      • Enter: Selects the active item in the dropdown or commits the typed value.
      • Escape: Closes the dropdown menu.

    Best Practices

    • Always associate the field with a label using <label htmlFor="ID"> and the component's id prop.
    • If no visible label is used, provide an aria-label.
  3. Understand TimePicker value behavior and constraints

    master

    Value Normalization

    • onValueChange format: The value returned is always a normalized string (e.g., "09:00"), regardless of whether the source elements are strings or objects.
    • Empty values: An empty value is returned as an empty string (""). This string can be passed directly back to the value prop.
    • Paste behavior: When pasting invalid time strings (e.g., "25:88"), the component normalizes the input to the nearest valid time (e.g., "23:59").
    • Unexpected input: Strings that do not resemble time (e.g., a date like "2026-08-01") are rejected and trigger the onUnexpectedInput callback.

    minTime and maxTime constraints

    • Dropdown behavior: The minTime and maxTime props restrict which elements are available in the dropdown menu.
    • Manual input: These props do not prevent manual text entry. To restrict manual input, you must perform validation at the product level using TimePicker.validate(value, { minTime, maxTime }).
    • Mobile exception: If using useMobileNativeTimePicker, minTime and maxTime are passed to the native input[type='time'], which provides native browser constraints.
  4. How validation interacts with UI visibility

    master

    Form validation via ValidationContainer.validate() only considers components that are currently rendered using ValidationWrapper.

    If a validationInfo object exists for a specific node but that node is not passed into any currently rendered ValidationWrapper component, it will not affect the overall result of ValidationContainer.validate().

    Key takeaway: You do not need to duplicate UI visibility logic (e.g., if (isVisible)) inside your validation rules. You can always validate the node in the model; if the field is not present in the UI, the form will remain valid even if the underlying model node has validation errors.