From 4af5d053151dc66e6fd41b7c5b19d7654f881d24 Mon Sep 17 00:00:00 2001 From: SerraMorec Date: Thu, 25 Dec 2025 14:40:28 +0300 Subject: [PATCH 1/2] feat(sdds-acore/uikit): File was implemented for xml --- .../docs/components/AvatarGroupUsage.md | 2 +- .../docs/components/AvatarUsage.md | 8 +- .../docs/components/ButtonGroupUsage.md | 4 +- .../docs/components/ButtonUsage.md | 4 +- .../xml-template/docs/components/CardUsage.md | 2 +- .../xml-template/docs/components/CellUsage.md | 6 +- .../docs/components/CheckBoxUsage.md | 4 +- .../components/CircularProgressBarUsage.md | 6 +- .../docs/components/CodeFieldUsage.md | 4 +- .../docs/components/CodeInputUsage.md | 4 +- .../docs/components/CounterUsage.md | 2 +- .../docs/components/DividerUsage.md | 4 +- .../docs/components/DrawerUsage.md | 10 +- .../docs/components/DropDownMenuUsage.md | 3 +- .../docs/components/FileUssage.md | 132 ++++ .../docs/components/IndicatorUsage.md | 2 +- .../docs/components/ListItemUsage.md | 2 +- .../xml-template/docs/components/ListUsage.md | 2 +- .../docs/components/LoaderUsage.md | 6 +- .../docs/components/NavigationDrawerUsage.md | 2 +- .../xml-template/docs/components/NoteUsage.md | 4 +- .../docs/components/NotificationUsage.md | 2 +- .../docs/components/OverlayUsage.md | 4 +- .../docs/components/PopoverUsage.md | 2 +- .../docs/components/ProgressUsage.md | 2 +- .../docs/components/RadioBoxUsage.md | 4 +- .../docs/components/RectSkeletonUsage.md | 6 +- .../docs/components/ScrollBarUsage.md | 2 +- .../docs/components/SegmentUsage.md | 4 +- .../docs/components/SpinnerUsage.md | 4 +- .../docs/components/SwitchUsage.md | 2 +- .../docs/components/TextFieldUsage.md | 16 +- .../docs/components/TextSkeletonUsage.md | 10 +- .../docs/components/ToastUsage.md | 2 +- .../docs/components/ToolBarUsage.md | 8 +- .../sandbox/core/compose/MenuItem.kt | 4 +- .../playground/sandbox/core/vs/MenuItem.kt | 9 + .../sandbox/file/{ => compose}/FileScreen.kt | 10 +- .../sandbox/file/{ => compose}/FileUiState.kt | 2 +- .../file/{ => compose}/FileViewModel.kt | 2 +- .../sandbox/file/vs/FileFragment.kt | 56 ++ .../file/vs/FileParametersViewModel.kt | 118 +++ .../src/main/res/values/components_ids.xml | 1 + .../src/main/res/values/routes.xml | 1 + ...sServFileCircularProgressVariationsView.kt | 22 + ...ddsServFileLinearProgressVariationsView.kt | 22 + .../view/SddsServViewComponents.kt | 7 + .../components/file/FileConfigDelegate.kt | 23 +- .../file/view/FileStyleGeneratorView.kt | 135 ++++ .../com/sdds/testing/vs/file/FileFactory.kt | 80 ++ .../com/sdds/testing/vs/file/FileUiState.kt | 61 ++ .../main/res/layout/layout_component_file.xml | 75 ++ .../src/main/res/values/components_id.xml | 1 + .../main/kotlin/com/sdds/uikit/CellLayout.kt | 12 +- .../src/main/kotlin/com/sdds/uikit/File.kt | 732 ++++++++++++++++++ .../uikit/src/main/res/values/file_attrs.xml | 77 ++ .../uikit/src/main/res/values/styles_file.xml | 9 + .../config-info-view-system.json | 134 ++++ .../sdds/serv/colorstate/FileColorState.kt | 44 ++ .../src/main/res/layout/test.xml | 52 ++ ...le_circular_progress_description_color.xml | 11 + .../serv_file_circular_progress_icon_tint.xml | 8 + ...erv_file_circular_progress_label_color.xml | 8 + ...file_linear_progress_description_color.xml | 11 + .../serv_file_linear_progress_icon_tint.xml | 8 + .../serv_file_linear_progress_label_color.xml | 8 + .../values/file-attributes.xml | 15 + .../theme-builder-res/values/style-dimens.xml | 19 + .../values/styles-filecircularprogress.xml | 126 +++ .../values/styles-filelinearprogress.xml | 127 +++ .../main/theme-builder-res/values/theme.xml | 2 + 71 files changed, 2219 insertions(+), 94 deletions(-) create mode 100644 build-system/docs-template/xml-template/docs/components/FileUssage.md rename playground/sandbox-compose/src/main/kotlin/com/sdds/playground/sandbox/file/{ => compose}/FileScreen.kt (95%) rename playground/sandbox-compose/src/main/kotlin/com/sdds/playground/sandbox/file/{ => compose}/FileUiState.kt (93%) rename playground/sandbox-compose/src/main/kotlin/com/sdds/playground/sandbox/file/{ => compose}/FileViewModel.kt (98%) create mode 100644 playground/sandbox-compose/src/main/kotlin/com/sdds/playground/sandbox/file/vs/FileFragment.kt create mode 100644 playground/sandbox-compose/src/main/kotlin/com/sdds/playground/sandbox/file/vs/FileParametersViewModel.kt create mode 100644 playground/sandbox-sdds-serv-integration/src/main/kotlin/com/sdds/playground/sandbox/sdds/serv/integration/view/SddsServFileCircularProgressVariationsView.kt create mode 100644 playground/sandbox-sdds-serv-integration/src/main/kotlin/com/sdds/playground/sandbox/sdds/serv/integration/view/SddsServFileLinearProgressVariationsView.kt create mode 100644 sdds-core/plugin_theme_builder/src/main/kotlin/com/sdds/plugin/themebuilder/internal/components/file/view/FileStyleGeneratorView.kt create mode 100644 sdds-core/testing/src/main/kotlin/com/sdds/testing/vs/file/FileFactory.kt create mode 100644 sdds-core/testing/src/main/kotlin/com/sdds/testing/vs/file/FileUiState.kt create mode 100644 sdds-core/testing/src/main/res/layout/layout_component_file.xml create mode 100644 sdds-core/uikit/src/main/kotlin/com/sdds/uikit/File.kt create mode 100644 sdds-core/uikit/src/main/res/values/file_attrs.xml create mode 100644 sdds-core/uikit/src/main/res/values/styles_file.xml create mode 100644 tokens/sdds.serv.view/src/main/kotlin/com/sdds/serv/colorstate/FileColorState.kt create mode 100644 tokens/sdds.serv.view/src/main/res/layout/test.xml create mode 100644 tokens/sdds.serv.view/src/main/theme-builder-res/color/serv_file_circular_progress_description_color.xml create mode 100644 tokens/sdds.serv.view/src/main/theme-builder-res/color/serv_file_circular_progress_icon_tint.xml create mode 100644 tokens/sdds.serv.view/src/main/theme-builder-res/color/serv_file_circular_progress_label_color.xml create mode 100644 tokens/sdds.serv.view/src/main/theme-builder-res/color/serv_file_linear_progress_description_color.xml create mode 100644 tokens/sdds.serv.view/src/main/theme-builder-res/color/serv_file_linear_progress_icon_tint.xml create mode 100644 tokens/sdds.serv.view/src/main/theme-builder-res/color/serv_file_linear_progress_label_color.xml create mode 100644 tokens/sdds.serv.view/src/main/theme-builder-res/values/file-attributes.xml create mode 100644 tokens/sdds.serv.view/src/main/theme-builder-res/values/styles-filecircularprogress.xml create mode 100644 tokens/sdds.serv.view/src/main/theme-builder-res/values/styles-filelinearprogress.xml diff --git a/build-system/docs-template/xml-template/docs/components/AvatarGroupUsage.md b/build-system/docs-template/xml-template/docs/components/AvatarGroupUsage.md index 806fc82f5..4b0ee9e9a 100644 --- a/build-system/docs-template/xml-template/docs/components/AvatarGroupUsage.md +++ b/build-system/docs-template/xml-template/docs/components/AvatarGroupUsage.md @@ -33,7 +33,7 @@ title: AvatarGroup ## Стиль AvatarGroup Существует набор сгенерированных стилей. Так же можно настроить стиль самостоятельно. -Для использования заранее сгененрированного стиля, необходимо через атрибут style указатать стиль из библиотеки (пример выше). +Для использования заранее сгенерированного стиля, необходимо через атрибут style указать стиль из библиотеки (пример выше). Для настройки стиля Avatar в формате xml предусмотрены следующие атрибуты: |Название атрибута|Описание|Формат данных| diff --git a/build-system/docs-template/xml-template/docs/components/AvatarUsage.md b/build-system/docs-template/xml-template/docs/components/AvatarUsage.md index 16166ec36..7dac6529d 100644 --- a/build-system/docs-template/xml-template/docs/components/AvatarUsage.md +++ b/build-system/docs-template/xml-template/docs/components/AvatarUsage.md @@ -14,7 +14,7 @@ title: Avatar ## Стиль Avatar Существует набор сгенерированных стилей. Так же можно настроить стиль самостоятельно. -Для использования заранее сгененрированного стиля, необходимо через атрибут style указатать стиль из библиотеки (пример выше). +Для использования заранее сгенерированного стиля, необходимо через атрибут style указать стиль из библиотеки (пример выше). Для настройки стиля Avatar в формате xml предусмотрены следующие атрибуты: |Название атрибута|Описание|Формат данных| @@ -24,16 +24,16 @@ title: Avatar |sd_statusOffsetX / sd_statusOffsetY|смещение статуса по x/y|dimension, reference| |sd_statusStyle|статусу можно задать стиль (обычно это стиль компонента Indicator)|reference| -В Avatar возможно отобразить extra (обвесы), в качестве которых пердусмотрен компонент Badge и компонент Counter +В Avatar возможно отобразить extra (обвесы), в качестве которых предусмотрен компонент Badge и компонент Counter |Название атрибута|Описание|Формат данных| |:-:|:-:|:-:| -|sd_extraBadgeStyle|cтиль Badge|reference| +|sd_extraBadgeStyle|стиль Badge|reference| |sd_extraBadgeEnabled|отображение Badge как enabled|boolean| |sd_extraBadgeText|текст внутри Badge|string| |sd_extraBadgeIconStart / sd_extraBadgeIconEnd|расположение иконки внутри Badge|reference| |sd_extraBadgePlacement|расположение Badge внутри Avatar|enum (topLeft,topRight, bottomRight, bottomLeft)| -|sd_extraCounterStyle|cтиль Counter|reference| +|sd_extraCounterStyle|стиль Counter|reference| |sd_extraCounterEnabled|отображение Counter как enabled|boolean| |sd_extraCounterText|текст внутри Counter (число)|string| |sd_extraCounterPlacement|расположение Counter внутри Avatar|enum (topLeft,topRight, bottomRight, bottomLeft)| diff --git a/build-system/docs-template/xml-template/docs/components/ButtonGroupUsage.md b/build-system/docs-template/xml-template/docs/components/ButtonGroupUsage.md index b2299ee77..d57f1d346 100644 --- a/build-system/docs-template/xml-template/docs/components/ButtonGroupUsage.md +++ b/build-system/docs-template/xml-template/docs/components/ButtonGroupUsage.md @@ -58,12 +58,12 @@ title: ButtonGroup ## Стиль ButtonGroup Существует набор сгенерированных стилей. Так же можно настроить стиль самостоятельно. -Для использования заранее сгененрированного стиля, необходимо через атрибут style указатать стиль из библиотеки (пример выше). +Для использования заранее сгенерированного стиля, необходимо через атрибут style указать стиль из библиотеки (пример выше). Для настройки стиля ButtonGroup в формате xml предусмотрены следующие атрибуты: |Название атрибута|Описание|Формат данных| |:-:|:-:|:-:| |sd_buttonStyleOverlay|оверлэй стиль кнопки|reference| -|sd_externalShapeAppearance|форма скруглений наружних углов у крайних элементов группы|reference| +|sd_externalShapeAppearance|форма скруглений наружных углов у крайних элементов группы|reference| |sd_internalShapeAppearance|форма скруглений углов элементов группы |reference| |sd_buttonSpacing|отступ между элементами внутри группы|dimension| diff --git a/build-system/docs-template/xml-template/docs/components/ButtonUsage.md b/build-system/docs-template/xml-template/docs/components/ButtonUsage.md index 687bbae50..f64a03a16 100644 --- a/build-system/docs-template/xml-template/docs/components/ButtonUsage.md +++ b/build-system/docs-template/xml-template/docs/components/ButtonUsage.md @@ -37,11 +37,11 @@ title: Button |sd_spinnerSize|размер спиннера, который отображается как состояние загрузки|dimension| |sd_spinnerStrokeWidth|ширина бордера анимированного спиннера, в состоянии загрузки|dimension| |sd_spinnerTint|цвет спиннера|reference, color| -|sd_spacing|расположение контента, может быть packed (контент центрирован, лишние оступы располагаются по краям) или spaceBetween (контент отобразится по всей ширине, отступы будут добавлены между элементами контента)|enum(packed, spaceBetween)| +|sd_spacing|расположение контента, может быть packed (контент центрирован, лишние отступы располагаются по краям) или spaceBetween (контент отобразится по всей ширине, отступы будут добавлены между элементами контента)|enum(packed, spaceBetween)| Для задания лэйбла (основного текста внутри Button), а так же конфигурирования стиля и цвета текста - используйте стандартные атрибуты android(android:text, android:textAppearance, android:textColor). -Для использования заранее сгененрированного стиля, необходимо через атрибут style указатать стиль из библиотеки. +Для использования заранее сгенерированного стиля, необходимо через атрибут style укатать стиль из библиотеки. Для настройки и корректировки формы скругления используйте [sd_shapeAppearance](../theme/ShapeAppearance.md#sd_shapeappearance). Для настройки и корректировки фокус селектора используйте [настройки фокус-селектора](../focus). diff --git a/build-system/docs-template/xml-template/docs/components/CardUsage.md b/build-system/docs-template/xml-template/docs/components/CardUsage.md index dc08ebaa9..08dbba2c5 100644 --- a/build-system/docs-template/xml-template/docs/components/CardUsage.md +++ b/build-system/docs-template/xml-template/docs/components/CardUsage.md @@ -44,7 +44,7 @@ title: Card ## Стиль Card Существует набор сгенерированных стилей. Так же можно настроить стиль самостоятельно. -Для использования заранее сгененрированного стиля, необходимо через атрибут style указатать стиль из библиотеки (пример выше). +Для использования заранее сгенерированного стиля, необходимо через атрибут style указать стиль из библиотеки (пример выше). Компонент Card разработан на основе Flow, поэтому атрибуты [FlowLayout](FlowUsage.md#настройка-flow) доступны для использования Для настройки размера и паддингов Card используйте стандартные атрибуты android. Для настройки и корректировки формы скругления используйте [sd_shapeAppearance](../theme/ShapeAppearance.md#sd_shapeappearance). diff --git a/build-system/docs-template/xml-template/docs/components/CellUsage.md b/build-system/docs-template/xml-template/docs/components/CellUsage.md index a56884a53..0a6957751 100644 --- a/build-system/docs-template/xml-template/docs/components/CellUsage.md +++ b/build-system/docs-template/xml-template/docs/components/CellUsage.md @@ -69,7 +69,7 @@ title: Cell ## Стиль Cell Существует набор сгенерированных стилей. Так же можно настроить стиль самостоятельно. -Для использования заранее сгененрированного стиля, необходимо через атрибут style указатать стиль из библиотеки (пример выше). +Для использования заранее сгенерированного стиля, необходимо через атрибут style указать стиль из библиотеки (пример выше). Для настройки стиля Cell в формате xml предусмотрены следующие атрибуты: |Название атрибута|Описание|Формат данных| @@ -91,9 +91,9 @@ title: Cell |sd_disclosureIcon|drawable(иконка)|reference| |sd_disclosureColor / sd_disclosureTextColor|если не задан sd_disclosureTextColor то цвет текста и drawable будет определен атрибутом sd_disclosureColor|reference,color| -Предполагается, что в качестве контента используются компоннеты [Avatar](AvatarUsage.md#avatar), [CheckBox](CheckBoxUsage.md#checkbox), [RadioBox](RadioBoxUsage.md#radiobox), [IconButton](ButtonUsage.md), [Switch](SwitchUsage.md#switch). +Предполагается, что в качестве контента используются компоненты [Avatar](AvatarUsage.md#avatar), [CheckBox](CheckBoxUsage.md#checkbox), [RadioBox](RadioBoxUsage.md#radiobox), [IconButton](ButtonUsage.md), [Switch](SwitchUsage.md#switch). Если в CellLayout не используется сгенерированный стиль (который определяет стили контента в начале и в конце), -то возможно задать стили контента самомстоятельно при помощи следующих атрибутов +то возможно задать стили контента самостоятельно при помощи следующих атрибутов |Название атрибута|Описание|Формат данных| |:-:|:-:|:-:| diff --git a/build-system/docs-template/xml-template/docs/components/CheckBoxUsage.md b/build-system/docs-template/xml-template/docs/components/CheckBoxUsage.md index 0baa48f35..05fb86b43 100644 --- a/build-system/docs-template/xml-template/docs/components/CheckBoxUsage.md +++ b/build-system/docs-template/xml-template/docs/components/CheckBoxUsage.md @@ -38,9 +38,9 @@ title: CheckBox |sd_toggleIconWidth / sd_toggleIconHeight|размеры иконок, согласно состоянию|dimension| Если ресурсы иконок не предоставлены - используется анимированная отрисовка состояний (такое поведение предпочтительно). -Основной текст стилизуется с помощю стандартных атрибутов android. +Основной текст стилизуется с помощью стандартных атрибутов android. Для настройки и корректировки формы скругления используйте [sd_shapeAppearance](../theme/ShapeAppearance.md#sd_shapeappearance). -Для использования заранее сгененрированного стиля, необходимо через атрибут style указатать стиль из библиотеки. +Для использования заранее сгенерированного стиля, необходимо через атрибут style указать стиль из библиотеки. ```xml + + + + + + + + + + + + + + + + + +``` + +Обратите внимание, что у каждого вложенного компонента указана роль layout_fileContent. +Стоит так же отметить, что внутри File предусмотрена автоматическая стилизация компонентов +ProgressBar, CircularProgressBar и IconButton (использующегося в качестве Action) если заданы атрибуты +заданы R.styleable.File_sd_circularProgressBarStyleOverlay, R.styleable.File_sd_progressBarStyleOverlay, +R.styleable.File_sd_iconButtonStyleOverlay. + +## Стили + +Существует набор сгенерированных стилей. Так же можно настроить стиль самостоятельно. +Для конфигурирования стиля File предусмотрены следующие атрибуты: + +|Название атрибута|Описание|Формат данных| +|sd_circularProgressBarStyleOverlay|Оверлэй стиль компонента CircularProgressBar|reference| +|sd_progressBarStyleOverlay|Оверлэй стиль компонента ProgressBar|reference| +|sd_iconButtonStyleOverlay|Оверлэй стиль компонента IconButton|reference| +|sd_contentStartPadding|отступ после контента, расположенного в начале|dimension| +|sd_contentEndPadding|отступ перед контентом, расположенным в конце|dimension| +|sd_contentBottomPadding|отступ перед контентом, расположенным снизу|dimension| +|sd_descriptionPadding|отступ между Label и Description|dimension| +|sd_labelAppearance|стиль текста Label|reference| +|sd_labelColor|цвет текста Label|reference,color| +|sd_iconTint|окрас иконки|reference,color| +|sd_descriptionAppearance|стиль текста Description|reference| +|sd_descriptionColor|цвет текста Description|reference,color| +|sd_isLoading|перевод компонента в состояние загрузки|boolean| +|sd_progressPlacement|Расположение компонента с ролью прогресс|enum(inner, outer)| +|sd_actionPlacement|расположение компонента с ролью Action|enum(start, end)| +|layout_fileContent|роли компонентов, размещаемых внутри File|enum(image, icon, action, progress, label, description)| + +## Размещение контента внутри CircularProgressBar + +Обратите внимание, в примере выше, CircularProgressBar так же содержит некий Action внутри себя, это возможно +благодаря тому, что CircularProgressBar - FrameLayout. Вы можете располагать любой контент внутри CircularProgressBar, +выравнивая его с помощью gravity. Примером такого использования может послужить необходимость отмены загрузки, если +таковая уже началась. Объяснение этому описано в разделе [isLoading](FileUssage.md#isloading) + +## isLoading + +Режим компонента, в котором отображается компонент прогресс. Особенностью этого режима является то, что если, +в качестве прогресса используется компонент CircularProgressBar, все компоненты, находящиеся в одном слоте с +прогрессом будут скрыты. Например: actionPlacement выставлен в end и присутствует компонент с ролью Action, +это означает, что при isLoading = true будет показан компонент CircularProgressBar, а компонент с ролью +Action скрыт. Если же в качестве компонента прогресса используется горизонтальный ProgressBar, то компонент с +ролью Action не будет скрываться, это объясняется тем, что ProgressBar расположен НЕ в Cell. + +## ActionPlacement + +При переключении этого свойства, роли компонентов внутри Cell переприсваиваются автоматически, компоненты +с ролью Action и Progress меняют свое положение внутри компонента относительно Label и Description. +При этом, если в File имеются компоненты с ролями Image или Icon, и actionPlacement = ACTION_PLACEMENT_START, +то эти компоненты будут скрыты. + +## ProgressPlacement + +Указывает на то, какой компонент прогресса отобразить, если isLoading = true. Если добавлены оба компонента, +и ProgressBar в качестве горизонтального прогресса и CircularProgressBar в качестве круглого прогресса, будет +отображен только один из них. При PROGRESS_PLACEMENT_OUTER- горизонтальный прогресс, при PROGRESS_PLACEMENT_INNER - +круглый прогресс. \ No newline at end of file diff --git a/build-system/docs-template/xml-template/docs/components/IndicatorUsage.md b/build-system/docs-template/xml-template/docs/components/IndicatorUsage.md index b17847291..c0e9bb422 100644 --- a/build-system/docs-template/xml-template/docs/components/IndicatorUsage.md +++ b/build-system/docs-template/xml-template/docs/components/IndicatorUsage.md @@ -12,7 +12,7 @@ title: Indicator ## Стиль Indicator Существует набор сгенерированных стилей. Так же можно настроить стиль самостоятельно. -Для использования заранее сгененрированного стиля, необходимо через атрибут style указатать +Для использования заранее сгенерированного стиля, необходимо через атрибут style указать стиль из библиотеки (пример выше). Для настройки стиля Indicator в формате xml предусмотрены следующие атрибуты: diff --git a/build-system/docs-template/xml-template/docs/components/ListItemUsage.md b/build-system/docs-template/xml-template/docs/components/ListItemUsage.md index c2f089e3f..9c6fd6420 100644 --- a/build-system/docs-template/xml-template/docs/components/ListItemUsage.md +++ b/build-system/docs-template/xml-template/docs/components/ListItemUsage.md @@ -46,6 +46,6 @@ title: ListItem ## Стиль ListItem Существует набор сгенерированных стилей. Так же можно настроить стиль самостоятельно. -Для использования заранее сгененрированного стиля, необходимо через атрибут style указатать стиль из библиотеки (пример выше). +Для использования заранее сгенерированного стиля, необходимо через атрибут style указать стиль из библиотеки (пример выше). Для настройки стиля ListItem в формате xml используйте атрибуты [Cell](CellUsage.md#стиль-cell) Для настройки и корректировки формы скругления используйте [sd_shapeAppearance](../theme/ShapeAppearance.md#sd_shapeappearance). diff --git a/build-system/docs-template/xml-template/docs/components/ListUsage.md b/build-system/docs-template/xml-template/docs/components/ListUsage.md index b65f6930c..3b59aae8a 100644 --- a/build-system/docs-template/xml-template/docs/components/ListUsage.md +++ b/build-system/docs-template/xml-template/docs/components/ListUsage.md @@ -16,7 +16,7 @@ title: List ## Стиль List Существует набор сгенерированных стилей. Так же можно настроить стиль самостоятельно. -Для использования заранее сгененрированного стиля, необходимо через атрибут style указатать стиль из библиотеки (пример выше). +Для использования заранее сгенерированного стиля, необходимо через атрибут style указать стиль из библиотеки (пример выше). В xml возможно задать стиль самого List (или оверлэй стиль ListItem), но для отображение контента, необходимо программно задать адаптер и контент: diff --git a/build-system/docs-template/xml-template/docs/components/LoaderUsage.md b/build-system/docs-template/xml-template/docs/components/LoaderUsage.md index d8858b15b..e87b7f19c 100644 --- a/build-system/docs-template/xml-template/docs/components/LoaderUsage.md +++ b/build-system/docs-template/xml-template/docs/components/LoaderUsage.md @@ -45,15 +45,15 @@ title: Loader |sd_progress|текущий прогресс|float| |sd_maxProgress|максимальный прогресс(это значение будет означать 100%)|float| |sd_minProgress|минимальный прогресс|float| -|sd_trackEnabled|бордер, по которому отрисовывется прогресс|boolean| +|sd_trackEnabled|бордер, по которому отрисовывается прогресс|boolean| |sd_progressValueEnabled|включение отображения численного значения прогресса|boolean| -|sd_progressValueSuffix|суффикс(единца измерения прогресса)|string| +|sd_progressValueSuffix|суффикс(единица измерения прогресса)|string| |sd_sweepAngle|угол дуги индикатора загрузки в градусах, определяет какую часть окружности занимает индикатор спиннера|float| |sd_loaderType|тип отображаемого индикатора загрузки Spinner или CircularProgressBar|enum(spinner, progress)| ## LoaderType -Параметр, определяющй, какой компонент отображается в данный момент. Ожидаемое значение +Параметр, определяющий, какой компонент отображается в данный момент. Ожидаемое значение Int, для отображения [Spinner] - Loader.SPINNER, для [CircularProgressBar] - Loader.PROGRESS ## Примечание diff --git a/build-system/docs-template/xml-template/docs/components/NavigationDrawerUsage.md b/build-system/docs-template/xml-template/docs/components/NavigationDrawerUsage.md index 81f0b7c18..fa8243f51 100644 --- a/build-system/docs-template/xml-template/docs/components/NavigationDrawerUsage.md +++ b/build-system/docs-template/xml-template/docs/components/NavigationDrawerUsage.md @@ -7,7 +7,7 @@ title: NavigationDrawer ## Стиль NavigationDrawer -Для использования заранее сгененрированного стиля, необходимо через атрибут style указатать стиль. +Для использования заранее сгенерированного стиля, необходимо через атрибут style указать стиль. Для конфигурирования стиля NavigationDrawer предусмотрены следующие атрибуты: |Название атрибута|Описание|Формат данных| diff --git a/build-system/docs-template/xml-template/docs/components/NoteUsage.md b/build-system/docs-template/xml-template/docs/components/NoteUsage.md index ca831c671..697dc8498 100644 --- a/build-system/docs-template/xml-template/docs/components/NoteUsage.md +++ b/build-system/docs-template/xml-template/docs/components/NoteUsage.md @@ -12,10 +12,10 @@ noteContent: NoteContent (NoteContent.ACTION или NoteContent.CONTENT_BEFORE) ContentBefore. Для корректного отображения, компоненты Note и NoteCompact реализованы так, что могут отобразить только одну view в каждой из секций, поэтому, при добавлении новых view в слот, старые view будут автоматически удалены. Компонент автоматически предопределяет стиль -только для компонента [LinkButton](ButtonUsage.md#стиль-linkbutton), для стилизации других компонентов необходимл +только для компонента [LinkButton](ButtonUsage.md#стиль-linkbutton), для стилизации других компонентов необходимо вручную указывать стиль этого компонента. Для удобного добавления иконки, в слот ContentBefore, достаточно указать ее ресурс, воспользовавшись функцией setIconResource или через атрибут sd_icon. -Альтернативным вариантом является добавление компоннета ImageView, с установленной заранне иконкой. +Альтернативным вариантом является добавление компонента ImageView, с установленной заранее иконкой. ``` kotlin addContentBefore( diff --git a/build-system/docs-template/xml-template/docs/components/NotificationUsage.md b/build-system/docs-template/xml-template/docs/components/NotificationUsage.md index 8d9cbfec6..b83b3dfab 100644 --- a/build-system/docs-template/xml-template/docs/components/NotificationUsage.md +++ b/build-system/docs-template/xml-template/docs/components/NotificationUsage.md @@ -3,7 +3,7 @@ title: Notification --- Всплывающий элемент - уведомление поверх контента, отображаемое с помощью системы оверлеев SDDS UI Kit, -разработааной для удобства позиционирования и анимирования контента. +разработанной для удобства позиционирования и анимирования контента. В качестве контента ожидает [NotificationContent](NotificationContentUsage.md) или произвольный контент. diff --git a/build-system/docs-template/xml-template/docs/components/OverlayUsage.md b/build-system/docs-template/xml-template/docs/components/OverlayUsage.md index 7d07ceb7c..2a3e440f2 100644 --- a/build-system/docs-template/xml-template/docs/components/OverlayUsage.md +++ b/build-system/docs-template/xml-template/docs/components/OverlayUsage.md @@ -17,9 +17,9 @@ Overlay представляет из себя контейнер - подлож ## Стиль Overlay Существует готовый стиль. Так же можно настроить стиль самостоятельно. -Для использования заранее сгененрированного стиля, необходимо через атрибут style указатать стиль из библиотеки (пример выше). +Для использования заранее сгенерированного стиля, необходимо через атрибут style указать стиль из библиотеки (пример выше). Помимо атрибутов FrameLayout, для корректного отображения цвета фона, используйте атрибут |Название атрибута|Описание|Формат данных| |:-:|:-:|:-:| -|sd_background|цвет флона|color, reference| +|sd_background|цвет фона|color, reference| diff --git a/build-system/docs-template/xml-template/docs/components/PopoverUsage.md b/build-system/docs-template/xml-template/docs/components/PopoverUsage.md index b1ae4756c..523581497 100644 --- a/build-system/docs-template/xml-template/docs/components/PopoverUsage.md +++ b/build-system/docs-template/xml-template/docs/components/PopoverUsage.md @@ -8,7 +8,7 @@ title: Popover ## Стиль Popover Существует набор сгенерированных стилей. Так же можно настроить стиль самостоятельно. -Для конфигурирования стиля Popover преддусмтотрены следующие атрибуты +Для конфигурирования стиля Popover предусмотрены следующие атрибуты |Название атрибута|Описание|Формат данных| |:-:|:-:|:-:| diff --git a/build-system/docs-template/xml-template/docs/components/ProgressUsage.md b/build-system/docs-template/xml-template/docs/components/ProgressUsage.md index 8ec44dcf1..3fdbb692f 100644 --- a/build-system/docs-template/xml-template/docs/components/ProgressUsage.md +++ b/build-system/docs-template/xml-template/docs/components/ProgressUsage.md @@ -15,7 +15,7 @@ title: ProgressBar ## Стиль ProgressBar Существует набор сгенерированных стилей. Так же можно настроить стиль самостоятельно. -Для использования заранее сгененрированного стиля, необходимо через атрибут style указатать стиль из библиотеки (пример выше). +Для использования заранее сгенерированного стиля, необходимо через атрибут style указать стиль из библиотеки (пример выше). Для настройки стиля ProgressBar в формате xml предусмотрены следующие атрибуты: |Название атрибута|Описание|Формат данных| diff --git a/build-system/docs-template/xml-template/docs/components/RadioBoxUsage.md b/build-system/docs-template/xml-template/docs/components/RadioBoxUsage.md index 999e25533..8f177206e 100644 --- a/build-system/docs-template/xml-template/docs/components/RadioBoxUsage.md +++ b/build-system/docs-template/xml-template/docs/components/RadioBoxUsage.md @@ -14,7 +14,7 @@ title: RadioBox ## Стиль RadioBox Существует набор сгенерированных стилей. Так же можно настроить стиль самостоятельно. -Для использования заранее сгененрированного стиля, необходимо через атрибут style указатать стиль из библиотеки. +Для использования заранее сгенерированного стиля, необходимо через атрибут style указать стиль из библиотеки. Для настройки стиля RadioBox в формате xml предусмотрены следующие атрибуты: |Название атрибута|Описание|Формат данных| @@ -35,5 +35,5 @@ title: RadioBox |sd_toggleIconWidth / sd_toggleIconHeight|размеры иконок, согласно состоянию|dimension| Если ресурс иконки не предоставлен - используется дефолтная отрисовка состояний (такое поведение предпочтительно). -Основной текст стилизуется с помощю стандартных атрибутов android. +Основной текст стилизуется с помощью стандартных атрибутов android. Для настройки и корректировки формы скругления используйте [sd_shapeAppearance](../theme/ShapeAppearance.md#sd_shapeappearance). diff --git a/build-system/docs-template/xml-template/docs/components/RectSkeletonUsage.md b/build-system/docs-template/xml-template/docs/components/RectSkeletonUsage.md index b9f54029a..edbb08795 100644 --- a/build-system/docs-template/xml-template/docs/components/RectSkeletonUsage.md +++ b/build-system/docs-template/xml-template/docs/components/RectSkeletonUsage.md @@ -12,14 +12,14 @@ title: RectSkeleton ## Стиль RectSkeleton Существует набор сгенерированных стилей. Так же можно настроить стиль самостоятельно. -Для использования заранее сгененрированного стиля, необходимо через атрибут style указатать стиль из библиотеки (пример выше). +Для использования заранее сгенерированного стиля, необходимо через атрибут style указать стиль из библиотеки (пример выше). По скольку в основе RectSkeleton лежит ShimmerLayout - атрибуты ShimmerLayout так же доступны для конфигурирования. Для настройки стиля RectSkeleton в формате xml предусмотрены следующие атрибуты: |Название атрибута|Описание|Формат данных| |:-:|:-:|:-:| -|sd_shimmer|drawable для отрисоки шиммера|reference| -|sd_shimmerDuration|время движения шиммера - скорочть анимации|integer| +|sd_shimmer|drawable для отрисовки шиммера|reference| +|sd_shimmerDuration|время движения шиммера - скорость анимации|integer| |sd_autoStart|анимация запускается сама, автоматически|boolean| Для настройки и корректировки формы скругления используйте [sd_shapeAppearance](../theme/ShapeAppearance.md#sd_shapeappearance). diff --git a/build-system/docs-template/xml-template/docs/components/ScrollBarUsage.md b/build-system/docs-template/xml-template/docs/components/ScrollBarUsage.md index 8e6b2b451..268c6cbe9 100644 --- a/build-system/docs-template/xml-template/docs/components/ScrollBarUsage.md +++ b/build-system/docs-template/xml-template/docs/components/ScrollBarUsage.md @@ -17,7 +17,7 @@ title: ScrollBar ## Стиль ScrollBar Существует набор сгенерированных стилей. Так же можно настроить стиль самостоятельно. -Для использования заранее сгененрированного стиля, необходимо через атрибут style указатать стиль из библиотеки (пример выше). +Для использования заранее сгенерированного стиля, необходимо через атрибут style указать стиль из библиотеки (пример выше). Для настройки стиля TextSkeleton в формате xml предусмотрены следующие атрибуты: | Название атрибута | Описание | Формат данных | diff --git a/build-system/docs-template/xml-template/docs/components/SegmentUsage.md b/build-system/docs-template/xml-template/docs/components/SegmentUsage.md index 6022c022f..a65ca54b2 100644 --- a/build-system/docs-template/xml-template/docs/components/SegmentUsage.md +++ b/build-system/docs-template/xml-template/docs/components/SegmentUsage.md @@ -32,7 +32,7 @@ title: Segment ## Стиль Segment Существует набор сгенерированных стилей. Так же можно настроить стиль самостоятельно. -Для использования заранее сгененрированного стиля, необходимо через атрибут style указатать стиль из библиотеки. +Для использования заранее сгенерированного стиля, необходимо через атрибут style указать стиль из библиотеки. Для настройки стиля Segment в формате xml предусмотрены следующие атрибуты: |Название атрибута|Описание|Формат данных| @@ -46,7 +46,7 @@ title: Segment ## Стиль SegmentItem Существует набор сгенерированных стилей. Так же можно настроить стиль самостоятельно. -Для использования заранее сгененрированного стиля, необходимо через атрибут style указатать стиль из библиотеки. +Для использования заранее сгенерированного стиля, необходимо через атрибут style указать стиль из библиотеки. Для настройки стиля SegmentItem в формате xml предусмотрены следующие атрибуты: |Название атрибута|Описание|Формат данных| diff --git a/build-system/docs-template/xml-template/docs/components/SpinnerUsage.md b/build-system/docs-template/xml-template/docs/components/SpinnerUsage.md index 2798bbab5..cb8efdc5d 100644 --- a/build-system/docs-template/xml-template/docs/components/SpinnerUsage.md +++ b/build-system/docs-template/xml-template/docs/components/SpinnerUsage.md @@ -15,7 +15,7 @@ title: Spinner ## Стиль Spinner Существует набор сгенерированных стилей. Так же можно настроить стиль самостоятельно. -Для использования заранее сгененрированного стиля, необходимо через атрибут style указатать стиль из библиотеки (пример выше). +Для использования заранее сгенерированного стиля, необходимо через атрибут style указать стиль из библиотеки (пример выше). Для настройки стиля Spinner в формате xml предусмотрены следующие атрибуты: |Название атрибута|Описание|Формат данных| @@ -24,7 +24,7 @@ title: Spinner |android:tint|окрас индикатора загрузки|color| |sd_startColor|начальный цвет градиента индикатора загрузки|reference, color| |sd_endColor|конечный цвет градиента индикатора загрузки|reference, color| -|sd_strokeCap|форма крааев линии индикатора загрузки|enum(round, square)| +|sd_strokeCap|форма краев линии индикатора загрузки|enum(round, square)| |sd_sweepAngle|угол дуги индикатора загрузки в градусах, определяет какую часть окружности занимает индикатор|float| Для настройки размера и отступов применяются стандартные атрибуты android (android:maxWidth, android:minHeight, android:padding) diff --git a/build-system/docs-template/xml-template/docs/components/SwitchUsage.md b/build-system/docs-template/xml-template/docs/components/SwitchUsage.md index f7da1ae74..96675ed4c 100644 --- a/build-system/docs-template/xml-template/docs/components/SwitchUsage.md +++ b/build-system/docs-template/xml-template/docs/components/SwitchUsage.md @@ -14,7 +14,7 @@ title: Switch ## Стиль Switch Существует набор сгенерированных стилей. Так же можно настроить стиль самостоятельно. -Для использования заранее сгененрированного стиля, необходимо через атрибут style указатать стиль из библиотеки. +Для использования заранее сгенерированного стиля, необходимо через атрибут style указать стиль из библиотеки. Для настройки стиля Switch в формате xml предусмотрены следующие атрибуты: | Название атрибута | Описание |Формат данных| diff --git a/build-system/docs-template/xml-template/docs/components/TextFieldUsage.md b/build-system/docs-template/xml-template/docs/components/TextFieldUsage.md index dab151580..bc590f428 100644 --- a/build-system/docs-template/xml-template/docs/components/TextFieldUsage.md +++ b/build-system/docs-template/xml-template/docs/components/TextFieldUsage.md @@ -22,20 +22,20 @@ title: TextField ## Стиль TextField Существует набор сгенерированных стилей. Так же можно настроить стиль самостоятельно. -Для использования заранее сгененрированного стиля, необходимо через атрибут style указатать стиль из библиотеки (пример выше). +Для использования заранее сгенерированного стиля, необходимо через атрибут style указать стиль из библиотеки (пример выше). Для настройки стиля TextField в формате xml предусмотрены следующие атрибуты: |Название атрибута|Описание|Формат данных| |:-:|:-:|:-:| |sd_label|текст лэйбла|string| |sd_labelAppearance|стиль лэйбла|reference| -|sd_labelColor|цвет лэбла|color, reference| +|sd_labelColor|цвет лэйбла|color, reference| |sd_labelPadding|отступ лэйбла от value|dimension| |sd_labelPlacement|расположение лэйбла|enum (none, outer, inner)| |sd_value|основной текст|string| |sd_valueAppearance|стиль основного текста|reference| |sd_valueColor|цвет основного текста|color, reference| -|sd_placeholder|текст плйсхолдера|string| +|sd_placeholder|текст плэйсхолдера|string| |sd_placeholderAppearance|стиль текста плэйхолдера|reference| |sd_placeholderColor|цвет текста плэйсхолдера|color, reference| |sd_caption|текст подписи|string| @@ -68,8 +68,8 @@ title: TextField |sd_boxPaddingTop|отступ сверху текстового поля|dimension| |sd_boxPaddingEnd|отступ в конце текстового поля|dimension| |sd_boxPaddingBottom|отступ снизу текстового поля|dimension| -|sd_chipGroupStyleOverlay|стиль компонента ChipGroup, если задан, то при вводе текста и нажатии клавиши пробел, введенный текст оборачивается в комопнент Chip с иконкой закрытия (удаления Chip) |reference| -|sd_chipsPadding|оступы между Chip в текстовом поле|dimension| +|sd_chipGroupStyleOverlay|стиль компонента ChipGroup, если задан, то при вводе текста и нажатии клавиши пробел, введенный текст оборачивается в компонент Chip с иконкой закрытия (удаления Chip) |reference| +|sd_chipsPadding|отступы между Chip в текстовом поле|dimension| |sd_suffixText|текст после value|string| |sd_suffixDrawable|drawable после value|reference| |sd_suffixTextPadding|отступ между основным текстом (value) и suffix|dimension| @@ -81,7 +81,7 @@ title: TextField |sd_scrollBarPaddingTop|отступ сверху|dimension| |sd_scrollBarPaddingEnd|отступ в конце|dimension| |sd_scrollBarPaddingStart|отступ в начале|dimension| -|sd_scrollBarPaddingBottom|оступ снизу|dimension| +|sd_scrollBarPaddingBottom|отступ снизу|dimension| |sd_scrollBarTrackColor|цвет фона полосы прокрутки|color, reference| |sd_scrollBarThumbColor|цвет индикатора прокрутки|color, reference| @@ -90,7 +90,7 @@ title: TextField ## TextArea Существует набор сгенерированных стилей. Так же можно настроить стиль самостоятельно. -Для использования заранее сгененрированного стиля, необходимо через атрибут style указатать стиль из библиотеки. +Для использования заранее сгенерированного стиля, необходимо через атрибут style указать стиль из библиотеки. Для настройки стиля TextArea в формате xml предусмотрены те же атрибуты, что у TextField, так как эти два компонента отличаются друг от друга только визуально. @@ -111,7 +111,7 @@ title: TextField ## TextField readOnly -При включении этого параметра компоннет сатновится доступным только для чтения, изменение текстовых полей невозможно. +При включении этого параметра компонент становится доступным только для чтения, изменение текстовых полей невозможно. ## TextField value diff --git a/build-system/docs-template/xml-template/docs/components/TextSkeletonUsage.md b/build-system/docs-template/xml-template/docs/components/TextSkeletonUsage.md index becb8b7d2..d6cc5c282 100644 --- a/build-system/docs-template/xml-template/docs/components/TextSkeletonUsage.md +++ b/build-system/docs-template/xml-template/docs/components/TextSkeletonUsage.md @@ -5,7 +5,7 @@ title: TextSkeleton Компонент представляет из себя контейнер (вертикальный LinearLayout), в котором может отображаться указанное количество строк-заглушек с анимированным мерцанием, представленных компонентом ShimmerLayout, поверх которых возможно наложение текста. -Высота строк и оступы между строками высчитываются на основе переданного стиля текста. +Высота строк и отступы между строками высчитываются на основе переданного стиля текста. Ширина строк настраивается провайдером SkeletonLineWidthProvider и может быть двух видов - на всю ширину контейнера или с учетом псевдо отклонения от ширины (имитируется неравномерность, как при написании текста). @@ -23,17 +23,17 @@ title: TextSkeleton ## Стиль TextSkeleton Существует набор сгенерированных стилей. Так же можно настроить стиль самостоятельно. -Для использования заранее сгененрированного стиля, необходимо через атрибут style указатать стиль из библиотеки (пример выше). +Для использования заранее сгенерированного стиля, необходимо через атрибут style указать стиль из библиотеки (пример выше). По скольку в основе TextSkeleton лежит ShimmerLayout - атрибуты ShimmerLayout так же доступны для конфигурирования. Для настройки стиля TextSkeleton в формате xml предусмотрены следующие атрибуты: |Название атрибута|Описание|Формат данных| |:-:|:-:|:-:| -|sd_shimmer|drawable для отрисоки шиммера|reference| -|sd_shimmerDuration|время движения шиммера - скорочть анимации|integer| +|sd_shimmer|drawable для отрисовки шиммера|reference| +|sd_shimmerDuration|время движения шиммера - скорость анимации|integer| |sd_autoStart|анимация запускается сама, автоматически|boolean| |sd_lineCount|количество строк-заглушек (ShimmerLayout)|integer| -|android:textAppearance|стиль текста, на основе которого будет вычислена высота строки и оступ между строками|reference| +|android:textAppearance|стиль текста, на основе которого будет вычислена высота строки и отступ между строками|reference| Для настройки и корректировки формы скругления используйте [sd_shapeAppearance](../theme/ShapeAppearance.md#sd_shapeappearance). diff --git a/build-system/docs-template/xml-template/docs/components/ToastUsage.md b/build-system/docs-template/xml-template/docs/components/ToastUsage.md index f0de67f3f..0cab4b538 100644 --- a/build-system/docs-template/xml-template/docs/components/ToastUsage.md +++ b/build-system/docs-template/xml-template/docs/components/ToastUsage.md @@ -3,7 +3,7 @@ title: Toast --- Временное всплывающее сообщение, отображаемое с помощью системы оверлеев SDDS UI Kit, -разработааной для удобства позиционирования и анимирования контента. +разработанной для удобства позиционирования и анимирования контента. ## Стиль Toast diff --git a/build-system/docs-template/xml-template/docs/components/ToolBarUsage.md b/build-system/docs-template/xml-template/docs/components/ToolBarUsage.md index a9413d6ca..5118887ad 100644 --- a/build-system/docs-template/xml-template/docs/components/ToolBarUsage.md +++ b/build-system/docs-template/xml-template/docs/components/ToolBarUsage.md @@ -2,12 +2,12 @@ title: ToolBar --- -Вспомогательная панель с набором инструментов для работы на основном экране. Можно задать неогрниченное -количество секций/слотов. Для добавления контента в слоты предоставляются функии addViewToSection и +Вспомогательная панель с набором инструментов для работы на основном экране. Можно задать неограниченное +количество секций/слотов. Для добавления контента в слоты предоставляются функции addViewToSection и addViewsToSection с указанием индекса слота, в который следует добавить контент. Так же возможно добавление через стандартную функцию addView, предварительно, задав контенту ToolBar.LayoutParams и указав нужный индекс через свойство slotIndex. Для добавления контента через xml предусмотрен атрибут sd_slotIndex. Для визуального -рвазделения секций свойством hasDivider включается отображение [Divider](DividerUsage.md). Слоты, а так же +разделения секций свойством hasDivider включается отображение [Divider](DividerUsage.md). Слоты, а так же разделители, в компоненте создаются автоматически, при указании количества, через свойство slotsAmount. В роли слотов в ToolBar используется android.widget.LinearLayout с LayoutParams(WRAP_CONTENT, WRAP_CONTENT) и gravity Gravity.CENTER_VERTICAL для горизонтального `ToolBar`, Gravity.CENTER_HORIZONTAL - для вертикального. Ниже пример @@ -52,7 +52,7 @@ Gravity.CENTER_VERTICAL для горизонтального `ToolBar`, Gravity |sd_slotsAmount|количество слотов для контента|integer| |android:orientation|ориентация компонента|enum (horizontal, vertical)| |sd_dividerMargin|отступ от краев Divider в горизонтальной ориентации marginTop и marginBottom в вертикальной - marginStart и marginEnd|dimension| -|sd_slotPadding|падинг между слотами (устанавливается в конце текущего слота и в начале следующего)|dimension| +|sd_slotPadding|паддинг между слотами (устанавливается в конце текущего слота и в начале следующего)|dimension| Компонентам, добавленным в Layout `ToolBar` доступны следующие атрибуты: diff --git a/playground/sandbox-compose/src/main/kotlin/com/sdds/playground/sandbox/core/compose/MenuItem.kt b/playground/sandbox-compose/src/main/kotlin/com/sdds/playground/sandbox/core/compose/MenuItem.kt index 3710d379e..60956ad00 100644 --- a/playground/sandbox-compose/src/main/kotlin/com/sdds/playground/sandbox/core/compose/MenuItem.kt +++ b/playground/sandbox-compose/src/main/kotlin/com/sdds/playground/sandbox/core/compose/MenuItem.kt @@ -88,8 +88,8 @@ import com.sdds.playground.sandbox.drawer.compose.DrawerPreview import com.sdds.playground.sandbox.drawer.compose.DrawerScreen import com.sdds.playground.sandbox.dropdownmenu.compose.DropdownMenuPreview import com.sdds.playground.sandbox.dropdownmenu.compose.DropdownMenuScreen -import com.sdds.playground.sandbox.file.FilePreview -import com.sdds.playground.sandbox.file.FileScreen +import com.sdds.playground.sandbox.file.compose.FilePreview +import com.sdds.playground.sandbox.file.compose.FileScreen import com.sdds.playground.sandbox.image.compose.ImageScreen import com.sdds.playground.sandbox.image.compose.ImageScreenPreview import com.sdds.playground.sandbox.indicator.compose.IndicatorScreen diff --git a/playground/sandbox-compose/src/main/kotlin/com/sdds/playground/sandbox/core/vs/MenuItem.kt b/playground/sandbox-compose/src/main/kotlin/com/sdds/playground/sandbox/core/vs/MenuItem.kt index 6775c50df..ebae9af02 100644 --- a/playground/sandbox-compose/src/main/kotlin/com/sdds/playground/sandbox/core/vs/MenuItem.kt +++ b/playground/sandbox-compose/src/main/kotlin/com/sdds/playground/sandbox/core/vs/MenuItem.kt @@ -35,6 +35,7 @@ import com.sdds.playground.sandbox.counter.vs.CounterFragment import com.sdds.playground.sandbox.divider.vs.DividerFragment import com.sdds.playground.sandbox.drawer.vs.DrawerFragment import com.sdds.playground.sandbox.dropdownmenu.vs.DropdownMenuFragment +import com.sdds.playground.sandbox.file.vs.FileFragment import com.sdds.playground.sandbox.flow.vs.FlowFragment import com.sdds.playground.sandbox.image.vs.ImageFragment import com.sdds.playground.sandbox.indicator.vs.IndicatorFragment @@ -101,6 +102,7 @@ import com.sdds.testing.vs.counter.counter import com.sdds.testing.vs.divider.divider import com.sdds.testing.vs.drawer.drawer import com.sdds.testing.vs.dropdownmenu.dropdownMenuTrigger +import com.sdds.testing.vs.file.file import com.sdds.testing.vs.flow.FlowUiState import com.sdds.testing.vs.flow.flowLayout import com.sdds.testing.vs.image.image @@ -423,6 +425,10 @@ internal sealed class ComponentScreen( object Autocomplete : ComponentScreen( { item -> fragment(item.route, item.defaultBuilder) }, ) + + object File : ComponentScreen( + { item -> fragment(item.route, item.defaultBuilder) }, + ) } @Suppress("CyclomaticComplexMethod", "LongMethod") @@ -486,6 +492,7 @@ private fun CoreComponent.screen(): ComponentScreen { CoreComponent.MASK -> ComponentScreen.Mask CoreComponent.CAROUSEL -> ComponentScreen.Carousel CoreComponent.AUTOCOMPLETE -> ComponentScreen.Autocomplete + CoreComponent.FILE -> ComponentScreen.File else -> throw NoSuchElementException("Component not implemented") } } @@ -551,6 +558,7 @@ private fun ComponentKey.routeId(): Int? { CoreComponent.MASK -> R.id.nav_note_compact CoreComponent.CAROUSEL -> R.id.nav_carousel CoreComponent.AUTOCOMPLETE -> R.id.nav_autocomplete + CoreComponent.FILE -> R.id.nav_file else -> null }?.let { it + hashCode() } } @@ -662,6 +670,7 @@ internal fun MenuItem.preview(context: Context, style: Int): View { CoreComponent.MASK -> maskedTextField(context, style) CoreComponent.CAROUSEL -> carousel(context, style) CoreComponent.AUTOCOMPLETE -> autocomplete(context, style) + CoreComponent.FILE -> file(context, style) else -> throw NoSuchElementException("Component not implemented") } } diff --git a/playground/sandbox-compose/src/main/kotlin/com/sdds/playground/sandbox/file/FileScreen.kt b/playground/sandbox-compose/src/main/kotlin/com/sdds/playground/sandbox/file/compose/FileScreen.kt similarity index 95% rename from playground/sandbox-compose/src/main/kotlin/com/sdds/playground/sandbox/file/FileScreen.kt rename to playground/sandbox-compose/src/main/kotlin/com/sdds/playground/sandbox/file/compose/FileScreen.kt index 1d6e1ef18..b68f7fe4c 100644 --- a/playground/sandbox-compose/src/main/kotlin/com/sdds/playground/sandbox/file/FileScreen.kt +++ b/playground/sandbox-compose/src/main/kotlin/com/sdds/playground/sandbox/file/compose/FileScreen.kt @@ -1,4 +1,4 @@ -package com.sdds.playground.sandbox.file +package com.sdds.playground.sandbox.file.compose import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.size @@ -64,7 +64,7 @@ internal fun FileScreen(componentKey: ComponentKey = ComponentKey.File) { progress = 0.4f, valueContent = { Icon( - painter = painterResource(id = com.sdds.icons.R.drawable.ic_close_16), + painter = painterResource(id = R.drawable.ic_close_16), contentDescription = "", ) }, @@ -78,7 +78,7 @@ internal fun FileScreen(componentKey: ComponentKey = ComponentKey.File) { }, action = { IconButton( - iconRes = com.sdds.icons.R.drawable.ic_close_24, + iconRes = R.drawable.ic_close_24, onClick = {}, ) }, @@ -130,7 +130,7 @@ internal fun FilePreview(style: FileStyle) { progress = 0.4f, valueContent = { Icon( - painter = painterResource(id = com.sdds.icons.R.drawable.ic_close_16), + painter = painterResource(id = R.drawable.ic_close_16), contentDescription = "", ) }, @@ -138,7 +138,7 @@ internal fun FilePreview(style: FileStyle) { }, action = { IconButton( - iconRes = com.sdds.icons.R.drawable.ic_close_36, + iconRes = R.drawable.ic_close_36, onClick = {}, ) }, diff --git a/playground/sandbox-compose/src/main/kotlin/com/sdds/playground/sandbox/file/FileUiState.kt b/playground/sandbox-compose/src/main/kotlin/com/sdds/playground/sandbox/file/compose/FileUiState.kt similarity index 93% rename from playground/sandbox-compose/src/main/kotlin/com/sdds/playground/sandbox/file/FileUiState.kt rename to playground/sandbox-compose/src/main/kotlin/com/sdds/playground/sandbox/file/compose/FileUiState.kt index 7997c237b..13f424c43 100644 --- a/playground/sandbox-compose/src/main/kotlin/com/sdds/playground/sandbox/file/FileUiState.kt +++ b/playground/sandbox-compose/src/main/kotlin/com/sdds/playground/sandbox/file/compose/FileUiState.kt @@ -1,4 +1,4 @@ -package com.sdds.playground.sandbox.file +package com.sdds.playground.sandbox.file.compose import com.sdds.compose.uikit.FileActionPlacement import com.sdds.playground.sandbox.core.compose.UiState diff --git a/playground/sandbox-compose/src/main/kotlin/com/sdds/playground/sandbox/file/FileViewModel.kt b/playground/sandbox-compose/src/main/kotlin/com/sdds/playground/sandbox/file/compose/FileViewModel.kt similarity index 98% rename from playground/sandbox-compose/src/main/kotlin/com/sdds/playground/sandbox/file/FileViewModel.kt rename to playground/sandbox-compose/src/main/kotlin/com/sdds/playground/sandbox/file/compose/FileViewModel.kt index 7b1ef0845..93a7699fb 100644 --- a/playground/sandbox-compose/src/main/kotlin/com/sdds/playground/sandbox/file/FileViewModel.kt +++ b/playground/sandbox-compose/src/main/kotlin/com/sdds/playground/sandbox/file/compose/FileViewModel.kt @@ -1,4 +1,4 @@ -package com.sdds.playground.sandbox.file +package com.sdds.playground.sandbox.file.compose import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider diff --git a/playground/sandbox-compose/src/main/kotlin/com/sdds/playground/sandbox/file/vs/FileFragment.kt b/playground/sandbox-compose/src/main/kotlin/com/sdds/playground/sandbox/file/vs/FileFragment.kt new file mode 100644 index 000000000..e1c643dfd --- /dev/null +++ b/playground/sandbox-compose/src/main/kotlin/com/sdds/playground/sandbox/file/vs/FileFragment.kt @@ -0,0 +1,56 @@ +package com.sdds.playground.sandbox.file.vs + +import android.view.ContextThemeWrapper +import android.view.ViewGroup.LayoutParams +import android.widget.FrameLayout +import androidx.lifecycle.ViewModelProvider +import com.sdds.playground.sandbox.R +import com.sdds.playground.sandbox.core.vs.ComponentFragment +import com.sdds.testing.databinding.LayoutComponentFileBinding +import com.sdds.testing.vs.file.FileUiState +import com.sdds.testing.vs.file.applyState +import com.sdds.testing.vs.file.fileLayoutBinding +import com.sdds.uikit.File + +/** + * Фрагмент с компонентом File + */ +internal class FileFragment : ComponentFragment() { + + override val viewModelFactory: ViewModelProvider.Factory by lazy { + FileParametersViewModelFactory( + defaultState = getState { FileUiState() }, + componentKey = componentKey, + ) + } + + override val defaultLayoutParams: FrameLayout.LayoutParams by lazy { + FrameLayout.LayoutParams( + resources.getDimensionPixelSize(com.sdds.uikit.R.dimen.sdds_spacer_108x), + LayoutParams.WRAP_CONTENT, + ) + } + + private var fileLayout: LayoutComponentFileBinding? = null + + override fun getComponent(contextWrapper: ContextThemeWrapper): File { + return fileLayoutBinding(contextWrapper) + .also { fileLayout = it }.root + .apply { id = R.id.file } + } + +// override fun getComponent(contextWrapper: ContextThemeWrapper): File { +// return file(contextWrapper) +// } +// +// override fun onComponentUpdate(component: File?, state: FileUiState) = Unit + + override fun onComponentUpdate(component: File?, state: FileUiState) { + fileLayout?.applyState(state) + } + + override fun onDestroyView() { + super.onDestroyView() + fileLayout = null + } +} diff --git a/playground/sandbox-compose/src/main/kotlin/com/sdds/playground/sandbox/file/vs/FileParametersViewModel.kt b/playground/sandbox-compose/src/main/kotlin/com/sdds/playground/sandbox/file/vs/FileParametersViewModel.kt new file mode 100644 index 000000000..35c4037a1 --- /dev/null +++ b/playground/sandbox-compose/src/main/kotlin/com/sdds/playground/sandbox/file/vs/FileParametersViewModel.kt @@ -0,0 +1,118 @@ +package com.sdds.playground.sandbox.file.vs + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.ViewModelProvider +import com.sdds.playground.sandbox.core.integration.component.ComponentKey +import com.sdds.playground.sandbox.core.vs.ComponentViewModel +import com.sdds.playground.sandbox.core.vs.Property +import com.sdds.playground.sandbox.core.vs.enumProperty +import com.sdds.testing.vs.file.ActionPlacement +import com.sdds.testing.vs.file.FileContentType +import com.sdds.testing.vs.file.FileUiState + +/** + * ViewModel для экранов с компонентом File + */ +internal class FileParametersViewModel( + defaultState: FileUiState, + componentKey: ComponentKey, +) : ComponentViewModel(defaultState, componentKey) { + + override fun updateProperty(name: String, value: Any?) { + super.updateProperty(name, value) + + when (FilePropertyName.values().find { it.value == name }) { + FilePropertyName.Label -> updateTitle(value?.toString().orEmpty()) + FilePropertyName.Description -> updateText(value?.toString().orEmpty()) + FilePropertyName.IsLoading -> updateIsLoading((value as? Boolean) == true) + FilePropertyName.ActionPlacement -> updateActionPlacement(ActionPlacement.valueOf(value.toString())) + FilePropertyName.ContentType -> updateContentType(FileContentType.valueOf(value.toString())) + FilePropertyName.HasContentStart -> updateHasContentStart((value as? Boolean) == true) + else -> Unit + } + } + + private fun updateTitle(title: String) { + internalUiState.value = internalUiState.value.copy(label = title) + } + + private fun updateText(text: String) { + internalUiState.value = internalUiState.value.copy(description = text) + } + + private fun updateIsLoading(isLoading: Boolean) { + internalUiState.value = internalUiState.value.copy(isLoading = isLoading) + } + + private fun updateActionPlacement(actionPlacement: ActionPlacement) { + internalUiState.value = internalUiState.value.copy(actionPlacement = actionPlacement) + } + + private fun updateContentType(contentType: FileContentType) { + internalUiState.value = internalUiState.value.copy(contentType = contentType) + } + + private fun updateHasContentStart(hasContentStart: Boolean) { + internalUiState.value = internalUiState.value.copy(hasContentStart = hasContentStart) + } + + override fun FileUiState.toProps(): List> { + val contentType = if (internalUiState.value.hasContentStart) { + listOf>( + enumProperty( + name = FilePropertyName.ContentType.value, + value = contentType, + ), + ) + } else { + emptyList() + } + + return listOfNotNull( + Property.StringProperty( + name = FilePropertyName.Label.value, + value = label, + ), + Property.StringProperty( + name = FilePropertyName.Description.value, + value = description, + ), + Property.BooleanProperty( + name = FilePropertyName.IsLoading.value, + value = isLoading, + ), + enumProperty( + name = FilePropertyName.ActionPlacement.value, + value = actionPlacement, + ), + + Property.BooleanProperty( + name = FilePropertyName.HasContentStart.value, + value = hasContentStart, + ), + ) + contentType + } + + private enum class FilePropertyName(val value: String) { + Label("label"), + Description("description"), + IsLoading("isLoading"), + ActionPlacement("actionPlacement"), + ContentType("contentType"), + HasContentStart("hasContentStart"), + } +} + +/** + * Фабрика [FileParametersViewModel] + */ +internal class FileParametersViewModelFactory( + private val defaultState: FileUiState = FileUiState(), + private val componentKey: ComponentKey, +) : ViewModelProvider.Factory { + + @Suppress("UNCHECKED_CAST") + override fun create(modelClass: Class): T { + return FileParametersViewModel(defaultState, componentKey) as T + } +} diff --git a/playground/sandbox-compose/src/main/res/values/components_ids.xml b/playground/sandbox-compose/src/main/res/values/components_ids.xml index 119403a44..0a6cc3922 100644 --- a/playground/sandbox-compose/src/main/res/values/components_ids.xml +++ b/playground/sandbox-compose/src/main/res/values/components_ids.xml @@ -5,6 +5,7 @@ + diff --git a/playground/sandbox-compose/src/main/res/values/routes.xml b/playground/sandbox-compose/src/main/res/values/routes.xml index 40df3975c..6e7ea7152 100644 --- a/playground/sandbox-compose/src/main/res/values/routes.xml +++ b/playground/sandbox-compose/src/main/res/values/routes.xml @@ -60,4 +60,5 @@ + \ No newline at end of file diff --git a/playground/sandbox-sdds-serv-integration/src/main/kotlin/com/sdds/playground/sandbox/sdds/serv/integration/view/SddsServFileCircularProgressVariationsView.kt b/playground/sandbox-sdds-serv-integration/src/main/kotlin/com/sdds/playground/sandbox/sdds/serv/integration/view/SddsServFileCircularProgressVariationsView.kt new file mode 100644 index 000000000..cc5091117 --- /dev/null +++ b/playground/sandbox-sdds-serv-integration/src/main/kotlin/com/sdds/playground/sandbox/sdds/serv/integration/view/SddsServFileCircularProgressVariationsView.kt @@ -0,0 +1,22 @@ +package com.sdds.playground.sandbox.sdds.serv.integration.view + +import com.sdds.playground.sandbox.core.integration.ViewStyleProvider +import com.sdds.serv.R as DsR + +internal object SddsServFileCircularProgressVariationsView : ViewStyleProvider() { + override val variations: Map = + mapOf( + "Xs" to DsR.style.Serv_Sdds_ComponentOverlays_FileCircularProgressXs, + "Xs.Default" to DsR.style.Serv_Sdds_ComponentOverlays_FileCircularProgressXsDefault, + "Xs.Negative" to DsR.style.Serv_Sdds_ComponentOverlays_FileCircularProgressXsNegative, + "S" to DsR.style.Serv_Sdds_ComponentOverlays_FileCircularProgressS, + "S.Default" to DsR.style.Serv_Sdds_ComponentOverlays_FileCircularProgressSDefault, + "S.Negative" to DsR.style.Serv_Sdds_ComponentOverlays_FileCircularProgressSNegative, + "M" to DsR.style.Serv_Sdds_ComponentOverlays_FileCircularProgressM, + "M.Default" to DsR.style.Serv_Sdds_ComponentOverlays_FileCircularProgressMDefault, + "M.Negative" to DsR.style.Serv_Sdds_ComponentOverlays_FileCircularProgressMNegative, + "L" to DsR.style.Serv_Sdds_ComponentOverlays_FileCircularProgressL, + "L.Default" to DsR.style.Serv_Sdds_ComponentOverlays_FileCircularProgressLDefault, + "L.Negative" to DsR.style.Serv_Sdds_ComponentOverlays_FileCircularProgressLNegative, + ) +} diff --git a/playground/sandbox-sdds-serv-integration/src/main/kotlin/com/sdds/playground/sandbox/sdds/serv/integration/view/SddsServFileLinearProgressVariationsView.kt b/playground/sandbox-sdds-serv-integration/src/main/kotlin/com/sdds/playground/sandbox/sdds/serv/integration/view/SddsServFileLinearProgressVariationsView.kt new file mode 100644 index 000000000..61e6e6486 --- /dev/null +++ b/playground/sandbox-sdds-serv-integration/src/main/kotlin/com/sdds/playground/sandbox/sdds/serv/integration/view/SddsServFileLinearProgressVariationsView.kt @@ -0,0 +1,22 @@ +package com.sdds.playground.sandbox.sdds.serv.integration.view + +import com.sdds.playground.sandbox.core.integration.ViewStyleProvider +import com.sdds.serv.R as DsR + +internal object SddsServFileLinearProgressVariationsView : ViewStyleProvider() { + override val variations: Map = + mapOf( + "Xs" to DsR.style.Serv_Sdds_ComponentOverlays_FileLinearProgressXs, + "Xs.Default" to DsR.style.Serv_Sdds_ComponentOverlays_FileLinearProgressXsDefault, + "Xs.Negative" to DsR.style.Serv_Sdds_ComponentOverlays_FileLinearProgressXsNegative, + "S" to DsR.style.Serv_Sdds_ComponentOverlays_FileLinearProgressS, + "S.Default" to DsR.style.Serv_Sdds_ComponentOverlays_FileLinearProgressSDefault, + "S.Negative" to DsR.style.Serv_Sdds_ComponentOverlays_FileLinearProgressSNegative, + "M" to DsR.style.Serv_Sdds_ComponentOverlays_FileLinearProgressM, + "M.Default" to DsR.style.Serv_Sdds_ComponentOverlays_FileLinearProgressMDefault, + "M.Negative" to DsR.style.Serv_Sdds_ComponentOverlays_FileLinearProgressMNegative, + "L" to DsR.style.Serv_Sdds_ComponentOverlays_FileLinearProgressL, + "L.Default" to DsR.style.Serv_Sdds_ComponentOverlays_FileLinearProgressLDefault, + "L.Negative" to DsR.style.Serv_Sdds_ComponentOverlays_FileLinearProgressLNegative, + ) +} diff --git a/playground/sandbox-sdds-serv-integration/src/main/kotlin/com/sdds/playground/sandbox/sdds/serv/integration/view/SddsServViewComponents.kt b/playground/sandbox-sdds-serv-integration/src/main/kotlin/com/sdds/playground/sandbox/sdds/serv/integration/view/SddsServViewComponents.kt index d060be951..7d61a1994 100644 --- a/playground/sandbox-sdds-serv-integration/src/main/kotlin/com/sdds/playground/sandbox/sdds/serv/integration/view/SddsServViewComponents.kt +++ b/playground/sandbox-sdds-serv-integration/src/main/kotlin/com/sdds/playground/sandbox/sdds/serv/integration/view/SddsServViewComponents.kt @@ -399,5 +399,12 @@ object SddsServViewComponents : ComponentsProviderView() { "Carousel" to SddsServCarouselVariationsView, ), ), + ViewComponent( + ComponentKey.File, + mapOf( + "FileCircularProgress" to SddsServFileCircularProgressVariationsView, + "FileLinearProgress" to SddsServFileLinearProgressVariationsView, + ), + ), ).associateBy { it.key } } diff --git a/sdds-core/plugin_theme_builder/src/main/kotlin/com/sdds/plugin/themebuilder/internal/components/file/FileConfigDelegate.kt b/sdds-core/plugin_theme_builder/src/main/kotlin/com/sdds/plugin/themebuilder/internal/components/file/FileConfigDelegate.kt index 45eaff24d..f3b5f0de3 100644 --- a/sdds-core/plugin_theme_builder/src/main/kotlin/com/sdds/plugin/themebuilder/internal/components/file/FileConfigDelegate.kt +++ b/sdds-core/plugin_theme_builder/src/main/kotlin/com/sdds/plugin/themebuilder/internal/components/file/FileConfigDelegate.kt @@ -3,9 +3,11 @@ package com.sdds.plugin.themebuilder.internal.components.file import com.sdds.plugin.themebuilder.internal.TargetPackage import com.sdds.plugin.themebuilder.internal.builder.KtFileBuilder import com.sdds.plugin.themebuilder.internal.components.ComponentConfigDelegate +import com.sdds.plugin.themebuilder.internal.components.ComponentStyleGenerator import com.sdds.plugin.themebuilder.internal.components.StyleGeneratorDependencies import com.sdds.plugin.themebuilder.internal.components.base.Component import com.sdds.plugin.themebuilder.internal.components.file.compose.FileComposeVariationGenerator +import com.sdds.plugin.themebuilder.internal.components.file.view.FileStyleGeneratorView import com.sdds.plugin.themebuilder.internal.serializer.Serializer import com.sdds.plugin.themebuilder.internal.utils.decode import com.sdds.plugin.themebuilder.internal.utils.techToCamelCase @@ -21,7 +23,18 @@ internal class FileConfigDelegate : override fun createViewGenerator( deps: StyleGeneratorDependencies, component: Component, - ) = null + ): ComponentStyleGenerator? { + return FileStyleGeneratorView( + xmlBuilderFactory = deps.xmlBuilderFactory, + resourceReferenceProvider = deps.resourceReferenceProvider, + dimensAggregator = deps.dimensAggregator, + outputResDir = deps.outputResDir, + resourcePrefix = deps.resourcePrefixConfig.resourcePrefix, + viewColorStateGeneratorFactory = deps.viewColorStateGeneratorFactory, + colorStateListGeneratorFactory = deps.colorStateListGeneratorFactory, + styleComponentName = component.styleName.techToCamelCase(), + ) + } override fun createComposeGenerator( deps: StyleGeneratorDependencies, @@ -29,9 +42,11 @@ internal class FileConfigDelegate : ) = FileComposeVariationGenerator( actionButtonStylesPackage = "${deps.packageResolver.getPackage(TargetPackage.STYLES)}.iconbutton", progressBarStylesPackage = "${deps.packageResolver.getPackage(TargetPackage.STYLES)}.progressbar", - circularProgressBarStylesPackage = "${deps.packageResolver.getPackage( - TargetPackage.STYLES, - )}.circularprogressbar", + circularProgressBarStylesPackage = "${ + deps.packageResolver.getPackage( + TargetPackage.STYLES, + ) + }.circularprogressbar", themeClassName = deps.themeClassName, themePackage = deps.packageResolver.getPackage(TargetPackage.THEME), dimensionsConfig = deps.dimensionsConfig, diff --git a/sdds-core/plugin_theme_builder/src/main/kotlin/com/sdds/plugin/themebuilder/internal/components/file/view/FileStyleGeneratorView.kt b/sdds-core/plugin_theme_builder/src/main/kotlin/com/sdds/plugin/themebuilder/internal/components/file/view/FileStyleGeneratorView.kt new file mode 100644 index 000000000..7cbee88d0 --- /dev/null +++ b/sdds-core/plugin_theme_builder/src/main/kotlin/com/sdds/plugin/themebuilder/internal/components/file/view/FileStyleGeneratorView.kt @@ -0,0 +1,135 @@ +package com.sdds.plugin.themebuilder.internal.components.file.view + +import com.sdds.plugin.themebuilder.internal.builder.XmlResourcesDocumentBuilder +import com.sdds.plugin.themebuilder.internal.components.base.Color +import com.sdds.plugin.themebuilder.internal.components.base.Dimension +import com.sdds.plugin.themebuilder.internal.components.base.VariationNode +import com.sdds.plugin.themebuilder.internal.components.base.view.ProvidableColorProperty +import com.sdds.plugin.themebuilder.internal.components.base.view.ProvidableProperty +import com.sdds.plugin.themebuilder.internal.components.base.view.ViewVariationGenerator +import com.sdds.plugin.themebuilder.internal.components.base.view.camelCaseValue +import com.sdds.plugin.themebuilder.internal.components.file.FileProperties +import com.sdds.plugin.themebuilder.internal.dimens.DimensAggregator +import com.sdds.plugin.themebuilder.internal.factory.ColorStateListGeneratorFactory +import com.sdds.plugin.themebuilder.internal.factory.ViewColorStateGeneratorFactory +import com.sdds.plugin.themebuilder.internal.factory.XmlResourcesDocumentBuilderFactory +import com.sdds.plugin.themebuilder.internal.utils.ResourceReferenceProvider +import org.w3c.dom.Element +import java.io.File + +internal class FileStyleGeneratorView( + xmlBuilderFactory: XmlResourcesDocumentBuilderFactory, + resourceReferenceProvider: ResourceReferenceProvider, + dimensAggregator: DimensAggregator, + outputResDir: File, + resourcePrefix: String, + styleComponentName: String, + coreComponentName: String = CORE_COMPONENT_NAME, + componentParent: String = COMPONENT_PARENT, + viewColorStateGeneratorFactory: ViewColorStateGeneratorFactory, + colorStateListGeneratorFactory: ColorStateListGeneratorFactory, + defStyleAttr: String = DEF_STYLE_ATTR, +) : ViewVariationGenerator( + xmlBuilderFactory = xmlBuilderFactory, + resourceReferenceProvider = resourceReferenceProvider, + dimensAggregator = dimensAggregator, + outputResDir = outputResDir, + resourcePrefix = resourcePrefix, + styleComponentName = styleComponentName, + coreComponentName = coreComponentName, + componentParent = componentParent, + viewColorStateGeneratorFactory = viewColorStateGeneratorFactory, + colorStateListGeneratorFactory = colorStateListGeneratorFactory, + defStyleAttr = defStyleAttr, +) { + + override fun onCreateStyle( + variation: String, + rootDocument: XmlResourcesDocumentBuilder, + styleElement: Element, + variationNode: VariationNode, + props: FileProperties, + ) = with(styleElement) { + FileDimensionsProperty.values().forEach { + addDimensionProperty(it, variation, variationNode) + } + addProps(variation, props) + FileColorProperty.values().forEach { + addColorProperty(it, variation, variationNode) + } + } + + private fun Element.addProps(variation: String, props: FileProperties) { + props.descriptionStyle?.let { typographyAttribute("sd_descriptionAppearance", it.value) } + props.labelStyle?.let { typographyAttribute("sd_labelAppearance", it.value) } + props.progressBarStyle?.let { + componentOverlayAttribute("sd_progressBarStyleOverlay", it.camelCaseValue("")) + } + props.circularProgressBarStyle?.let { + componentOverlayAttribute("sd_circularProgressBarStyleOverlay", it.camelCaseValue("")) + } + props.actionButtonStyle?.let { + componentOverlayAttribute("sd_iconButtonStyleOverlay", it.camelCaseValue("")) + } + props.actionPlacement?.let { valueAttribute("sd_actionPlacement", it.value.asActionPlacement()) } + props.progressPlacement?.let { valueAttribute("sd_progressPlacement", it.value.asProgressPlacement()) } + } + + private enum class FileDimensionsProperty( + override val attribute: String, + override val fileSuffix: String, + ) : ProvidableProperty { + START_CONTENT_PADDING("sd_contentStartPadding", "content_start_padding"), + END_CONTENT_PADDING("sd_contentEndPadding", "content_end_padding"), + BOTTOM_CONTENT_PADDING("sd_contentBottomPadding", "content_bottom_padding"), + DESCRIPTION_PADDING("sd_descriptionPadding", "description_padding"), + ; + + override fun provide(owner: FileProperties): Dimension? { + return when (this) { + START_CONTENT_PADDING -> owner.startContentPadding + END_CONTENT_PADDING -> owner.endContentPadding + BOTTOM_CONTENT_PADDING -> owner.bottomContentPadding + DESCRIPTION_PADDING -> owner.descriptionPadding + } + } + } + + private enum class FileColorProperty( + override val attribute: String, + override val colorFileSuffix: String, + ) : ProvidableColorProperty { + ICON_COLOR("sd_iconTint", "icon_tint"), + DESCRIPTION_COLOR("sd_descriptionColor", "description_color"), + LABEL_COLOR("sd_labelColor", "label_color"), + ; + + override fun provide(owner: FileProperties): Color? { + return when (this) { + ICON_COLOR -> owner.iconColor + DESCRIPTION_COLOR -> owner.descriptionColor + LABEL_COLOR -> owner.labelColor + } + } + } + + private companion object { + const val CORE_COMPONENT_NAME = "File" + const val DEF_STYLE_ATTR = "sd_fileStyle" + const val COMPONENT_PARENT = "Sdds.Components.File" + + fun String.asActionPlacement(): String { + return when (this) { + "end" -> "end" + else -> "start" + } + } + + fun String.asProgressPlacement(): String { + return when (this) { + "inner" -> "inner" + else -> "outer" + } + } + } +} diff --git a/sdds-core/testing/src/main/kotlin/com/sdds/testing/vs/file/FileFactory.kt b/sdds-core/testing/src/main/kotlin/com/sdds/testing/vs/file/FileFactory.kt new file mode 100644 index 000000000..5ebc5bb3e --- /dev/null +++ b/sdds-core/testing/src/main/kotlin/com/sdds/testing/vs/file/FileFactory.kt @@ -0,0 +1,80 @@ +package com.sdds.testing.vs.file + +import android.content.Context +import android.view.LayoutInflater +import androidx.annotation.StyleRes +import androidx.core.view.isVisible +import com.bumptech.glide.Glide +import com.bumptech.glide.load.resource.bitmap.RoundedCorners +import com.sdds.testing.databinding.LayoutComponentFileBinding +import com.sdds.testing.vs.styleWrapper +import com.sdds.uikit.File +import com.sdds.uikit.dp + +/** + * Создает [File] + * @param context контекст + * @param style стиль + * @param state состояние + */ +fun file( + context: Context, + @StyleRes style: Int? = null, + state: FileUiState = FileUiState(), +): File { + return fileLayoutBinding(context.styleWrapper(style)) + .applyState(state) + .root +} + +/** + * Фабрика для создания [LayoutComponentFileBinding] + */ +fun fileLayoutBinding( + context: Context, +): LayoutComponentFileBinding { + return LayoutComponentFileBinding.inflate(LayoutInflater.from(context)) +} + +/** + * Применяет [FileUiState] к [LayoutComponentFileBinding] + */ +fun LayoutComponentFileBinding.applyState(state: FileUiState?): LayoutComponentFileBinding = apply { + state ?: return this@apply + + file.apply { + isLoading = state.isLoading + actionPlacement = state.actionPlacement.toFileActionPlacement() + } + + componentFileLabel.apply { + text = state.label + isVisible = state.label.isNotBlank() + } + + componentFileDescription.apply { + text = state.description + isVisible = state.description.isNotBlank() + } + + componentFileIcon.apply { + isVisible = state.contentType == + FileContentType.Icon && + state.hasContentStart && + state.actionPlacement != ActionPlacement.Start + } + + componentFileImage.apply { + isVisible = state.contentType == + FileContentType.Image && + state.hasContentStart && + state.actionPlacement != ActionPlacement.Start + Glide.with(this) + .load("https://cdn.costumewall.com/wp-content/uploads/2018/09/michael-scott.jpg") + .override(36.dp) + .transform( + RoundedCorners(5.dp), + ) + .into(this) + } +} diff --git a/sdds-core/testing/src/main/kotlin/com/sdds/testing/vs/file/FileUiState.kt b/sdds-core/testing/src/main/kotlin/com/sdds/testing/vs/file/FileUiState.kt new file mode 100644 index 000000000..cd1fa16be --- /dev/null +++ b/sdds-core/testing/src/main/kotlin/com/sdds/testing/vs/file/FileUiState.kt @@ -0,0 +1,61 @@ +package com.sdds.testing.vs.file + +import android.os.Parcelable +import com.sdds.testing.vs.UiState +import com.sdds.uikit.File +import kotlinx.parcelize.Parcelize + +/** + * Состояние компонента File + * @property variant вариация стиля + * @property appearance вариация компонента + * @property label лэйбл + * @property description описание + * @property isLoading состояние загрузки + * @property hasContentStart отображение иконки или изображения (только для песочницы) + * @property actionPlacement расположение экшн компонента + * @property contentType тип контента (иконка или изображение) + */ +@Parcelize +data class FileUiState( + override val variant: String = "", + override val appearance: String = "", + val label: String = "Label", + val description: String = "Description", + val isLoading: Boolean = false, + val hasContentStart: Boolean = true, + val actionPlacement: ActionPlacement = ActionPlacement.End, + val contentType: FileContentType = FileContentType.Icon, +) : UiState, Parcelable { + override fun updateVariant(appearance: String, variant: String): UiState { + return copy(appearance = appearance, variant = variant) + } +} + +/** + * Расположение action в [File] + */ +@Parcelize +enum class ActionPlacement : Parcelable { + Start, + End, +} + +/** + * Преобразует [ActionPlacement] в [File].ACTION_PLACEMENT + */ +fun ActionPlacement.toFileActionPlacement(): Int { + return when (this) { + ActionPlacement.Start -> File.ACTION_PLACEMENT_START + ActionPlacement.End -> File.ACTION_PLACEMENT_END + } +} + +/** + * Тип контента в [File] + */ +@Parcelize +enum class FileContentType : Parcelable { + Icon, + Image, +} diff --git a/sdds-core/testing/src/main/res/layout/layout_component_file.xml b/sdds-core/testing/src/main/res/layout/layout_component_file.xml new file mode 100644 index 000000000..ae7ad8b00 --- /dev/null +++ b/sdds-core/testing/src/main/res/layout/layout_component_file.xml @@ -0,0 +1,75 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/sdds-core/testing/src/main/res/values/components_id.xml b/sdds-core/testing/src/main/res/values/components_id.xml index 705a83551..fbda628c5 100644 --- a/sdds-core/testing/src/main/res/values/components_id.xml +++ b/sdds-core/testing/src/main/res/values/components_id.xml @@ -59,4 +59,5 @@ + \ No newline at end of file diff --git a/sdds-core/uikit/src/main/kotlin/com/sdds/uikit/CellLayout.kt b/sdds-core/uikit/src/main/kotlin/com/sdds/uikit/CellLayout.kt index b296928ec..38beb0623 100644 --- a/sdds-core/uikit/src/main/kotlin/com/sdds/uikit/CellLayout.kt +++ b/sdds-core/uikit/src/main/kotlin/com/sdds/uikit/CellLayout.kt @@ -534,24 +534,24 @@ open class CellLayout @JvmOverloads constructor( } private fun TextView.applyLabelRole() { - setTextAppearancesList(_labelAppearance) + _labelAppearance?.let { setTextAppearancesList(_labelAppearance) } _labelColor?.let(::setTextColor) TextViewCompat.setCompoundDrawableTintList(this, _labelColor) - state = ViewState.SECONDARY + state = if (colorState == null) ViewState.PRIMARY else null } private fun TextView.applyTitleRole() { - setTextAppearancesList(_titleAppearance) + _titleAppearance?.let { setTextAppearancesList(it) } _titleColor?.let(::setTextColor) TextViewCompat.setCompoundDrawableTintList(this, _titleColor) - state = ViewState.PRIMARY + state = if (colorState == null) ViewState.PRIMARY else null } private fun TextView.applySubtitleRole() { - setTextAppearancesList(_subtitleAppearance) + _subtitleAppearance?.let { setTextAppearancesList(it) } _subtitleColor?.let(::setTextColor) TextViewCompat.setCompoundDrawableTintList(this, _subtitleColor) - state = ViewState.SECONDARY + state = if (colorState == null) ViewState.PRIMARY else null } private fun View.applyDisclosureRole() { diff --git a/sdds-core/uikit/src/main/kotlin/com/sdds/uikit/File.kt b/sdds-core/uikit/src/main/kotlin/com/sdds/uikit/File.kt new file mode 100644 index 000000000..83b792469 --- /dev/null +++ b/sdds-core/uikit/src/main/kotlin/com/sdds/uikit/File.kt @@ -0,0 +1,732 @@ +package com.sdds.uikit + +import android.content.Context +import android.content.res.ColorStateList +import android.util.AttributeSet +import android.view.ContextThemeWrapper +import android.view.Gravity +import android.view.View +import android.view.ViewGroup +import android.widget.LinearLayout +import androidx.core.content.withStyledAttributes +import androidx.core.view.children +import androidx.core.view.isVisible +import androidx.core.widget.TextViewCompat +import com.sdds.uikit.CellLayout.CellContent +import com.sdds.uikit.File.Companion.ACTION_PLACEMENT_END +import com.sdds.uikit.File.Companion.ACTION_PLACEMENT_START +import com.sdds.uikit.File.Companion.PROGRESS_PLACEMENT_INNER +import com.sdds.uikit.File.Companion.PROGRESS_PLACEMENT_OUTER +import com.sdds.uikit.colorstate.ColorState +import com.sdds.uikit.colorstate.ColorStateHolder +import com.sdds.uikit.statelist.StyleStateList +import com.sdds.uikit.statelist.getStyleStateList + +/** + * Компонент [File] позволяет компоновать дочерние [View] согласно заданным им ролей [FileContent] при помощи + * атрибута [R.styleable.File_Layout_layout_fileContent]. Предназначен для отображения информации о загружаемом + * контенте, показывая прогресс загрузки с помощью компонентов [ProgressBar] и [CircularProgressBar] + * @param context контекст + * @param attrs аттрибуты view + * @param defStyleAttr аттрибут стиля по умолчанию + */ + +open class File @JvmOverloads constructor( + context: Context, + attrs: AttributeSet? = null, + defStyleAttr: Int = R.attr.sd_fileStyle, + defStyleRes: Int = R.style.Sdds_Components_File, +) : LinearLayout( + wrapper(context, attrs, defStyleAttr, defStyleRes), + attrs, + defStyleAttr, + defStyleRes, +), + ColorStateHolder { + + private val cell: CellLayout = CellLayout(context, null, 0, 0) + private var _contentStartPadding: Int = 0 + private var _contentEndPadding: Int = 0 + private var _contentBottomPadding: Int = 0 + private var _descriptionPadding: Int = 0 + private var labelAppearance: StyleStateList? = null + private var labelColor: ColorStateList? = null + private var descriptionAppearance: StyleStateList? = null + private var descriptionColor: ColorStateList? = null + private var iconTint: ColorStateList? = null + private var _progressPlacement: Int = PROGRESS_PLACEMENT_INNER + private var _actionPlacement: Int = ACTION_PLACEMENT_START + private var _isLoading: Boolean = false + + init { + orientation = VERTICAL + context.withStyledAttributes(attrs, R.styleable.File, defStyleAttr, defStyleRes) { + _contentStartPadding = getDimensionPixelSize(R.styleable.File_sd_contentStartPadding, 0) + _contentEndPadding = getDimensionPixelSize(R.styleable.File_sd_contentEndPadding, 0) + _contentBottomPadding = getDimensionPixelSize(R.styleable.File_sd_contentBottomPadding, 0) + _descriptionPadding = getDimensionPixelSize(R.styleable.File_sd_descriptionPadding, 0) + labelAppearance = getStyleStateList(context, R.styleable.File_sd_labelAppearance) + descriptionAppearance = getStyleStateList(context, R.styleable.File_sd_descriptionAppearance) + labelColor = getColorStateList(R.styleable.File_sd_labelColor) + descriptionColor = getColorStateList(R.styleable.File_sd_descriptionColor) + iconTint = getColorStateList(R.styleable.File_sd_iconTint) + _actionPlacement = getInt(R.styleable.File_sd_actionPlacement, 0) + _progressPlacement = getInt(R.styleable.File_sd_progressPlacement, 0) + _isLoading = getBoolean(R.styleable.File_sd_isLoading, false) + } + addView(cell) + cell.apply { + contentStartPadding = this@File._contentStartPadding + contentEndPadding = this@File._contentEndPadding + gravity = Gravity.CENTER_VERTICAL + } + } + + /** + * Выравнивание дочерних элементов относительно строки, в которой они находятся. + * @see Gravity + */ + open var contentGravity: Int + get() = cell.gravity + set(value) { + cell.gravity = value + } + + /** + * Отступ между контентом в начале [File] и компонентами с ролью Label/Description + */ + open var contentStartPadding: Int + get() = _contentStartPadding + set(value) { + if (_contentStartPadding != value) { + _contentStartPadding = value + cell.contentStartPadding = value + } + } + + /** + * Отступ между компонентами с ролью Label/Description и контентом в конце [File] + */ + open var contentEndPadding: Int + get() = _contentEndPadding + set(value) { + if (_contentEndPadding != value) { + _contentEndPadding = value + cell.contentEndPadding = value + } + } + + /** + * Отступ между контентом и горизонтальным прогрессом, если [progressPlacement] = + * [PROGRESS_PLACEMENT_OUTER] + */ + open var contentBottomPadding: Int + get() = _contentBottomPadding + set(value) { + if (_contentBottomPadding != value) { + _contentBottomPadding = value + setContentBottomPadding() + } + } + + /** + * Отступ между компонентами с ролями Label и Description + */ + open var descriptionPadding: Int + get() = _descriptionPadding + set(value) { + if (_descriptionPadding != value) { + _descriptionPadding = value + setDescriptionPadding() + } + } + + /** + * Расположение прогресса + */ + open var progressPlacement: Int + get() = _progressPlacement + set(value) { + if (_progressPlacement != value) { + _progressPlacement = value + } + setContentVisibility() + } + + /** + * Расположение контента предполагающего взаимодействие с ним + */ + open var actionPlacement: Int + get() = _actionPlacement + set(value) { + if (_actionPlacement != value) { + _actionPlacement = value + } + changeActionPlacement() + setCellContentVisibility() + } + + /** + * Находится ли компонент в процессе загрузки в данный момент, + * если true - отображается компонент прогресса в зависимости от + * [progressPlacement] + */ + open var isLoading: Boolean + get() = _isLoading + set(value) { + if (_isLoading != value) { + _isLoading = value + } + setContentVisibility() + } + + /** + * Устанавливает Label, при этом все ранее установленные Label будут удалены + * @param textView - [TextView] вью с текстом + * @param params - [FileLayoutParams] лэйаут параметры для textview, если не заданы, + * ширина и высота будет установлена как [ViewGroup.LayoutParams.WRAP_CONTENT]. + * Роль назначается автоматически как [FileContent.LABEL] + */ + open fun setLabel(textView: TextView, params: FileLayoutParams? = null) { + removeLabel() + addView( + textView, + params ?: FileLayoutParams( + LayoutParams.WRAP_CONTENT, + LayoutParams.WRAP_CONTENT, + FileContent.LABEL, + ), + ) + } + + /** + * Устанавливает Description, при этом все ранее установленные Description будут удалены + * @param textView - [TextView] вью с текстом + * @param params - [FileLayoutParams] лэйаут параметры для textview, если не заданы, + * ширина и высота будет установлена как [ViewGroup.LayoutParams.WRAP_CONTENT]. + * Роль назначается автоматически как [FileContent.DESCRIPTION] + */ + open fun setDescription(textView: TextView, params: FileLayoutParams? = null) { + removeDescription() + addView( + textView, + params ?: FileLayoutParams( + LayoutParams.WRAP_CONTENT, + LayoutParams.WRAP_CONTENT, + FileContent.DESCRIPTION, + ), + ) + } + + /** + * Устанавливает Action - компонент предполагающий взаимодействие (например [LinkButton]), + * при этом все ранее установленные Action будут удалены + * @param view - [View] компонент для взаимодействия + * @param params - [FileLayoutParams] лэйаут параметры для view, если не заданы, + * ширина и высота будет установлена как [ViewGroup.LayoutParams.WRAP_CONTENT]. + * Роль назначается автоматически как [FileContent.ACTION] + */ + open fun setAction(view: View, params: FileLayoutParams? = null) { + removeActions() + addView( + view, + params ?: FileLayoutParams( + LayoutParams.WRAP_CONTENT, + LayoutParams.WRAP_CONTENT, + FileContent.ACTION, + ), + ) + } + + /** + * Устанавливает в качестве прогресса компонент [CircularProgressBar], + * при этом все ранее установленные [CircularProgressBar] будут удалены + * @param progress - [CircularProgressBar] круглый прогресс + * @param params - [FileLayoutParams] лэйаут параметры для progress, если не заданы, + * ширина и высота будет установлена как [ViewGroup.LayoutParams.WRAP_CONTENT]. + * Роль назначается автоматически как [FileContent.PROGRESS] + */ + open fun setCircularProgress(progress: CircularProgressBar, params: FileLayoutParams? = null) { + removeCircularProgress() + addView( + progress, + params ?: FileLayoutParams( + LayoutParams.WRAP_CONTENT, + LayoutParams.WRAP_CONTENT, + FileContent.PROGRESS, + ), + ) + } + + /** + * Устанавливает в качестве прогресса компонент [ProgressBar], + * при этом все ранее установленные [ProgressBar] будут удалены + * @param progress - [ProgressBar] горизонтальный прогресс + * @param params - [FileLayoutParams] лэйаут параметры для progress, если не заданы, + * ширина и высота будет установлена как [ViewGroup.LayoutParams.WRAP_CONTENT]. + * Роль назначается автоматически как [FileContent.PROGRESS] + */ + open fun setHorizontalProgress(progress: ProgressBar, params: FileLayoutParams? = null) { + removeHorizontalProgress() + addView( + progress, + params ?: FileLayoutParams( + LayoutParams.WRAP_CONTENT, + LayoutParams.WRAP_CONTENT, + FileContent.PROGRESS, + ), + ) + } + + /** + * Устанавливает в качестве контента в начале - [ImageView], + * будьте внимательны, если вы использовали несколько [ImageView], они будут удалены + * (например одна из вью использовалась для отображения иконки а другая - для изображения) + * @param image - [ImageView] + * @param asIcon - установите true, если собираетесь использовать [ImageView] для отображения + * иконок, в этом случае к иконкам будет применен iconTint, заданный в стиле, через атрибут + * [R.styleable.File_sd_iconTint] + * @param params - [FileLayoutParams] лэйаут параметры для image, если не заданы, + * ширина и высота будет установлена как [ViewGroup.LayoutParams.WRAP_CONTENT]. + * Роль назначается автоматически как [FileContent.IMAGE] + */ + open fun setImage(image: ImageView, asIcon: Boolean, params: FileLayoutParams? = null) { + removeImageAndIcon() + addView( + image, + params ?: FileLayoutParams( + LayoutParams.WRAP_CONTENT, + LayoutParams.WRAP_CONTENT, + fileContent = if (asIcon) FileContent.ICON else FileContent.IMAGE, + ), + ) + } + + /** + * Удаляет все установленные [ProgressBar] + */ + open fun removeHorizontalProgress() { + children + .filter { it is ProgressBar } + .toList() + .forEach(::removeView) + } + + /** + * Удаляет все установленные [CircularProgressBar] + */ + open fun removeCircularProgress() { + cell.children + .filter { it is CircularProgressBar } + .toList() + .forEach { cell.removeView(it) } + } + + /** + * Удаляет все установленные вью с ролью [FileContent.ACTION] + */ + open fun removeActions() { + cell.children + .filter { + (it.layoutParams as? CellLayout.LayoutParams)?.cellContent == + when (_actionPlacement) { + ACTION_PLACEMENT_END -> CellContent.END + else -> CellContent.START + } + } + .filter { it !is ImageView } + .toList() + .forEach { cell.removeView(it) } + } + + /** + * Удаляет все установленные вью с ролью [FileContent.IMAGE] + */ + open fun removeImageAndIcon() { + cell.children + .filter { it is ImageView } + .toList() + .forEach { cell.removeView(it) } + } + + /** + * Удаляет все установленные вью с ролью [FileContent.LABEL] + */ + open fun removeLabel() { + cell.children + .filter { it is TextView } + .toList() + .forEach { view -> + val lp = view.layoutParams as? CellLayout.LayoutParams + if (lp?.cellContent == CellContent.TITLE) cell.removeView(view) + } + } + + /** + * Удаляет все установленные вью с ролью [FileContent.DESCRIPTION] + */ + open fun removeDescription() { + cell.children + .filter { it is TextView } + .toList() + .forEach { view -> + val lp = view.layoutParams as? CellLayout.LayoutParams + if (lp?.cellContent == CellContent.SUBTITLE) cell.removeView(view) + } + } + + override fun addView(child: View?, index: Int, params: ViewGroup.LayoutParams?) { + if (child == cell) { + super.addView(child, childCount, params) + return + } + val fileParams = params as? FileLayoutParams ?: return + child?.applyContentRole(fileParams) + + if (fileParams.fileContent == FileContent.PROGRESS && child is ProgressBar) { + super.addView(child, childCount, params) + } else { + val cellParams = convertToCellParams(fileParams) + cell.addView(child, cell.childCount, cellParams) + } + setContentVisibility() + } + + override fun removeView(view: View?) { + if (view == cell) return + super.removeView(view) + } + + override fun removeViewAt(index: Int) { + val view = getChildAt(index) + if (view == cell) return + super.removeViewAt(index) + } + + override fun removeAllViews() { + cell.removeAllViews() + children.filter { it != cell } + .toList() + .forEach(::removeView) + } + + /** + * @see ColorStateHolder.colorState + */ + override var colorState: ColorState? = ColorState.obtain(context, attrs, defStyleAttr) + set(value) { + if (field != value) { + field = value + refreshDrawableState() + } + } + + override fun generateDefaultLayoutParams(): FileLayoutParams { + return FileLayoutParams( + LayoutParams.MATCH_PARENT, + LayoutParams.WRAP_CONTENT, + ) + } + + override fun checkLayoutParams(p: ViewGroup.LayoutParams?): Boolean { + return p is FileLayoutParams + } + + override fun generateLayoutParams(attrs: AttributeSet?): FileLayoutParams { + return FileLayoutParams(context, attrs) + } + + override fun generateLayoutParams(p: ViewGroup.LayoutParams?): FileLayoutParams { + return FileLayoutParams(p) + } + + /** + * Параметры расположения дочерних [View] в [File] + */ + class FileLayoutParams : LayoutParams { + + /** + * Роль [View] внутри [File] + */ + var fileContent: FileContent? = null + + constructor(c: Context, attrs: AttributeSet?) : super(c, attrs) { + c.withStyledAttributes(attrs, R.styleable.File_Layout) { + this@FileLayoutParams.fileContent = + getInt(R.styleable.File_Layout_layout_fileContent, 0) + .let { FileContent.values().getOrElse(it) { null } } + } + } + + constructor(width: Int, height: Int) : super(width, height) + constructor(width: Int, height: Int, fileContent: FileContent) : super(width, height) { + this.fileContent = fileContent + } + + constructor(source: ViewGroup.LayoutParams?) : super(source) { + if (source is FileLayoutParams) { + this.fileContent = source.fileContent + } + } + } + + /** + * Роли для дочерних элементов [View] в [File] + */ + enum class FileContent { + /** + * Назначает этой [View] роль Иображения. + * Несколько [View] с этой ролью будут следовать друг за другом по горизонтали в том + * порядке, в котором они добавлялись в [File], в начало компонента. + */ + IMAGE, + + /** + * Назначает этой [View] роль Иконки. + * Несколько [View] с этой ролью будут следовать друг за другом по горизонтали в том + * порядке, в котором они добавлялись в [File], в начало компонента. + */ + ICON, + + /** + * Назначает этой [View] роль Активного элемента (с которым предполагается какое + * то взаимодейстивие, например нажатие). + * Несколько [View] с этой ролью будут следовать друг за другом по горизонтали в том + * порядке, в котором они добавлялись в [File], позиционирование зависит от + * actionPlacement ([ACTION_PLACEMENT_START] - в начале компонента, + * [ACTION_PLACEMENT_END] - в конце компонента). + */ + ACTION, + + /** + * Назначает этой [View] роль элемента отображающего Прогресс (обычно процесс загрузки). + * Позиционирование зависит от progressPlacement, [PROGRESS_PLACEMENT_INNER] - + * будет располагаться с той же стороны, что и Action, будет показан, когда isLoading = true, + * предпочтительно использование компоннета [CircularProgressBar], если добавлено несколько компонентов - + * они будут следовать друг за другом по горизонтали. + * [PROGRESS_PLACEMENT_OUTER] - будет располагаться снизу, под всем остальным контентом (только + * если это горизонтальный [ProgressBar]), если добавлено несколько компонентов [ProgressBar] + * они будут следовать друг за другом по вертикали. + */ + PROGRESS, + + /** + * Назначает этой [View] роль Label, позиционирует по центру [File] между + * контентом в начале (если есть Image или Icon) и контентом в конце (Action). + * Дополнительно применяет стили текста и цвета для элемента с этой ролью. + */ + LABEL, + + /** + * Назначает этой [View] роль Label, позиционирует по центру [File] между + * контентом в начале (если есть Image или Icon) и контентом в конце (Action), + * если есть [LABEL], то будет следовать за ним, по вертикали. + * Дополнительно применяет стили текста и цвета для элемента с этой ролью. + */ + DESCRIPTION, + } + + private fun View.applyContentRole(fileParams: FileLayoutParams) { + (this as? TextView)?.apply { + when (fileParams.fileContent) { + FileContent.LABEL -> this@apply.applyLabelRole() + FileContent.DESCRIPTION -> this@apply.applyDescriptionRole() + else -> Unit + } + } + if ((fileParams.fileContent == FileContent.ICON) && this is ImageView) { + if (imageTintList == null) { + iconTint?.let { imageTintList = it } + } + } + if (fileParams.fileContent == FileContent.PROGRESS && this is ProgressBar) { + fileParams.topMargin = _contentBottomPadding + } + } + + private fun TextView.applyLabelRole() { + setTextAppearancesList(labelAppearance) + colorState = this@File.colorState + labelColor?.let(::setTextColor) + TextViewCompat.setCompoundDrawableTintList(this, labelColor) + } + + private fun TextView.applyDescriptionRole() { + setTextAppearancesList(descriptionAppearance) + colorState = this@File.colorState + descriptionColor?.let(::setTextColor) + TextViewCompat.setCompoundDrawableTintList(this, descriptionColor) + } + + private fun convertToCellParams(params: FileLayoutParams): CellLayout.LayoutParams { + return CellLayout.LayoutParams(params).apply { + cellContent = when (params.fileContent) { + FileContent.ACTION, FileContent.PROGRESS -> { + when (_actionPlacement) { + ACTION_PLACEMENT_END -> CellContent.END + else -> CellContent.START + } + } + + FileContent.LABEL -> CellContent.TITLE + FileContent.DESCRIPTION -> CellContent.SUBTITLE + FileContent.IMAGE, FileContent.ICON -> CellContent.START + else -> CellContent.END + } + if (cellContent == CellContent.SUBTITLE) { + topMargin = _descriptionPadding + } + } + } + + private fun setContentBottomPadding() { + children.forEach { child -> + val lp = child.layoutParams as? FileLayoutParams + if (lp?.fileContent == FileContent.PROGRESS) { + lp.topMargin = _contentBottomPadding + } + } + requestLayout() + invalidate() + } + + private fun setDescriptionPadding() { + cell.children.forEach { child -> + val lp = child.layoutParams as? CellLayout.LayoutParams + if (lp?.cellContent == CellContent.SUBTITLE) { + lp.topMargin = _descriptionPadding + } + } + requestLayout() + invalidate() + } + + private fun setContentVisibility() { + setBottomContentVisibility() + setCellContentVisibility() + } + + private fun setBottomContentVisibility() { + children.forEach { child -> + val lp = child.layoutParams as? FileLayoutParams + if (lp?.fileContent == FileContent.PROGRESS) { + if (child is ProgressBar) { + child.isVisible = + _progressPlacement == PROGRESS_PLACEMENT_OUTER && isLoading + } + } + } + } + + private fun setCellContentVisibility() { + cell.children.forEach { child -> + val lp = child.layoutParams as? CellLayout.LayoutParams + if (lp?.cellContent == CellContent.START) { + if (_actionPlacement == ACTION_PLACEMENT_END) { + child.isVisible = child is ImageView + } else { + cellChildrenVisibility(child) + } + } else if (lp?.cellContent == CellContent.END) { + if (_actionPlacement == ACTION_PLACEMENT_START) { + child.isVisible = false + } else { + cellChildrenVisibility(child) + } + } + } + } + + private fun cellChildrenVisibility(child: View) { + when (child) { + is CircularProgressBar -> + child.isVisible = _progressPlacement == PROGRESS_PLACEMENT_INNER && isLoading + + is ImageView -> child.isVisible = _actionPlacement != ACTION_PLACEMENT_START + else -> child.isVisible = !(_progressPlacement == PROGRESS_PLACEMENT_INNER && isLoading) + } + } + + private fun changeActionPlacement() { + cell.children.forEach { child -> + val lp = child.layoutParams as? CellLayout.LayoutParams + when { + lp?.cellContent == CellContent.END && _actionPlacement == ACTION_PLACEMENT_START -> { + val newLp = lp + newLp.cellContent = CellContent.START + child.layoutParams = newLp + } + + lp?.cellContent == CellContent.START && _actionPlacement == ACTION_PLACEMENT_END -> { + if (child !is ImageView) { + val newLp = lp + newLp.cellContent = CellContent.END + child.layoutParams = newLp + } + } + } + } + } + + companion object { + + /** + * Расположение Action в начале + */ + const val ACTION_PLACEMENT_START = 0 + + /** + * Расположение Action в конце + */ + const val ACTION_PLACEMENT_END = 1 + + /** + * Расположение ProgressBar. Предполагается использование + * [CircularProgressBar] в начале или в конце. + */ + const val PROGRESS_PLACEMENT_INNER = 0 + + /** + * Расположение ProgressBar. Предполагается использование + * горизонтального [ProgressBar] снизу компонента. + */ + const val PROGRESS_PLACEMENT_OUTER = 1 + + internal fun wrapper( + context: Context, + attrs: AttributeSet?, + defStyleAttr: Int, + defStyleRes: Int, + ): Context { + var iconButtonStyleOverlay = 0 + context.withStyledAttributes(attrs, R.styleable.File, defStyleAttr, defStyleRes) { + iconButtonStyleOverlay = getResourceId(R.styleable.File_sd_iconButtonStyleOverlay, 0) + } + var progressBarStyleOverlay = 0 + context.withStyledAttributes(attrs, R.styleable.File, defStyleAttr, defStyleRes) { + progressBarStyleOverlay = getResourceId(R.styleable.File_sd_progressBarStyleOverlay, 0) + } + var circularBarStyleOverlay = 0 + context.withStyledAttributes(attrs, R.styleable.File, defStyleAttr, defStyleRes) { + circularBarStyleOverlay = getResourceId(R.styleable.File_sd_circularProgressBarStyleOverlay, 0) + } + val themeOverlay = createMergedOverlayContext( + context, + iconButtonStyleOverlay, + progressBarStyleOverlay, + circularBarStyleOverlay, + ) + return themeOverlay + } + + private fun createMergedOverlayContext(base: Context, vararg overlays: Int): Context { + if (overlays.all { it == 0 }) return base + val newTheme = base.resources.newTheme() + newTheme.setTo(base.theme) + + overlays.filter { it != 0 } + .forEach { newTheme.applyStyle(it, true) } + return ContextThemeWrapper(base, newTheme) + } + } +} diff --git a/sdds-core/uikit/src/main/res/values/file_attrs.xml b/sdds-core/uikit/src/main/res/values/file_attrs.xml new file mode 100644 index 000000000..6c634b9c0 --- /dev/null +++ b/sdds-core/uikit/src/main/res/values/file_attrs.xml @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/sdds-core/uikit/src/main/res/values/styles_file.xml b/sdds-core/uikit/src/main/res/values/styles_file.xml new file mode 100644 index 000000000..a8e7848e6 --- /dev/null +++ b/sdds-core/uikit/src/main/res/values/styles_file.xml @@ -0,0 +1,9 @@ + + + + \ No newline at end of file diff --git a/tokens/sdds.serv.view/config-info-view-system.json b/tokens/sdds.serv.view/config-info-view-system.json index bc19399b2..1c1654dad 100644 --- a/tokens/sdds.serv.view/config-info-view-system.json +++ b/tokens/sdds.serv.view/config-info-view-system.json @@ -12877,6 +12877,140 @@ "viewOverlayReference": "Serv.Sdds.ComponentOverlays.CarouselButtonsPlacementOuter" } ] + }, + { + "key": "file", + "coreName": "File", + "styleName": "FileCircularProgress", + "variations": [ + { + "name": "xs", + "viewReference": "Serv.Sdds.Components.FileCircularProgress.Xs", + "viewOverlayReference": "Serv.Sdds.ComponentOverlays.FileCircularProgressXs" + }, + { + "name": "xs.default", + "viewReference": "Serv.Sdds.Components.FileCircularProgress.Xs.Default", + "viewOverlayReference": "Serv.Sdds.ComponentOverlays.FileCircularProgressXsDefault" + }, + { + "name": "xs.negative", + "viewReference": "Serv.Sdds.Components.FileCircularProgress.Xs.Negative", + "viewOverlayReference": "Serv.Sdds.ComponentOverlays.FileCircularProgressXsNegative" + }, + { + "name": "s", + "viewReference": "Serv.Sdds.Components.FileCircularProgress.S", + "viewOverlayReference": "Serv.Sdds.ComponentOverlays.FileCircularProgressS" + }, + { + "name": "s.default", + "viewReference": "Serv.Sdds.Components.FileCircularProgress.S.Default", + "viewOverlayReference": "Serv.Sdds.ComponentOverlays.FileCircularProgressSDefault" + }, + { + "name": "s.negative", + "viewReference": "Serv.Sdds.Components.FileCircularProgress.S.Negative", + "viewOverlayReference": "Serv.Sdds.ComponentOverlays.FileCircularProgressSNegative" + }, + { + "name": "m", + "viewReference": "Serv.Sdds.Components.FileCircularProgress.M", + "viewOverlayReference": "Serv.Sdds.ComponentOverlays.FileCircularProgressM" + }, + { + "name": "m.default", + "viewReference": "Serv.Sdds.Components.FileCircularProgress.M.Default", + "viewOverlayReference": "Serv.Sdds.ComponentOverlays.FileCircularProgressMDefault" + }, + { + "name": "m.negative", + "viewReference": "Serv.Sdds.Components.FileCircularProgress.M.Negative", + "viewOverlayReference": "Serv.Sdds.ComponentOverlays.FileCircularProgressMNegative" + }, + { + "name": "l", + "viewReference": "Serv.Sdds.Components.FileCircularProgress.L", + "viewOverlayReference": "Serv.Sdds.ComponentOverlays.FileCircularProgressL" + }, + { + "name": "l.default", + "viewReference": "Serv.Sdds.Components.FileCircularProgress.L.Default", + "viewOverlayReference": "Serv.Sdds.ComponentOverlays.FileCircularProgressLDefault" + }, + { + "name": "l.negative", + "viewReference": "Serv.Sdds.Components.FileCircularProgress.L.Negative", + "viewOverlayReference": "Serv.Sdds.ComponentOverlays.FileCircularProgressLNegative" + } + ] + }, + { + "key": "file", + "coreName": "File", + "styleName": "FileLinearProgress", + "variations": [ + { + "name": "xs", + "viewReference": "Serv.Sdds.Components.FileLinearProgress.Xs", + "viewOverlayReference": "Serv.Sdds.ComponentOverlays.FileLinearProgressXs" + }, + { + "name": "xs.default", + "viewReference": "Serv.Sdds.Components.FileLinearProgress.Xs.Default", + "viewOverlayReference": "Serv.Sdds.ComponentOverlays.FileLinearProgressXsDefault" + }, + { + "name": "xs.negative", + "viewReference": "Serv.Sdds.Components.FileLinearProgress.Xs.Negative", + "viewOverlayReference": "Serv.Sdds.ComponentOverlays.FileLinearProgressXsNegative" + }, + { + "name": "s", + "viewReference": "Serv.Sdds.Components.FileLinearProgress.S", + "viewOverlayReference": "Serv.Sdds.ComponentOverlays.FileLinearProgressS" + }, + { + "name": "s.default", + "viewReference": "Serv.Sdds.Components.FileLinearProgress.S.Default", + "viewOverlayReference": "Serv.Sdds.ComponentOverlays.FileLinearProgressSDefault" + }, + { + "name": "s.negative", + "viewReference": "Serv.Sdds.Components.FileLinearProgress.S.Negative", + "viewOverlayReference": "Serv.Sdds.ComponentOverlays.FileLinearProgressSNegative" + }, + { + "name": "m", + "viewReference": "Serv.Sdds.Components.FileLinearProgress.M", + "viewOverlayReference": "Serv.Sdds.ComponentOverlays.FileLinearProgressM" + }, + { + "name": "m.default", + "viewReference": "Serv.Sdds.Components.FileLinearProgress.M.Default", + "viewOverlayReference": "Serv.Sdds.ComponentOverlays.FileLinearProgressMDefault" + }, + { + "name": "m.negative", + "viewReference": "Serv.Sdds.Components.FileLinearProgress.M.Negative", + "viewOverlayReference": "Serv.Sdds.ComponentOverlays.FileLinearProgressMNegative" + }, + { + "name": "l", + "viewReference": "Serv.Sdds.Components.FileLinearProgress.L", + "viewOverlayReference": "Serv.Sdds.ComponentOverlays.FileLinearProgressL" + }, + { + "name": "l.default", + "viewReference": "Serv.Sdds.Components.FileLinearProgress.L.Default", + "viewOverlayReference": "Serv.Sdds.ComponentOverlays.FileLinearProgressLDefault" + }, + { + "name": "l.negative", + "viewReference": "Serv.Sdds.Components.FileLinearProgress.L.Negative", + "viewOverlayReference": "Serv.Sdds.ComponentOverlays.FileLinearProgressLNegative" + } + ] } ] } \ No newline at end of file diff --git a/tokens/sdds.serv.view/src/main/kotlin/com/sdds/serv/colorstate/FileColorState.kt b/tokens/sdds.serv.view/src/main/kotlin/com/sdds/serv/colorstate/FileColorState.kt new file mode 100644 index 000000000..94f799a43 --- /dev/null +++ b/tokens/sdds.serv.view/src/main/kotlin/com/sdds/serv/colorstate/FileColorState.kt @@ -0,0 +1,44 @@ +// AUTO-GENERATED. DO NOT MODIFY this file. +package com.sdds.serv.colorstate + +import android.content.Context +import android.util.AttributeSet +import androidx.`annotation`.Keep +import com.sdds.serv.R +import com.sdds.uikit.colorstate.ColorState +import com.sdds.uikit.colorstate.ColorStateProvider +import kotlin.Int +import kotlin.IntArray + +/** + * Реализация [ColorState] для компонента File + */ +public enum class FileColorState( + public override val attrs: IntArray, +) : ColorState { + DEFAULT(intArrayOf(R.attr.serv_file_state_default)), + NEGATIVE(intArrayOf(R.attr.serv_file_state_negative)), +} + +/** + * Реализация [ColorStateProvider] для FileColorState + */ +@Keep +internal class FileColorStateProvider : ColorStateProvider { + public override fun obtain( + context: Context, + attrs: AttributeSet?, + defStyleAttr: Int, + defStyleRes: Int, + ): FileColorState? { + val typedArray = context.obtainStyledAttributes( + attrs, + R.styleable.File, + defStyleAttr, + defStyleRes, + ) + val stateOrdinal: Int = typedArray.getInt(R.styleable.File_serv_fileColors, 0) + typedArray.recycle() + return FileColorState.values().getOrNull(stateOrdinal) + } +} diff --git a/tokens/sdds.serv.view/src/main/res/layout/test.xml b/tokens/sdds.serv.view/src/main/res/layout/test.xml new file mode 100644 index 000000000..0acc1a9f9 --- /dev/null +++ b/tokens/sdds.serv.view/src/main/res/layout/test.xml @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tokens/sdds.serv.view/src/main/theme-builder-res/color/serv_file_circular_progress_description_color.xml b/tokens/sdds.serv.view/src/main/theme-builder-res/color/serv_file_circular_progress_description_color.xml new file mode 100644 index 000000000..3369ce383 --- /dev/null +++ b/tokens/sdds.serv.view/src/main/theme-builder-res/color/serv_file_circular_progress_description_color.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/tokens/sdds.serv.view/src/main/theme-builder-res/color/serv_file_circular_progress_icon_tint.xml b/tokens/sdds.serv.view/src/main/theme-builder-res/color/serv_file_circular_progress_icon_tint.xml new file mode 100644 index 000000000..dc8dd1e72 --- /dev/null +++ b/tokens/sdds.serv.view/src/main/theme-builder-res/color/serv_file_circular_progress_icon_tint.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/tokens/sdds.serv.view/src/main/theme-builder-res/color/serv_file_circular_progress_label_color.xml b/tokens/sdds.serv.view/src/main/theme-builder-res/color/serv_file_circular_progress_label_color.xml new file mode 100644 index 000000000..dc8dd1e72 --- /dev/null +++ b/tokens/sdds.serv.view/src/main/theme-builder-res/color/serv_file_circular_progress_label_color.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/tokens/sdds.serv.view/src/main/theme-builder-res/color/serv_file_linear_progress_description_color.xml b/tokens/sdds.serv.view/src/main/theme-builder-res/color/serv_file_linear_progress_description_color.xml new file mode 100644 index 000000000..3369ce383 --- /dev/null +++ b/tokens/sdds.serv.view/src/main/theme-builder-res/color/serv_file_linear_progress_description_color.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/tokens/sdds.serv.view/src/main/theme-builder-res/color/serv_file_linear_progress_icon_tint.xml b/tokens/sdds.serv.view/src/main/theme-builder-res/color/serv_file_linear_progress_icon_tint.xml new file mode 100644 index 000000000..dc8dd1e72 --- /dev/null +++ b/tokens/sdds.serv.view/src/main/theme-builder-res/color/serv_file_linear_progress_icon_tint.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/tokens/sdds.serv.view/src/main/theme-builder-res/color/serv_file_linear_progress_label_color.xml b/tokens/sdds.serv.view/src/main/theme-builder-res/color/serv_file_linear_progress_label_color.xml new file mode 100644 index 000000000..dc8dd1e72 --- /dev/null +++ b/tokens/sdds.serv.view/src/main/theme-builder-res/color/serv_file_linear_progress_label_color.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/tokens/sdds.serv.view/src/main/theme-builder-res/values/file-attributes.xml b/tokens/sdds.serv.view/src/main/theme-builder-res/values/file-attributes.xml new file mode 100644 index 000000000..a4ea30983 --- /dev/null +++ b/tokens/sdds.serv.view/src/main/theme-builder-res/values/file-attributes.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/tokens/sdds.serv.view/src/main/theme-builder-res/values/style-dimens.xml b/tokens/sdds.serv.view/src/main/theme-builder-res/values/style-dimens.xml index 554fdd6e1..86a63c8ac 100644 --- a/tokens/sdds.serv.view/src/main/theme-builder-res/values/style-dimens.xml +++ b/tokens/sdds.serv.view/src/main/theme-builder-res/values/style-dimens.xml @@ -2044,4 +2044,23 @@ 12.0dp 12.0dp 12.0dp + 2.0dp + 6.0dp + 6.0dp + 8.0dp + 8.0dp + 10.0dp + 10.0dp + 12.0dp + 12.0dp + 8.0dp + 2.0dp + 6.0dp + 6.0dp + 8.0dp + 8.0dp + 10.0dp + 10.0dp + 12.0dp + 12.0dp diff --git a/tokens/sdds.serv.view/src/main/theme-builder-res/values/styles-filecircularprogress.xml b/tokens/sdds.serv.view/src/main/theme-builder-res/values/styles-filecircularprogress.xml new file mode 100644 index 000000000..8e0e6e82b --- /dev/null +++ b/tokens/sdds.serv.view/src/main/theme-builder-res/values/styles-filecircularprogress.xml @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tokens/sdds.serv.view/src/main/theme-builder-res/values/styles-filelinearprogress.xml b/tokens/sdds.serv.view/src/main/theme-builder-res/values/styles-filelinearprogress.xml new file mode 100644 index 000000000..d32f35bdd --- /dev/null +++ b/tokens/sdds.serv.view/src/main/theme-builder-res/values/styles-filelinearprogress.xml @@ -0,0 +1,127 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tokens/sdds.serv.view/src/main/theme-builder-res/values/theme.xml b/tokens/sdds.serv.view/src/main/theme-builder-res/values/theme.xml index 821a41cee..c268811f8 100644 --- a/tokens/sdds.serv.view/src/main/theme-builder-res/values/theme.xml +++ b/tokens/sdds.serv.view/src/main/theme-builder-res/values/theme.xml @@ -1281,6 +1281,7 @@ @style/Serv.Sdds.Components.Note.L.Default @style/Serv.Sdds.Components.NoteCompact.L.Default @style/Serv.Sdds.Components.SliderHorizontalLabelInner.L + @style/Serv.Sdds.Components.FileLinearProgress.L