From 180cd80fa7355d051b14113c58b5697b1a0e9945 Mon Sep 17 00:00:00 2001 From: Andrea Giancarli Date: Fri, 20 Sep 2024 16:21:23 +0200 Subject: [PATCH] - Centered text in SirioButton component. - Fixed shadow elevation and tile overflow in SirioCard. - Added scroll animation to SirioCarousel. - SirioChips now display an icon when selected. - Added onSearch callback to SirioSearchBar. - Introduced new notification layout. - Updated Sirio token to version 8.1.0. - Added new components: TitleBar, Avviso, MenuSpalla, Filter, and Table. --- .gitignore | 7 + README.md | 2 +- build.gradle | 1 + design/build.gradle.kts | 4 +- .../styleDictionary/StyleDictionaryColor.kt | 18 +- .../styleDictionary/StyleDictionarySize.kt | 4 +- .../main/java/it/inps/sirio/theme/Color.kt | 594 +++++++++-- .../src/main/java/it/inps/sirio/theme/Size.kt | 146 ++- .../main/java/it/inps/sirio/theme/Theme.kt | 77 +- .../src/main/java/it/inps/sirio/theme/Type.kt | 142 ++- .../it/inps/sirio/ui/avviso/SirioAvviso.kt | 18 + .../inps/sirio/ui/avviso/SirioAvvisoCommon.kt | 161 +++ .../inps/sirio/ui/button/SirioButtonCommon.kt | 2 + .../it/inps/sirio/ui/card/SirioCardCommon.kt | 10 +- .../sirio/ui/carousel/SirioCarouselCommon.kt | 11 +- .../sirio/ui/checkbox/SirioCheckboxCommon.kt | 29 +- .../{ChipCommon.kt => SirioChipCommon.kt} | 28 +- .../chip/{ChipLabel.kt => SirioChipLabel.kt} | 30 +- ...ipLabelClose.kt => SirioChipLabelClose.kt} | 14 +- ...ChipLabelIcon.kt => SirioChipLabelIcon.kt} | 12 +- ...conClose.kt => SirioChipLabelIconClose.kt} | 14 +- .../inps/sirio/ui/dropdown/SirioDropdown.kt | 144 +++ .../ui/dropdown/SirioDropdownOptionItem.kt | 132 +++ .../it/inps/sirio/ui/dropdown/SirioPopup.kt | 358 +++++++ .../sirio/ui/fileupload/FileUploadCommon.kt | 4 +- .../sirio/ui/filter/SirioFilterCheckbox.kt | 84 ++ .../inps/sirio/ui/filter/SirioFilterChips.kt | 85 ++ .../sirio/ui/filter/SirioFilterChipsWrap.kt | 84 ++ .../inps/sirio/ui/filter/SirioFilterCommon.kt | 49 + .../inps/sirio/ui/filter/SirioFilterFooter.kt | 74 ++ .../inps/sirio/ui/filter/SirioFilterHeader.kt | 79 ++ .../inps/sirio/ui/filter/SirioFilterInput.kt | 100 ++ .../inps/sirio/ui/filter/SirioFilterRadio.kt | 84 ++ .../sirio/ui/filter/SirioFilterSelected.kt | 78 ++ .../inps/sirio/ui/filter/SirioFilterTabs.kt | 99 ++ .../inps/sirio/ui/filter/SirioFilterTitle.kt | 72 ++ .../inps/sirio/ui/filter/SirioFilterToggle.kt | 84 ++ .../sirio/ui/menuspalla/SirioMenuSpalla.kt | 319 ++++++ .../menuspalla/SirioMenuSpallaDrawerItem.kt | 158 +++ .../SirioMenuSpallaDrawerItemInfo.kt | 130 +++ .../SirioMenuSpallaExpandableItem.kt | 49 + .../ui/menuspalla/SirioMenuSpallaItem.kt | 330 ++++++ .../ui/menuspalla/SirioMenuSpallaItemData.kt | 35 + .../SirioMenuSpallaItemTitleSection.kt | 88 ++ .../ui/menuspalla/SirioMenuSpallaSection.kt | 31 + .../SirioMenuSpallaSectionItemData.kt | 9 + .../ui/notification/NotificationCommon.kt | 336 +++++- .../ui/notification/NotificationInline.kt | 2 +- .../notification/NotificationInlineCommon.kt | 160 --- .../ui/notification/NotificationToast.kt | 26 +- .../notification/NotificationToastCommon.kt | 181 ---- .../sirio/ui/radiobutton/SirioRadioButton.kt | 4 +- .../ui/radiobutton/SirioRadioButtonCommon.kt | 49 +- .../inps/sirio/ui/searchbar/SirioSearchBar.kt | 7 +- .../ui/searchbar/SirioSearchBarCommon.kt | 78 +- .../ui/stepprogressbar/SirioStepControls.kt | 131 +++ .../stepprogressbar/SirioStepProgressBar.kt | 42 + .../ui/stepprogressbar/SirioStepSelection.kt | 96 ++ .../it/inps/sirio/ui/tabbar/SirioTabBar.kt | 108 ++ ...bBarItemData.kt => SirioTabBarItemData.kt} | 8 +- .../java/it/inps/sirio/ui/tabbar/TabBar.kt | 194 ---- .../java/it/inps/sirio/ui/table/SirioTable.kt | 165 +++ .../inps/sirio/ui/table/SirioTableCommon.kt | 127 +++ .../inps/sirio/ui/table/SirioTableHeader.kt | 233 +++++ .../sirio/ui/table/SirioTableHeaderCommon.kt | 221 ++++ .../inps/sirio/ui/table/SirioTableIconData.kt | 28 + .../inps/sirio/ui/table/SirioTableRowData.kt | 12 + .../ui/table/cell/SirioTableCellAvatar.kt | 126 +++ .../ui/table/cell/SirioTableCellCommon.kt | 139 +++ .../sirio/ui/table/cell/SirioTableCellLink.kt | 95 ++ .../ui/table/cell/SirioTableCellMultiIcons.kt | 98 ++ .../ui/table/cell/SirioTableCellNumber.kt | 119 +++ .../ui/table/cell/SirioTableCellNumberOnly.kt | 90 ++ .../sirio/ui/table/cell/SirioTableCellTag.kt | 88 ++ .../sirio/ui/table/cell/SirioTableCellText.kt | 98 ++ .../ui/table/cell/SirioTableCellTextOnly.kt | 82 ++ .../table/cell/SirioTableComponentCommon.kt | 80 ++ .../sirio/ui/table/drawer/SirioTableDrawer.kt | 154 +++ .../ui/table/drawer/SirioTableDrawerHeader.kt | 61 ++ .../ui/table/drawer/SirioTableDrawerItem.kt | 96 ++ .../table/drawer/SirioTableDrawerItemData.kt | 15 + .../drawer/SirioTableDrawerStickyBottomBar.kt | 144 +++ .../ui/table/vertical/SirioTableVertical.kt | 109 ++ .../table/vertical/SirioTableVerticalCell.kt | 97 ++ .../vertical/SirioTableVerticalCellData.kt | 15 + .../vertical/SirioTableVerticalCellItem.kt | 146 +++ .../SirioTableVerticalCellItemData.kt | 14 + .../it/inps/sirio/ui/tabs/SirioTabCommon.kt | 118 +-- .../inps/sirio/ui/tabs/SirioTabGroupCommon.kt | 85 +- .../java/it/inps/sirio/ui/tabs/TabItemData.kt | 4 +- .../sirio/ui/textarea/SirioTextAreaCommon.kt | 30 +- .../ui/textfield/SirioTextFieldCommon.kt | 25 +- .../inps/sirio/ui/titlebar/SirioTitleBar.kt | 24 + .../sirio/ui/titlebar/SirioTitleBarCommon.kt | 145 +++ .../ui/titlebar/SirioTitleBarItemData.kt | 27 + .../ui/toggle/{Toggle.kt => SirioToggle.kt} | 8 +- .../inps/sirio/ui/toggle/SirioToggleCommon.kt | 44 +- .../java/it/inps/sirio/utils/ModifierExt.kt | 21 + .../java/it/inps/sirio/utils/SirioIcon.kt | 34 +- .../java/it/inps/sirio/utils/SirioIconData.kt | 68 ++ design/src/main/res/values/strings.xml | 5 +- gradle.properties | 2 +- gradle/libs.versions.toml | 25 +- gradle/wrapper/gradle-wrapper.properties | 2 +- sample/build.gradle.kts | 10 +- sample/src/main/AndroidManifest.xml | 9 +- .../main/java/it/inps/design/MainActivity.kt | 30 + .../it/inps/design/avviso/AvvisoActivity.kt | 87 ++ .../it/inps/design/button/ButtonActivity.kt | 9 +- .../inps/design/carousel/CarouselActivity.kt | 16 +- .../java/it/inps/design/chip/ChipActivity.kt | 36 +- .../it/inps/design/filter/FilterActivity.kt | 311 ++++++ .../design/menuspalla/MenuSpallaActivity.kt | 522 ++++++++++ .../StepProgressBarActivity.kt | 149 +++ .../java/it/inps/design/tabbar/Navigation.kt | 15 +- .../it/inps/design/tabbar/TabBarActivity.kt | 77 +- .../it/inps/design/table/TableActivity.kt | 979 ++++++++++++++++++ .../inps/design/titlebar/TitleBarActivity.kt | 103 ++ .../it/inps/design/toggle/ToggleActivity.kt | 18 +- .../java/it/inps/design/ui/DemoActivity.kt | 152 --- .../java/it/inps/design/ui/DemoNavigation.kt | 57 - .../main/java/it/inps/design/ui/DemoTabs.kt | 121 --- 122 files changed, 10169 insertions(+), 1356 deletions(-) create mode 100644 design/src/main/java/it/inps/sirio/ui/avviso/SirioAvviso.kt create mode 100644 design/src/main/java/it/inps/sirio/ui/avviso/SirioAvvisoCommon.kt rename design/src/main/java/it/inps/sirio/ui/chip/{ChipCommon.kt => SirioChipCommon.kt} (97%) rename design/src/main/java/it/inps/sirio/ui/chip/{ChipLabel.kt => SirioChipLabel.kt} (62%) rename design/src/main/java/it/inps/sirio/ui/chip/{ChipLabelClose.kt => SirioChipLabelClose.kt} (87%) rename design/src/main/java/it/inps/sirio/ui/chip/{ChipLabelIcon.kt => SirioChipLabelIcon.kt} (89%) rename design/src/main/java/it/inps/sirio/ui/chip/{ChipLabelIconClose.kt => SirioChipLabelIconClose.kt} (88%) create mode 100644 design/src/main/java/it/inps/sirio/ui/dropdown/SirioDropdown.kt create mode 100644 design/src/main/java/it/inps/sirio/ui/dropdown/SirioDropdownOptionItem.kt create mode 100644 design/src/main/java/it/inps/sirio/ui/dropdown/SirioPopup.kt create mode 100644 design/src/main/java/it/inps/sirio/ui/filter/SirioFilterCheckbox.kt create mode 100644 design/src/main/java/it/inps/sirio/ui/filter/SirioFilterChips.kt create mode 100644 design/src/main/java/it/inps/sirio/ui/filter/SirioFilterChipsWrap.kt create mode 100644 design/src/main/java/it/inps/sirio/ui/filter/SirioFilterCommon.kt create mode 100644 design/src/main/java/it/inps/sirio/ui/filter/SirioFilterFooter.kt create mode 100644 design/src/main/java/it/inps/sirio/ui/filter/SirioFilterHeader.kt create mode 100644 design/src/main/java/it/inps/sirio/ui/filter/SirioFilterInput.kt create mode 100644 design/src/main/java/it/inps/sirio/ui/filter/SirioFilterRadio.kt create mode 100644 design/src/main/java/it/inps/sirio/ui/filter/SirioFilterSelected.kt create mode 100644 design/src/main/java/it/inps/sirio/ui/filter/SirioFilterTabs.kt create mode 100644 design/src/main/java/it/inps/sirio/ui/filter/SirioFilterTitle.kt create mode 100644 design/src/main/java/it/inps/sirio/ui/filter/SirioFilterToggle.kt create mode 100644 design/src/main/java/it/inps/sirio/ui/menuspalla/SirioMenuSpalla.kt create mode 100644 design/src/main/java/it/inps/sirio/ui/menuspalla/SirioMenuSpallaDrawerItem.kt create mode 100644 design/src/main/java/it/inps/sirio/ui/menuspalla/SirioMenuSpallaDrawerItemInfo.kt create mode 100644 design/src/main/java/it/inps/sirio/ui/menuspalla/SirioMenuSpallaExpandableItem.kt create mode 100644 design/src/main/java/it/inps/sirio/ui/menuspalla/SirioMenuSpallaItem.kt create mode 100644 design/src/main/java/it/inps/sirio/ui/menuspalla/SirioMenuSpallaItemData.kt create mode 100644 design/src/main/java/it/inps/sirio/ui/menuspalla/SirioMenuSpallaItemTitleSection.kt create mode 100644 design/src/main/java/it/inps/sirio/ui/menuspalla/SirioMenuSpallaSection.kt create mode 100644 design/src/main/java/it/inps/sirio/ui/menuspalla/SirioMenuSpallaSectionItemData.kt delete mode 100644 design/src/main/java/it/inps/sirio/ui/notification/NotificationInlineCommon.kt delete mode 100644 design/src/main/java/it/inps/sirio/ui/notification/NotificationToastCommon.kt create mode 100644 design/src/main/java/it/inps/sirio/ui/stepprogressbar/SirioStepControls.kt create mode 100644 design/src/main/java/it/inps/sirio/ui/stepprogressbar/SirioStepProgressBar.kt create mode 100644 design/src/main/java/it/inps/sirio/ui/stepprogressbar/SirioStepSelection.kt create mode 100644 design/src/main/java/it/inps/sirio/ui/tabbar/SirioTabBar.kt rename design/src/main/java/it/inps/sirio/ui/tabbar/{TabBarItemData.kt => SirioTabBarItemData.kt} (76%) delete mode 100644 design/src/main/java/it/inps/sirio/ui/tabbar/TabBar.kt create mode 100644 design/src/main/java/it/inps/sirio/ui/table/SirioTable.kt create mode 100644 design/src/main/java/it/inps/sirio/ui/table/SirioTableCommon.kt create mode 100644 design/src/main/java/it/inps/sirio/ui/table/SirioTableHeader.kt create mode 100644 design/src/main/java/it/inps/sirio/ui/table/SirioTableHeaderCommon.kt create mode 100644 design/src/main/java/it/inps/sirio/ui/table/SirioTableIconData.kt create mode 100644 design/src/main/java/it/inps/sirio/ui/table/SirioTableRowData.kt create mode 100644 design/src/main/java/it/inps/sirio/ui/table/cell/SirioTableCellAvatar.kt create mode 100644 design/src/main/java/it/inps/sirio/ui/table/cell/SirioTableCellCommon.kt create mode 100644 design/src/main/java/it/inps/sirio/ui/table/cell/SirioTableCellLink.kt create mode 100644 design/src/main/java/it/inps/sirio/ui/table/cell/SirioTableCellMultiIcons.kt create mode 100644 design/src/main/java/it/inps/sirio/ui/table/cell/SirioTableCellNumber.kt create mode 100644 design/src/main/java/it/inps/sirio/ui/table/cell/SirioTableCellNumberOnly.kt create mode 100644 design/src/main/java/it/inps/sirio/ui/table/cell/SirioTableCellTag.kt create mode 100644 design/src/main/java/it/inps/sirio/ui/table/cell/SirioTableCellText.kt create mode 100644 design/src/main/java/it/inps/sirio/ui/table/cell/SirioTableCellTextOnly.kt create mode 100644 design/src/main/java/it/inps/sirio/ui/table/cell/SirioTableComponentCommon.kt create mode 100644 design/src/main/java/it/inps/sirio/ui/table/drawer/SirioTableDrawer.kt create mode 100644 design/src/main/java/it/inps/sirio/ui/table/drawer/SirioTableDrawerHeader.kt create mode 100644 design/src/main/java/it/inps/sirio/ui/table/drawer/SirioTableDrawerItem.kt create mode 100644 design/src/main/java/it/inps/sirio/ui/table/drawer/SirioTableDrawerItemData.kt create mode 100644 design/src/main/java/it/inps/sirio/ui/table/drawer/SirioTableDrawerStickyBottomBar.kt create mode 100644 design/src/main/java/it/inps/sirio/ui/table/vertical/SirioTableVertical.kt create mode 100644 design/src/main/java/it/inps/sirio/ui/table/vertical/SirioTableVerticalCell.kt create mode 100644 design/src/main/java/it/inps/sirio/ui/table/vertical/SirioTableVerticalCellData.kt create mode 100644 design/src/main/java/it/inps/sirio/ui/table/vertical/SirioTableVerticalCellItem.kt create mode 100644 design/src/main/java/it/inps/sirio/ui/table/vertical/SirioTableVerticalCellItemData.kt create mode 100644 design/src/main/java/it/inps/sirio/ui/titlebar/SirioTitleBar.kt create mode 100644 design/src/main/java/it/inps/sirio/ui/titlebar/SirioTitleBarCommon.kt create mode 100644 design/src/main/java/it/inps/sirio/ui/titlebar/SirioTitleBarItemData.kt rename design/src/main/java/it/inps/sirio/ui/toggle/{Toggle.kt => SirioToggle.kt} (94%) create mode 100644 design/src/main/java/it/inps/sirio/utils/ModifierExt.kt create mode 100644 design/src/main/java/it/inps/sirio/utils/SirioIconData.kt create mode 100644 sample/src/main/java/it/inps/design/avviso/AvvisoActivity.kt create mode 100644 sample/src/main/java/it/inps/design/filter/FilterActivity.kt create mode 100644 sample/src/main/java/it/inps/design/menuspalla/MenuSpallaActivity.kt create mode 100644 sample/src/main/java/it/inps/design/stepprogressbar/StepProgressBarActivity.kt create mode 100644 sample/src/main/java/it/inps/design/table/TableActivity.kt create mode 100644 sample/src/main/java/it/inps/design/titlebar/TitleBarActivity.kt delete mode 100644 sample/src/main/java/it/inps/design/ui/DemoActivity.kt delete mode 100644 sample/src/main/java/it/inps/design/ui/DemoNavigation.kt delete mode 100644 sample/src/main/java/it/inps/design/ui/DemoTabs.kt diff --git a/.gitignore b/.gitignore index 3071a6e..54d7bac 100644 --- a/.gitignore +++ b/.gitignore @@ -24,6 +24,9 @@ output.json # IntelliJ *.iml .idea/ +misc.xml +deploymentTargetDropDown.xml +render.experimental.xml # Keystore files *.jks @@ -95,6 +98,10 @@ Network Trash Folder Temporary Items .apdisk +### macOS Patch ### +# iCloud generated files +*.icloud + ### AndroidStudio ### # Covers files to be ignored for android development using Android Studio. diff --git a/README.md b/README.md index 91e9759..6c400f8 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ repositories { } } dependencies { - implementation 'it.inps.sirio:library:8.0.0' + implementation 'it.inps.sirio:library:8.1.0' } ``` 2. Add following repository in your gradle file (es. settings.gradle) diff --git a/build.gradle b/build.gradle index 2770610..230bff6 100644 --- a/build.gradle +++ b/build.gradle @@ -2,6 +2,7 @@ plugins { alias(libs.plugins.android.application) apply false alias(libs.plugins.android.library) apply false alias(libs.plugins.kotlin.android) apply false + alias(libs.plugins.compose.compiler) apply false } tasks.register('clean', Delete) { diff --git a/design/build.gradle.kts b/design/build.gradle.kts index 8881dd1..590cb26 100644 --- a/design/build.gradle.kts +++ b/design/build.gradle.kts @@ -2,6 +2,7 @@ plugins { // alias(libs.plugins.android.application) alias(libs.plugins.android.library) alias(libs.plugins.kotlin.android) + alias(libs.plugins.compose.compiler) id("maven-publish") } @@ -27,9 +28,6 @@ android { buildFeatures { compose = true } - composeOptions { - kotlinCompilerExtensionVersion = libs.versions.composeCompiler.get() - } packaging { resources.excludes.add("/META-INF/{AL2.0,LGPL2.1}") } diff --git a/design/src/main/java/it/inps/sirio/styleDictionary/StyleDictionaryColor.kt b/design/src/main/java/it/inps/sirio/styleDictionary/StyleDictionaryColor.kt index b7bc9c9..eeefe25 100644 --- a/design/src/main/java/it/inps/sirio/styleDictionary/StyleDictionaryColor.kt +++ b/design/src/main/java/it/inps/sirio/styleDictionary/StyleDictionaryColor.kt @@ -48,8 +48,8 @@ object StyleDictionaryColor { val colorAliasInteractiveSuccessFocus = Color(0xff008069) val colorAliasInteractiveSuccessHover = Color(0xff005c4b) val colorAliasInteractiveSuccessPressed = Color(0xff001a15) - val colorAliasInteractiveWarningDefault = Color(0xffe26334) - val colorAliasInteractiveWarningFocus = Color(0xffe26334) + val colorAliasInteractiveWarningDefault = Color(0xffcb4d1e) + val colorAliasInteractiveWarningFocus = Color(0xffcb4d1e) val colorAliasInteractiveWarningHover = Color(0xffffa217) val colorAliasInteractiveWarningPressed = Color(0xff9c3a16) val colorAliasOverlay15Secondary100 = Color(0x26454D56) @@ -103,29 +103,35 @@ object StyleDictionaryColor { val colorGlobalSemanticSuccess110 = Color(0xff005c4b) val colorGlobalSemanticSuccess120 = Color(0xff00382e) val colorGlobalSemanticSuccess130 = Color(0xff001a15) - val colorGlobalSemanticWarning100 = Color(0xffe26334) + val colorGlobalSemanticWarning100 = Color(0xffcb4d1e) val colorGlobalSemanticWarning110 = Color(0xff9c3a16) val colorGlobalSemanticWarning80 = Color(0xffffa217) val colorGlobalSemanticWarning90 = Color(0xfff97c1d) val colorSpecificCardOverlayGradientImg = listOf(Color(0x00000000), Color(0xFF000000)) + val colorSpecificDataEntryBorderColorAlert = Color(0xffaa224f) val colorSpecificDataEntryBorderColorDefault = Color(0xff454d56) - val colorSpecificDataEntryBorderColorError = Color(0xffaa224f) val colorSpecificDataEntryBorderColorFocus = Color(0xff2f6dd5) val colorSpecificDataEntryBorderColorHover = Color(0xff00368f) val colorSpecificDataEntryBorderColorSuccess = Color(0xff008069) val colorSpecificDataEntryBorderColorValued = Color(0xff454d56) - val colorSpecificDataEntryBorderColorWarning = Color(0xffe26334) + val colorSpecificDataEntryBorderColorWarning = Color(0xffcb4d1e) + val colorSpecificDataEntryLabelColorAlert = Color(0xffaa224f) val colorSpecificDataEntryLabelColorDefault = Color(0xff454d56) val colorSpecificDataEntryLabelColorFocus = Color(0xff2f6dd5) val colorSpecificDataEntryLabelColorHover = Color(0xff00368f) + val colorSpecificDataEntryLabelColorSuccess = Color(0xff008069) val colorSpecificDataEntryLabelColorValued = Color(0xff454d56) + val colorSpecificDataEntryLabelColorWarning = Color(0xffcb4d1e) + val colorSpecificDataEntryPlaceholderColorAlert = Color(0xffaa224f) val colorSpecificDataEntryPlaceholderColorDefault = Color(0xff454d56) val colorSpecificDataEntryPlaceholderColorFocus = Color(0xff2f6dd5) val colorSpecificDataEntryPlaceholderColorHover = Color(0xff00368f) + val colorSpecificDataEntryPlaceholderColorSuccess = Color(0xff008069) val colorSpecificDataEntryPlaceholderColorValued = Color(0xff454d56) + val colorSpecificDataEntryPlaceholderColorWarning = Color(0xffcb4d1e) val colorSpecificOptionBackgroundColorFocus = Color(0xff2f6dd5) val colorSpecificOptionBackgroundColorHover = Color(0xff00368f) val colorSpecificOptionBackgroundColorPressed = Color(0xff00173d) val colorSpecificOptionBackgroundColorValued = Color(0xff2f6dd5) val colorSpecificProgressbarBackgroundColor = listOf(Color(0xFF002460), Color(0xFF2F6DD5), Color(0xFF18CEE7)) -} \ No newline at end of file +} diff --git a/design/src/main/java/it/inps/sirio/styleDictionary/StyleDictionarySize.kt b/design/src/main/java/it/inps/sirio/styleDictionary/StyleDictionarySize.kt index de51be2..bd5a49c 100644 --- a/design/src/main/java/it/inps/sirio/styleDictionary/StyleDictionarySize.kt +++ b/design/src/main/java/it/inps/sirio/styleDictionary/StyleDictionarySize.kt @@ -5,7 +5,7 @@ package it.inps.sirio.styleDictionary object StyleDictionarySize { const val typographyAliasDisclaimerMdLineHeight04 = 24 - const val typographyAliasDisclaimerMdSize04 = 16 + const val typographyAliasDisclaimerMdSize04 = 14 const val typographyAliasH1LgLineHeight14 = 78 const val typographyAliasH1LgSize14 = 52 const val typographyAliasH1MdLineHeight13 = 72 @@ -85,4 +85,4 @@ object StyleDictionarySize { const val typographySpecificAppNavigationTitleXlLineHeight = 36 const val typographySpecificAppNavigationTitleXlSize = 24 const val typographySpecificIosTabbarLabelXsSize = 11 -} \ No newline at end of file +} diff --git a/design/src/main/java/it/inps/sirio/theme/Color.kt b/design/src/main/java/it/inps/sirio/theme/Color.kt index f066987..929ba68 100644 --- a/design/src/main/java/it/inps/sirio/theme/Color.kt +++ b/design/src/main/java/it/inps/sirio/theme/Color.kt @@ -14,6 +14,7 @@ import androidx.compose.runtime.Stable import androidx.compose.ui.graphics.Color import it.inps.sirio.styleDictionary.StyleDictionaryColor import it.inps.sirio.ui.accordion.SirioAccordionColors +import it.inps.sirio.ui.avviso.SirioAvvisoColors import it.inps.sirio.ui.badge.SirioBadgeColors import it.inps.sirio.ui.button.SirioButtonColors import it.inps.sirio.ui.card.SirioCardColors @@ -22,15 +23,34 @@ import it.inps.sirio.ui.carousel.SirioCarouselColors import it.inps.sirio.ui.carousel.SirioCarouselIndicatorColors import it.inps.sirio.ui.checkbox.SirioCheckboxColors import it.inps.sirio.ui.dialog.SirioDialogColors +import it.inps.sirio.ui.dropdown.SirioDropdownColors +import it.inps.sirio.ui.dropdown.SirioDropdownOptionColors +import it.inps.sirio.ui.filter.SirioFilterColors import it.inps.sirio.ui.hero.SirioHeroColors +import it.inps.sirio.ui.menuspalla.SirioMenuSpallaColors +import it.inps.sirio.ui.menuspalla.SirioMenuSpallaDrawerItemColors +import it.inps.sirio.ui.menuspalla.SirioMenuSpallaDrawerItemInfoColors +import it.inps.sirio.ui.menuspalla.SirioMenuSpallaItemColors +import it.inps.sirio.ui.menuspalla.SirioMenuSpallaItemTitleSectionColors +import it.inps.sirio.ui.notification.NotificationColors import it.inps.sirio.ui.pagination.SirioPaginationColors import it.inps.sirio.ui.radiobutton.SirioRadioButtonColors import it.inps.sirio.ui.searchbar.SirioSearchBarColors +import it.inps.sirio.ui.stepprogressbar.SirioStepControlsColors +import it.inps.sirio.ui.stepprogressbar.SirioStepProgressBarColors +import it.inps.sirio.ui.stepprogressbar.SirioStepSelectionColors +import it.inps.sirio.ui.table.SirioTableColors +import it.inps.sirio.ui.table.SirioTableHeaderColors +import it.inps.sirio.ui.table.cell.SirioTableCellColors +import it.inps.sirio.ui.table.cell.SirioTableComponentColors +import it.inps.sirio.ui.table.drawer.SirioTableDrawerColors +import it.inps.sirio.ui.table.vertical.SirioTableVerticalColors import it.inps.sirio.ui.tabs.SirioTabsColors import it.inps.sirio.ui.tag.SirioTagColors import it.inps.sirio.ui.tag.SirioTagsColors import it.inps.sirio.ui.textarea.SirioTextAreaColors import it.inps.sirio.ui.textfield.SirioTextFieldColors +import it.inps.sirio.ui.titlebar.SirioTitleBarColors import it.inps.sirio.ui.toggle.SirioToggleColors private val buttonsLightColors = ButtonColors( @@ -113,6 +133,15 @@ private val buttonsLightColors = ButtonColors( ), ) +private val sirioFilterLightColors = SirioFilterColors( + background = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight0, + close = StyleDictionaryColor.colorAliasInteractivePrimaryDefault, + header = StyleDictionaryColor.colorGlobalDarkPrimary115, + info = StyleDictionaryColor.colorGlobalSemanticInfo100, + selectedBackground = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight40, + title = StyleDictionaryColor.colorSpecificDataEntryLabelColorDefault, +) + private val tagLightColors = SirioTagsColors( gray = SirioTagColors( background = StyleDictionaryColor.colorAliasInteractiveSecondaryDefault, @@ -140,6 +169,127 @@ private val tagLightColors = SirioTagsColors( ), ) +private val menuSpallaLightColors = SirioMenuSpallaColors( + background = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight0, + drawerItem = SirioMenuSpallaDrawerItemColors( + background = SirioColorState( + default = StyleDictionaryColor.colorAliasInteractivePrimaryDefault, + focused = StyleDictionaryColor.colorAliasInteractivePrimaryFocus, + hovered = StyleDictionaryColor.colorAliasInteractivePrimaryHover, + pressed = StyleDictionaryColor.colorAliasInteractivePrimaryPressed, + ), + border = SirioColorState( + focused = StyleDictionaryColor.colorAliasInteractiveBorderFocus, + ), + content = SirioColorState.all(StyleDictionaryColor.colorAliasTextColorPrimaryLight0) + ), + drawerItemInfo = SirioMenuSpallaDrawerItemInfoColors( + background = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight50, + border = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight60, + content = StyleDictionaryColor.colorAliasTextColorPrimaryDark110, + ), + itemTitleSection = SirioMenuSpallaItemTitleSectionColors( + background = Color.Transparent, + border = StyleDictionaryColor.colorAliasInteractivePrimaryDefault, + content = StyleDictionaryColor.colorAliasInteractivePrimaryDefault, + ), + itemPrimary = SirioMenuSpallaItemColors( + background = SirioColorState( + default = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight0, + disabled = StyleDictionaryColor.colorAliasBackgroundColorDisabled, + focused = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight0, + hovered = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight0, + pressed = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight50, + ), + border = SirioColorState( + focused = StyleDictionaryColor.colorAliasInteractiveBorderFocus, + ), + indicator = SirioColorState( + default = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight0, + disabled = StyleDictionaryColor.colorAliasBackgroundColorDisabled, + focused = StyleDictionaryColor.colorAliasInteractivePrimaryDefault, + hovered = StyleDictionaryColor.colorAliasInteractivePrimaryHover, + pressed = StyleDictionaryColor.colorAliasInteractivePrimaryPressed, + ), + divider = SirioColorState( + default = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight60, + disabled = StyleDictionaryColor.colorAliasBackgroundColorDisabled, + focused = StyleDictionaryColor.colorAliasInteractiveBorderFocus, + hovered = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight60, + pressed = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight50, + ), + content = SirioColorState( + default = StyleDictionaryColor.colorAliasInteractiveSecondaryDefault, + disabled = StyleDictionaryColor.colorAliasTextColorDisabled, + focused = StyleDictionaryColor.colorAliasInteractivePrimaryDefault, + hovered = StyleDictionaryColor.colorAliasInteractivePrimaryHover, + pressed = StyleDictionaryColor.colorAliasInteractivePrimaryPressed, + ), + tag = tagLightColors.green, + tagDisabled = tagLightColors.gray, + ), + itemSecondary = SirioMenuSpallaItemColors( + background = SirioColorState( + default = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight40, + disabled = StyleDictionaryColor.colorAliasBackgroundColorDisabled, + focused = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight40, + hovered = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight40, + pressed = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight50, + ), + border = SirioColorState( + focused = StyleDictionaryColor.colorAliasInteractiveBorderFocus, + ), + indicator = SirioColorState( + focused = StyleDictionaryColor.colorAliasInteractivePrimaryDefault, + hovered = StyleDictionaryColor.colorAliasInteractivePrimaryHover, + pressed = StyleDictionaryColor.colorAliasInteractivePrimaryPressed, + ), + divider = SirioColorState( + default = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight60, + disabled = StyleDictionaryColor.colorAliasBackgroundColorDisabled, + focused = StyleDictionaryColor.colorAliasInteractiveBorderFocus, + hovered = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight60, + pressed = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight50, + ), + content = SirioColorState( + default = StyleDictionaryColor.colorAliasInteractiveSecondaryDefault, + disabled = StyleDictionaryColor.colorAliasTextColorDisabled, + focused = StyleDictionaryColor.colorAliasInteractivePrimaryDefault, + hovered = StyleDictionaryColor.colorAliasInteractivePrimaryHover, + pressed = StyleDictionaryColor.colorAliasInteractivePrimaryPressed, + ), + ), + itemTertiary = SirioMenuSpallaItemColors( + background = SirioColorState( + default = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight40, + disabled = StyleDictionaryColor.colorAliasBackgroundColorDisabled, + focused = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight40, + hovered = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight40, + pressed = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight40, + ), + border = SirioColorState( + focused = StyleDictionaryColor.colorAliasInteractiveBorderFocus, + ), + indicator = SirioColorState( + pressed = StyleDictionaryColor.colorAliasInteractivePrimaryPressed, + ), + divider = SirioColorState( + default = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight60, + disabled = StyleDictionaryColor.colorAliasBackgroundColorDisabled, + focused = StyleDictionaryColor.colorAliasInteractiveBorderFocus, + hovered = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight60, + pressed = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight50, + ), + content = SirioColorState( + default = StyleDictionaryColor.colorAliasInteractiveSecondaryDefault, + disabled = StyleDictionaryColor.colorAliasTextColorDisabled, + focused = StyleDictionaryColor.colorAliasInteractivePrimaryDefault, + hovered = StyleDictionaryColor.colorAliasInteractivePrimaryHover, + pressed = StyleDictionaryColor.colorAliasInteractivePrimaryPressed, + ), + ), +) + internal val LightColorPalette = SirioColors( brand = StyleDictionaryColor.colorGlobalPrimary100, accordion = SirioAccordionColors( @@ -176,6 +326,13 @@ internal val LightColorPalette = SirioColors( appNavigationText = StyleDictionaryColor.colorAliasTextColorPrimaryDark110, appNavigationUsernameBackground = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight50, appNavigationUsernameText = StyleDictionaryColor.colorAliasInteractivePrimaryDefault, + avviso = SirioAvvisoColors( + background = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight50, + borderBottom = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight50, + icon = StyleDictionaryColor.colorAliasTextColorSecondaryDark100, + text = StyleDictionaryColor.colorGlobalDarkPrimary130, + title = StyleDictionaryColor.colorAliasTextColorSecondaryDark100, + ), badge = SirioBadgeColors( background = StyleDictionaryColor.colorGlobalSemanticAlert100, border = StyleDictionaryColor.colorGlobalPrimary000 @@ -265,6 +422,34 @@ internal val LightColorPalette = SirioColors( title = StyleDictionaryColor.colorAliasTextColorSecondaryDark100, text = StyleDictionaryColor.colorAliasTextColorSecondaryDark100, ), + dropdown = SirioDropdownColors( + option = SirioDropdownOptionColors( + background = SirioColorState( + default = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight0, + disabled = StyleDictionaryColor.colorAliasBackgroundColorDisabled, + focused = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight0, + hovered = StyleDictionaryColor.colorSpecificOptionBackgroundColorHover, + pressed = StyleDictionaryColor.colorSpecificOptionBackgroundColorPressed, + valued = StyleDictionaryColor.colorSpecificOptionBackgroundColorValued, + ), + border = SirioColorState( + default = StyleDictionaryColor.colorSpecificDataEntryBorderColorDefault, + disabled = StyleDictionaryColor.colorAliasTextColorDisabled, + focused = StyleDictionaryColor.colorSpecificDataEntryBorderColorFocus, + hovered = StyleDictionaryColor.colorSpecificDataEntryBorderColorHover, + pressed = StyleDictionaryColor.colorSpecificOptionBackgroundColorPressed, + valued = StyleDictionaryColor.colorSpecificOptionBackgroundColorValued, + ), + content = SirioColorState( + default = StyleDictionaryColor.colorSpecificDataEntryPlaceholderColorDefault, + disabled = StyleDictionaryColor.colorAliasTextColorDisabled, + focused = StyleDictionaryColor.colorSpecificDataEntryLabelColorDefault, + hovered = StyleDictionaryColor.colorAliasTextColorPrimaryLight0, + pressed = StyleDictionaryColor.colorAliasTextColorPrimaryLight0, + valued = StyleDictionaryColor.colorAliasTextColorPrimaryLight0, + ) + ) + ), fabBorderFocus = StyleDictionaryColor.colorAliasInteractiveBorderFocus, fabContent = StyleDictionaryColor.colorAliasTextColorPrimaryLight0, fabDefaultBackground = StyleDictionaryColor.colorAliasInteractivePrimaryDefault, @@ -273,6 +458,7 @@ internal val LightColorPalette = SirioColors( fabPressedBackground = StyleDictionaryColor.colorAliasInteractivePrimaryPressed, fileUploadText = StyleDictionaryColor.colorAliasInteractiveSecondaryDefault, fileUploadTitle = StyleDictionaryColor.colorSpecificDataEntryLabelColorDefault, + filter = sirioFilterLightColors, hero = SirioHeroColors( background = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight0, title = StyleDictionaryColor.colorGlobalDarkPrimary115, @@ -280,10 +466,12 @@ internal val LightColorPalette = SirioColors( text = StyleDictionaryColor.colorAliasTextColorSecondaryDark100, borderBottom = StyleDictionaryColor.colorAliasTextColorPrimaryLight50, ), + menuSpalla = menuSpallaLightColors, notificationColors = NotificationColors( background = StyleDictionaryColor.colorAliasBackgroundColorPrimaryDark120, title = StyleDictionaryColor.colorAliasTextColorPrimaryLight0, text = StyleDictionaryColor.colorAliasTextColorPrimaryLight0, + link = StyleDictionaryColor.colorAliasInteractiveAccentDefault, icon = StyleDictionaryColor.colorAliasTextColorPrimaryLight0, close = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight0, alert = StyleDictionaryColor.colorGlobalSemanticAlert100, @@ -370,9 +558,61 @@ internal val LightColorPalette = SirioColors( sliderText = StyleDictionaryColor.colorAliasInteractiveSecondaryDefault, sliderThumb = StyleDictionaryColor.colorAliasInteractivePrimaryDefault, sliderTitle = StyleDictionaryColor.colorSpecificDataEntryLabelColorDefault, + stepProgressBar = SirioStepProgressBarColors( + action = StyleDictionaryColor.colorAliasAppInteractiveSecondaryDefault, + controls = SirioStepControlsColors( + background = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight40, + next = StyleDictionaryColor.colorAliasInteractivePrimaryDefault, + previous = StyleDictionaryColor.colorGlobalSecondary100, + ), + selection = SirioStepSelectionColors( + background = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight40, + progress = StyleDictionaryColor.colorGlobalSecondary100, + currentStep = StyleDictionaryColor.colorAliasInteractivePrimaryDefault, + ) + ), tabBarActive = StyleDictionaryColor.colorAliasAppInteractivePrimaryActive, tabBarBackground = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight0, tabBarContent = StyleDictionaryColor.colorAliasAppInteractiveSecondaryDefault, + table = SirioTableColors( + cell = SirioTableCellColors( + avatarSubtitle = StyleDictionaryColor.colorSpecificDataEntryLabelColorDefault, + avatarTitle = StyleDictionaryColor.colorAliasTextColorSecondaryDark130, + background = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight0, + icon = StyleDictionaryColor.colorAliasInteractivePrimaryDefault, + link = StyleDictionaryColor.colorAliasInteractivePrimaryDefault, + number = StyleDictionaryColor.colorAliasTextColorSecondaryDark130, + title = StyleDictionaryColor.colorSpecificDataEntryLabelColorDefault, + ), + component = SirioTableComponentColors( + border = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight50, + scrollIndicator = StyleDictionaryColor.colorAliasInteractiveAccentDefault, + ), + drawer = SirioTableDrawerColors( + actionsText = StyleDictionaryColor.colorAliasTextColorPrimaryLight0, + background = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight0, + border = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight50, + title = StyleDictionaryColor.colorAliasTextColorPrimary100, + iconsBackground = StyleDictionaryColor.colorGlobalPrimary100, + itemTitle = StyleDictionaryColor.colorSpecificDataEntryLabelColorDefault, + itemText = StyleDictionaryColor.colorSpecificDataEntryPlaceholderColorDefault, + itemNumber = StyleDictionaryColor.colorSpecificDataEntryPlaceholderColorDefault, + itemLink = StyleDictionaryColor.colorAliasInteractivePrimaryDefault, + ), + header = SirioTableHeaderColors( + background = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight40, + icon = StyleDictionaryColor.colorAliasInteractivePrimaryDefault, + title = StyleDictionaryColor.colorSpecificDataEntryLabelColorDefault, + ), + vertical = SirioTableVerticalColors( + background = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight0, + border = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight50, + itemTitle = StyleDictionaryColor.colorSpecificDataEntryLabelColorDefault, + itemText = StyleDictionaryColor.colorSpecificDataEntryLabelColorDefault, + itemNumber = StyleDictionaryColor.colorAliasTextColorSecondaryDark130, + itemLink = StyleDictionaryColor.colorAliasInteractivePrimaryDefault, + ), + ), tabs = SirioTabsColors( backgroundBottomSelection = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight0, backgroundTopSelection = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight40, @@ -411,7 +651,8 @@ internal val LightColorPalette = SirioColors( focused = StyleDictionaryColor.colorSpecificDataEntryBorderColorFocus, hovered = StyleDictionaryColor.colorSpecificDataEntryBorderColorHover, pressed = StyleDictionaryColor.colorSpecificDataEntryBorderColorValued, - alert = StyleDictionaryColor.colorSpecificDataEntryBorderColorError, + valued = StyleDictionaryColor.colorSpecificDataEntryBorderColorValued, + alert = StyleDictionaryColor.colorGlobalSemanticAlert100, warning = StyleDictionaryColor.colorSpecificDataEntryBorderColorWarning, success = StyleDictionaryColor.colorSpecificDataEntryBorderColorSuccess, info = StyleDictionaryColor.colorSpecificDataEntryBorderColorDefault, @@ -437,9 +678,10 @@ internal val LightColorPalette = SirioColors( focused = StyleDictionaryColor.colorSpecificDataEntryLabelColorFocus, hovered = StyleDictionaryColor.colorSpecificDataEntryLabelColorHover, pressed = StyleDictionaryColor.colorSpecificDataEntryLabelColorValued, - alert = StyleDictionaryColor.colorSpecificDataEntryBorderColorError, + valued = StyleDictionaryColor.colorSpecificDataEntryLabelColorValued, + alert = StyleDictionaryColor.colorSpecificDataEntryLabelColorAlert, warning = StyleDictionaryColor.colorSpecificDataEntryBorderColorWarning, - success = StyleDictionaryColor.colorSpecificDataEntryBorderColorSuccess, + success = StyleDictionaryColor.colorSpecificDataEntryLabelColorSuccess, info = StyleDictionaryColor.colorSpecificDataEntryLabelColorDefault, ), icon = SirioColorState( @@ -448,7 +690,8 @@ internal val LightColorPalette = SirioColors( focused = StyleDictionaryColor.colorAliasInteractivePrimaryDefault, hovered = StyleDictionaryColor.colorAliasInteractivePrimaryHover, pressed = StyleDictionaryColor.colorAliasInteractiveSecondaryDefault, - alert = StyleDictionaryColor.colorSpecificDataEntryBorderColorError, + valued = StyleDictionaryColor.colorAliasInteractiveSecondaryDefault, + alert = StyleDictionaryColor.colorGlobalSemanticAlert100, warning = StyleDictionaryColor.colorSpecificDataEntryBorderColorWarning, success = StyleDictionaryColor.colorSpecificDataEntryBorderColorSuccess, info = StyleDictionaryColor.colorAliasInteractiveSecondaryDefault, @@ -459,6 +702,7 @@ internal val LightColorPalette = SirioColors( focused = StyleDictionaryColor.colorAliasInteractivePrimaryDefault, hovered = StyleDictionaryColor.colorAliasInteractivePrimaryHover, pressed = StyleDictionaryColor.colorAliasInteractiveSecondaryDefault, + valued = StyleDictionaryColor.colorAliasInteractiveSecondaryDefault, alert = StyleDictionaryColor.colorGlobalSemanticAlert100, warning = StyleDictionaryColor.colorGlobalSemanticWarning100, success = StyleDictionaryColor.colorGlobalSemanticSuccess100, @@ -470,9 +714,10 @@ internal val LightColorPalette = SirioColors( focused = StyleDictionaryColor.colorSpecificDataEntryPlaceholderColorFocus, hovered = StyleDictionaryColor.colorSpecificDataEntryPlaceholderColorHover, pressed = StyleDictionaryColor.colorSpecificDataEntryPlaceholderColorValued, - alert = StyleDictionaryColor.colorSpecificDataEntryBorderColorError, + valued = StyleDictionaryColor.colorSpecificDataEntryPlaceholderColorValued, + alert = StyleDictionaryColor.colorSpecificDataEntryPlaceholderColorDefault, warning = StyleDictionaryColor.colorSpecificDataEntryBorderColorWarning, - success = StyleDictionaryColor.colorSpecificDataEntryBorderColorSuccess, + success = StyleDictionaryColor.colorSpecificDataEntryPlaceholderColorDefault, info = StyleDictionaryColor.colorSpecificDataEntryPlaceholderColorDefault, ), text = SirioColorState( @@ -481,7 +726,8 @@ internal val LightColorPalette = SirioColors( focused = StyleDictionaryColor.colorSpecificDataEntryPlaceholderColorFocus, hovered = StyleDictionaryColor.colorSpecificDataEntryPlaceholderColorHover, pressed = StyleDictionaryColor.colorSpecificDataEntryPlaceholderColorValued, - alert = StyleDictionaryColor.colorSpecificDataEntryBorderColorError, + valued = StyleDictionaryColor.colorSpecificDataEntryPlaceholderColorValued, + alert = StyleDictionaryColor.colorGlobalSemanticAlert100, warning = StyleDictionaryColor.colorSpecificDataEntryBorderColorWarning, success = StyleDictionaryColor.colorSpecificDataEntryBorderColorSuccess, info = StyleDictionaryColor.colorSpecificDataEntryPlaceholderColorDefault, @@ -496,7 +742,8 @@ internal val LightColorPalette = SirioColors( focused = StyleDictionaryColor.colorSpecificDataEntryBorderColorFocus, hovered = StyleDictionaryColor.colorSpecificDataEntryBorderColorHover, pressed = StyleDictionaryColor.colorSpecificDataEntryBorderColorValued, - alert = StyleDictionaryColor.colorSpecificDataEntryBorderColorError, + valued = StyleDictionaryColor.colorSpecificDataEntryBorderColorValued, + alert = StyleDictionaryColor.colorGlobalSemanticAlert100, warning = StyleDictionaryColor.colorSpecificDataEntryBorderColorWarning, success = StyleDictionaryColor.colorSpecificDataEntryBorderColorSuccess, info = StyleDictionaryColor.colorSpecificDataEntryBorderColorDefault, @@ -522,9 +769,10 @@ internal val LightColorPalette = SirioColors( focused = StyleDictionaryColor.colorSpecificDataEntryLabelColorFocus, hovered = StyleDictionaryColor.colorSpecificDataEntryLabelColorHover, pressed = StyleDictionaryColor.colorSpecificDataEntryLabelColorValued, - alert = StyleDictionaryColor.colorSpecificDataEntryBorderColorError, - warning = StyleDictionaryColor.colorSpecificDataEntryBorderColorWarning, - success = StyleDictionaryColor.colorSpecificDataEntryBorderColorSuccess, + valued = StyleDictionaryColor.colorSpecificDataEntryLabelColorValued, + alert = StyleDictionaryColor.colorSpecificDataEntryLabelColorAlert, + warning = StyleDictionaryColor.colorSpecificDataEntryLabelColorWarning, + success = StyleDictionaryColor.colorSpecificDataEntryLabelColorSuccess, info = StyleDictionaryColor.colorSpecificDataEntryLabelColorDefault, ), icon = SirioColorState( @@ -533,7 +781,8 @@ internal val LightColorPalette = SirioColors( focused = StyleDictionaryColor.colorAliasInteractivePrimaryDefault, hovered = StyleDictionaryColor.colorAliasInteractivePrimaryHover, pressed = StyleDictionaryColor.colorAliasInteractiveSecondaryDefault, - alert = StyleDictionaryColor.colorSpecificDataEntryBorderColorError, + valued = StyleDictionaryColor.colorAliasInteractiveSecondaryDefault, + alert = StyleDictionaryColor.colorGlobalSemanticAlert100, warning = StyleDictionaryColor.colorSpecificDataEntryBorderColorWarning, success = StyleDictionaryColor.colorSpecificDataEntryBorderColorSuccess, info = StyleDictionaryColor.colorAliasInteractiveSecondaryDefault, @@ -544,6 +793,7 @@ internal val LightColorPalette = SirioColors( focused = StyleDictionaryColor.colorAliasInteractivePrimaryDefault, hovered = StyleDictionaryColor.colorAliasInteractivePrimaryHover, pressed = StyleDictionaryColor.colorAliasInteractiveSecondaryDefault, + valued = StyleDictionaryColor.colorAliasInteractiveSecondaryDefault, alert = StyleDictionaryColor.colorGlobalSemanticAlert100, warning = StyleDictionaryColor.colorGlobalSemanticWarning100, success = StyleDictionaryColor.colorGlobalSemanticSuccess100, @@ -555,9 +805,10 @@ internal val LightColorPalette = SirioColors( focused = StyleDictionaryColor.colorSpecificDataEntryPlaceholderColorFocus, hovered = StyleDictionaryColor.colorSpecificDataEntryPlaceholderColorHover, pressed = StyleDictionaryColor.colorSpecificDataEntryPlaceholderColorValued, - alert = StyleDictionaryColor.colorSpecificDataEntryBorderColorError, - warning = StyleDictionaryColor.colorSpecificDataEntryBorderColorWarning, - success = StyleDictionaryColor.colorSpecificDataEntryBorderColorSuccess, + valued = StyleDictionaryColor.colorSpecificDataEntryPlaceholderColorValued, + alert = StyleDictionaryColor.colorSpecificDataEntryPlaceholderColorDefault, + warning = StyleDictionaryColor.colorSpecificDataEntryPlaceholderColorDefault, + success = StyleDictionaryColor.colorSpecificDataEntryPlaceholderColorDefault, info = StyleDictionaryColor.colorSpecificDataEntryPlaceholderColorDefault, ), text = SirioColorState( @@ -566,12 +817,17 @@ internal val LightColorPalette = SirioColors( focused = StyleDictionaryColor.colorSpecificDataEntryPlaceholderColorFocus, hovered = StyleDictionaryColor.colorSpecificDataEntryPlaceholderColorHover, pressed = StyleDictionaryColor.colorSpecificDataEntryPlaceholderColorValued, - alert = StyleDictionaryColor.colorSpecificDataEntryBorderColorError, + valued = StyleDictionaryColor.colorSpecificDataEntryPlaceholderColorValued, + alert = StyleDictionaryColor.colorGlobalSemanticAlert100, warning = StyleDictionaryColor.colorSpecificDataEntryBorderColorWarning, success = StyleDictionaryColor.colorSpecificDataEntryBorderColorSuccess, info = StyleDictionaryColor.colorSpecificDataEntryPlaceholderColorDefault, ), ), + titleBar = SirioTitleBarColors( + container = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight40, + content = StyleDictionaryColor.colorAliasInteractivePrimaryDefault, + ), toggle = SirioToggleColors( background = SirioColorState.all( StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight0, @@ -676,6 +932,136 @@ private val buttonsDarkColors = ButtonColors( ), ) +private val sirioFilterDarkColors = SirioFilterColors( + background = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight40, + close = StyleDictionaryColor.colorAliasInteractivePrimaryDefault, + header = StyleDictionaryColor.colorGlobalDarkPrimary115, + info = StyleDictionaryColor.colorGlobalSemanticInfo100, + selectedBackground = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight40, + title = StyleDictionaryColor.colorSpecificDataEntryLabelColorDefault, +) + +private val menuSpallaDarkColors = SirioMenuSpallaColors( + background = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight0, + drawerItem = SirioMenuSpallaDrawerItemColors( + background = SirioColorState( + default = StyleDictionaryColor.colorAliasInteractivePrimaryDefault, + focused = StyleDictionaryColor.colorAliasInteractivePrimaryFocus, + hovered = StyleDictionaryColor.colorAliasInteractivePrimaryHover, + pressed = StyleDictionaryColor.colorAliasInteractivePrimaryPressed, + ), + border = SirioColorState( + focused = StyleDictionaryColor.colorAliasInteractiveBorderFocus, + ), + content = SirioColorState.all(StyleDictionaryColor.colorAliasTextColorPrimaryLight0) + ), + drawerItemInfo = SirioMenuSpallaDrawerItemInfoColors( + background = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight50, + border = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight60, + content = StyleDictionaryColor.colorAliasTextColorPrimaryDark110, + ), + itemTitleSection = SirioMenuSpallaItemTitleSectionColors( + background = Color.Transparent, + border = StyleDictionaryColor.colorAliasInteractivePrimaryDefault, + content = StyleDictionaryColor.colorAliasInteractivePrimaryDefault, + ), + itemPrimary = SirioMenuSpallaItemColors( + background = SirioColorState( + default = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight0, + disabled = StyleDictionaryColor.colorAliasBackgroundColorDisabled, + focused = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight0, + hovered = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight0, + pressed = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight50, + ), + border = SirioColorState( + focused = StyleDictionaryColor.colorAliasInteractiveBorderFocus, + ), + indicator = SirioColorState( + default = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight0, + disabled = StyleDictionaryColor.colorAliasBackgroundColorDisabled, + focused = StyleDictionaryColor.colorAliasInteractivePrimaryDefault, + hovered = StyleDictionaryColor.colorAliasInteractivePrimaryHover, + pressed = StyleDictionaryColor.colorAliasInteractivePrimaryPressed, + ), + divider = SirioColorState( + default = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight60, + disabled = StyleDictionaryColor.colorAliasBackgroundColorDisabled, + focused = StyleDictionaryColor.colorAliasInteractiveBorderFocus, + hovered = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight60, + pressed = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight50, + ), + content = SirioColorState( + default = StyleDictionaryColor.colorAliasInteractiveSecondaryDefault, + disabled = StyleDictionaryColor.colorAliasTextColorDisabled, + focused = StyleDictionaryColor.colorAliasInteractivePrimaryDefault, + hovered = StyleDictionaryColor.colorAliasInteractivePrimaryHover, + pressed = StyleDictionaryColor.colorAliasInteractivePrimaryPressed, + ), + tag = tagLightColors.green, + tagDisabled = tagLightColors.gray, + ), + itemSecondary = SirioMenuSpallaItemColors( + background = SirioColorState( + default = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight40, + disabled = StyleDictionaryColor.colorAliasBackgroundColorDisabled, + focused = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight40, + hovered = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight40, + pressed = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight50, + ), + border = SirioColorState( + focused = StyleDictionaryColor.colorAliasInteractiveBorderFocus, + ), + indicator = SirioColorState( + focused = StyleDictionaryColor.colorAliasInteractivePrimaryDefault, + hovered = StyleDictionaryColor.colorAliasInteractivePrimaryHover, + pressed = StyleDictionaryColor.colorAliasInteractivePrimaryPressed, + ), + divider = SirioColorState( + default = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight60, + disabled = StyleDictionaryColor.colorAliasBackgroundColorDisabled, + focused = StyleDictionaryColor.colorAliasInteractiveBorderFocus, + hovered = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight60, + pressed = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight50, + ), + content = SirioColorState( + default = StyleDictionaryColor.colorAliasInteractiveSecondaryDefault, + disabled = StyleDictionaryColor.colorAliasTextColorDisabled, + focused = StyleDictionaryColor.colorAliasInteractivePrimaryDefault, + hovered = StyleDictionaryColor.colorAliasInteractivePrimaryHover, + pressed = StyleDictionaryColor.colorAliasInteractivePrimaryPressed, + ), + ), + itemTertiary = SirioMenuSpallaItemColors( + background = SirioColorState( + default = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight40, + disabled = StyleDictionaryColor.colorAliasBackgroundColorDisabled, + focused = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight40, + hovered = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight40, + pressed = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight40, + ), + border = SirioColorState( + focused = StyleDictionaryColor.colorAliasInteractiveBorderFocus, + ), + indicator = SirioColorState( + pressed = StyleDictionaryColor.colorAliasInteractivePrimaryPressed, + ), + divider = SirioColorState( + default = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight60, + disabled = StyleDictionaryColor.colorAliasBackgroundColorDisabled, + focused = StyleDictionaryColor.colorAliasInteractiveBorderFocus, + hovered = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight60, + pressed = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight50, + ), + content = SirioColorState( + default = StyleDictionaryColor.colorAliasInteractiveSecondaryDefault, + disabled = StyleDictionaryColor.colorAliasTextColorDisabled, + focused = StyleDictionaryColor.colorAliasInteractivePrimaryDefault, + hovered = StyleDictionaryColor.colorAliasInteractivePrimaryHover, + pressed = StyleDictionaryColor.colorAliasInteractivePrimaryPressed, + ), + ), +) + private val tagDarkColors = SirioTagsColors( gray = SirioTagColors( background = StyleDictionaryColor.colorAliasInteractiveSecondaryDefault, @@ -703,6 +1089,7 @@ private val tagDarkColors = SirioTagsColors( ), ) + internal val DarkColorPalette = SirioColors( brand = StyleDictionaryColor.colorGlobalPrimary000, accordion = SirioAccordionColors( @@ -739,6 +1126,13 @@ internal val DarkColorPalette = SirioColors( appNavigationText = StyleDictionaryColor.colorAliasTextColorPrimaryLight50, appNavigationUsernameBackground = StyleDictionaryColor.colorAliasBackgroundColorPrimaryDark115, appNavigationUsernameText = StyleDictionaryColor.colorAliasInteractivePrimary000Default, + avviso = SirioAvvisoColors( + background = StyleDictionaryColor.colorAliasBackgroundColorPrimaryDark115, + borderBottom = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight50, + icon = StyleDictionaryColor.colorAliasTextColorPrimaryLight40, + text = StyleDictionaryColor.colorAliasTextColorPrimaryLight40, + title = StyleDictionaryColor.colorAliasTextColorPrimaryLight40, + ), badge = SirioBadgeColors( background = StyleDictionaryColor.colorGlobalSemanticAlert100, border = StyleDictionaryColor.colorGlobalPrimary000 @@ -828,6 +1222,34 @@ internal val DarkColorPalette = SirioColors( title = StyleDictionaryColor.colorAliasTextColorSecondaryDark100, text = StyleDictionaryColor.colorAliasTextColorSecondaryDark100, ), + dropdown = SirioDropdownColors( + option = SirioDropdownOptionColors( + background = SirioColorState( + default = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight0, + disabled = StyleDictionaryColor.colorAliasBackgroundColorDisabled, + focused = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight0, + hovered = StyleDictionaryColor.colorSpecificOptionBackgroundColorHover, + pressed = StyleDictionaryColor.colorSpecificOptionBackgroundColorPressed, + valued = StyleDictionaryColor.colorSpecificOptionBackgroundColorValued, + ), + border = SirioColorState( + default = StyleDictionaryColor.colorSpecificDataEntryBorderColorDefault, + disabled = StyleDictionaryColor.colorAliasTextColorDisabled, + focused = StyleDictionaryColor.colorSpecificDataEntryBorderColorFocus, + hovered = StyleDictionaryColor.colorSpecificDataEntryBorderColorHover, + pressed = StyleDictionaryColor.colorSpecificOptionBackgroundColorPressed, + valued = StyleDictionaryColor.colorSpecificOptionBackgroundColorValued, + ), + content = SirioColorState( + default = StyleDictionaryColor.colorSpecificDataEntryPlaceholderColorDefault, + disabled = StyleDictionaryColor.colorAliasTextColorDisabled, + focused = StyleDictionaryColor.colorSpecificDataEntryLabelColorDefault, + hovered = StyleDictionaryColor.colorAliasTextColorPrimaryLight0, + pressed = StyleDictionaryColor.colorAliasTextColorPrimaryLight0, + valued = StyleDictionaryColor.colorAliasTextColorPrimaryLight0, + ) + ) + ), fabBorderFocus = StyleDictionaryColor.colorAliasInteractiveBorderFocus, fabContent = StyleDictionaryColor.colorAliasTextColorPrimaryDark110, fabDefaultBackground = StyleDictionaryColor.colorAliasAppInteractivePrimary000Default, @@ -836,6 +1258,7 @@ internal val DarkColorPalette = SirioColors( fabPressedBackground = StyleDictionaryColor.colorAliasInteractiveAccentDefault, fileUploadText = StyleDictionaryColor.colorAliasInteractiveSecondaryDefault, fileUploadTitle = StyleDictionaryColor.colorSpecificDataEntryLabelColorDefault, + filter = sirioFilterDarkColors, hero = SirioHeroColors( background = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight0, title = StyleDictionaryColor.colorGlobalDarkPrimary115, @@ -843,10 +1266,12 @@ internal val DarkColorPalette = SirioColors( text = StyleDictionaryColor.colorAliasTextColorSecondaryDark100, borderBottom = StyleDictionaryColor.colorAliasTextColorPrimaryLight50, ), + menuSpalla = menuSpallaDarkColors, notificationColors = NotificationColors( background = StyleDictionaryColor.colorAliasBackgroundColorPrimaryDark120, title = StyleDictionaryColor.colorAliasTextColorPrimaryLight0, text = StyleDictionaryColor.colorAliasTextColorPrimaryLight0, + link = StyleDictionaryColor.colorAliasInteractiveAccentDefault, icon = StyleDictionaryColor.colorAliasTextColorPrimaryLight0, close = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight0, alert = StyleDictionaryColor.colorGlobalSemanticAlert100, @@ -933,9 +1358,61 @@ internal val DarkColorPalette = SirioColors( sliderText = StyleDictionaryColor.colorAliasInteractiveSecondaryDefault, sliderThumb = StyleDictionaryColor.colorAliasInteractivePrimaryDefault, sliderTitle = StyleDictionaryColor.colorSpecificDataEntryLabelColorDefault, + stepProgressBar = SirioStepProgressBarColors( + action = StyleDictionaryColor.colorAliasAppInteractiveSecondaryDefault, + controls = SirioStepControlsColors( + background = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight40, + next = StyleDictionaryColor.colorAliasInteractivePrimaryDefault, + previous = StyleDictionaryColor.colorGlobalSecondary100, + ), + selection = SirioStepSelectionColors( + background = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight40, + progress = StyleDictionaryColor.colorGlobalSecondary100, + currentStep = StyleDictionaryColor.colorAliasInteractivePrimaryDefault, + ), + ), tabBarActive = StyleDictionaryColor.colorAliasAppInteractivePrimaryActive, tabBarBackground = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight0, tabBarContent = StyleDictionaryColor.colorAliasAppInteractiveSecondaryDefault, + table = SirioTableColors( + cell = SirioTableCellColors( + avatarSubtitle = StyleDictionaryColor.colorSpecificDataEntryLabelColorDefault, + avatarTitle = StyleDictionaryColor.colorAliasTextColorSecondaryDark130, + background = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight0, + icon = StyleDictionaryColor.colorAliasInteractivePrimaryDefault, + link = StyleDictionaryColor.colorAliasInteractivePrimaryDefault, + number = StyleDictionaryColor.colorAliasTextColorSecondaryDark130, + title = StyleDictionaryColor.colorSpecificDataEntryLabelColorDefault, + ), + component = SirioTableComponentColors( + border = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight50, + scrollIndicator = StyleDictionaryColor.colorAliasInteractiveAccentDefault, + ), + drawer = SirioTableDrawerColors( + actionsText = StyleDictionaryColor.colorAliasTextColorPrimaryLight0, + background = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight0, + border = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight50, + iconsBackground = StyleDictionaryColor.colorGlobalPrimary100, + title = StyleDictionaryColor.colorAliasTextColorPrimary100, + itemTitle = StyleDictionaryColor.colorSpecificDataEntryLabelColorDefault, + itemText = StyleDictionaryColor.colorSpecificDataEntryPlaceholderColorDefault, + itemNumber = StyleDictionaryColor.colorSpecificDataEntryPlaceholderColorDefault, + itemLink = StyleDictionaryColor.colorAliasInteractivePrimaryDefault, + ), + header = SirioTableHeaderColors( + background = StyleDictionaryColor.colorAliasBackgroundColorPrimaryDark115, + icon = StyleDictionaryColor.colorAliasInteractiveAccentDefault, + title = StyleDictionaryColor.colorAliasTextColorPrimaryLight0, + ), + vertical = SirioTableVerticalColors( + background = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight40, + border = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight50, + itemTitle = StyleDictionaryColor.colorSpecificDataEntryLabelColorDefault, + itemText = StyleDictionaryColor.colorSpecificDataEntryLabelColorDefault, + itemNumber = StyleDictionaryColor.colorAliasTextColorSecondaryDark130, + itemLink = StyleDictionaryColor.colorAliasInteractivePrimaryDefault, + ) + ), tabs = SirioTabsColors( backgroundBottomSelection = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight0, backgroundTopSelection = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight40, @@ -971,17 +1448,18 @@ internal val DarkColorPalette = SirioColors( border = SirioColorState( default = StyleDictionaryColor.colorSpecificDataEntryBorderColorDefault, disabled = StyleDictionaryColor.colorAliasBackgroundColorDisabled, - focused = StyleDictionaryColor.colorSpecificDataEntryLabelColorFocus, + focused = StyleDictionaryColor.colorSpecificDataEntryBorderColorFocus, hovered = StyleDictionaryColor.colorSpecificDataEntryBorderColorHover, pressed = StyleDictionaryColor.colorSpecificDataEntryBorderColorValued, - alert = StyleDictionaryColor.colorSpecificDataEntryBorderColorError, + valued = StyleDictionaryColor.colorSpecificDataEntryBorderColorValued, + alert = StyleDictionaryColor.colorGlobalSemanticAlert100, warning = StyleDictionaryColor.colorSpecificDataEntryBorderColorWarning, success = StyleDictionaryColor.colorSpecificDataEntryBorderColorSuccess, info = StyleDictionaryColor.colorSpecificDataEntryBorderColorDefault, ), dropdown = SirioColorState.all(StyleDictionaryColor.colorAliasInteractiveSecondaryDefault), optionBackground = SirioColorState( - default = Color.Transparent, + default = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight0, disabled = StyleDictionaryColor.colorAliasBackgroundColorDisabled, focused = StyleDictionaryColor.colorSpecificOptionBackgroundColorFocus, hovered = StyleDictionaryColor.colorSpecificOptionBackgroundColorHover, @@ -1000,9 +1478,10 @@ internal val DarkColorPalette = SirioColors( focused = StyleDictionaryColor.colorSpecificDataEntryLabelColorFocus, hovered = StyleDictionaryColor.colorSpecificDataEntryLabelColorHover, pressed = StyleDictionaryColor.colorSpecificDataEntryLabelColorValued, - alert = StyleDictionaryColor.colorSpecificDataEntryBorderColorError, + valued = StyleDictionaryColor.colorSpecificDataEntryLabelColorValued, + alert = StyleDictionaryColor.colorSpecificDataEntryLabelColorAlert, warning = StyleDictionaryColor.colorSpecificDataEntryBorderColorWarning, - success = StyleDictionaryColor.colorSpecificDataEntryBorderColorSuccess, + success = StyleDictionaryColor.colorSpecificDataEntryLabelColorSuccess, info = StyleDictionaryColor.colorSpecificDataEntryLabelColorDefault, ), icon = SirioColorState( @@ -1011,7 +1490,8 @@ internal val DarkColorPalette = SirioColors( focused = StyleDictionaryColor.colorAliasInteractivePrimaryDefault, hovered = StyleDictionaryColor.colorAliasInteractivePrimaryHover, pressed = StyleDictionaryColor.colorAliasInteractiveSecondaryDefault, - alert = StyleDictionaryColor.colorSpecificDataEntryBorderColorError, + valued = StyleDictionaryColor.colorAliasInteractiveSecondaryDefault, + alert = StyleDictionaryColor.colorGlobalSemanticAlert100, warning = StyleDictionaryColor.colorSpecificDataEntryBorderColorWarning, success = StyleDictionaryColor.colorSpecificDataEntryBorderColorSuccess, info = StyleDictionaryColor.colorAliasInteractiveSecondaryDefault, @@ -1022,6 +1502,7 @@ internal val DarkColorPalette = SirioColors( focused = StyleDictionaryColor.colorAliasInteractivePrimaryDefault, hovered = StyleDictionaryColor.colorAliasInteractivePrimaryHover, pressed = StyleDictionaryColor.colorAliasInteractiveSecondaryDefault, + valued = StyleDictionaryColor.colorAliasInteractiveSecondaryDefault, alert = StyleDictionaryColor.colorGlobalSemanticAlert100, warning = StyleDictionaryColor.colorGlobalSemanticWarning100, success = StyleDictionaryColor.colorGlobalSemanticSuccess100, @@ -1033,9 +1514,10 @@ internal val DarkColorPalette = SirioColors( focused = StyleDictionaryColor.colorSpecificDataEntryPlaceholderColorFocus, hovered = StyleDictionaryColor.colorSpecificDataEntryPlaceholderColorHover, pressed = StyleDictionaryColor.colorSpecificDataEntryPlaceholderColorValued, - alert = StyleDictionaryColor.colorSpecificDataEntryBorderColorError, + valued = StyleDictionaryColor.colorSpecificDataEntryPlaceholderColorValued, + alert = StyleDictionaryColor.colorSpecificDataEntryPlaceholderColorDefault, warning = StyleDictionaryColor.colorSpecificDataEntryBorderColorWarning, - success = StyleDictionaryColor.colorSpecificDataEntryBorderColorSuccess, + success = StyleDictionaryColor.colorSpecificDataEntryPlaceholderColorDefault, info = StyleDictionaryColor.colorSpecificDataEntryPlaceholderColorDefault, ), text = SirioColorState( @@ -1044,7 +1526,8 @@ internal val DarkColorPalette = SirioColors( focused = StyleDictionaryColor.colorSpecificDataEntryPlaceholderColorFocus, hovered = StyleDictionaryColor.colorSpecificDataEntryPlaceholderColorHover, pressed = StyleDictionaryColor.colorSpecificDataEntryPlaceholderColorValued, - alert = StyleDictionaryColor.colorSpecificDataEntryBorderColorError, + valued = StyleDictionaryColor.colorSpecificDataEntryPlaceholderColorValued, + alert = StyleDictionaryColor.colorGlobalSemanticAlert100, warning = StyleDictionaryColor.colorSpecificDataEntryBorderColorWarning, success = StyleDictionaryColor.colorSpecificDataEntryBorderColorSuccess, info = StyleDictionaryColor.colorSpecificDataEntryPlaceholderColorDefault, @@ -1056,17 +1539,18 @@ internal val DarkColorPalette = SirioColors( border = SirioColorState( default = StyleDictionaryColor.colorSpecificDataEntryBorderColorDefault, disabled = StyleDictionaryColor.colorAliasBackgroundColorDisabled, - focused = StyleDictionaryColor.colorSpecificDataEntryLabelColorFocus, + focused = StyleDictionaryColor.colorSpecificDataEntryBorderColorFocus, hovered = StyleDictionaryColor.colorSpecificDataEntryBorderColorHover, pressed = StyleDictionaryColor.colorSpecificDataEntryBorderColorValued, - alert = StyleDictionaryColor.colorSpecificDataEntryBorderColorError, + valued = StyleDictionaryColor.colorSpecificDataEntryBorderColorValued, + alert = StyleDictionaryColor.colorGlobalSemanticAlert100, warning = StyleDictionaryColor.colorSpecificDataEntryBorderColorWarning, success = StyleDictionaryColor.colorSpecificDataEntryBorderColorSuccess, info = StyleDictionaryColor.colorSpecificDataEntryBorderColorDefault, ), dropdown = SirioColorState.all(StyleDictionaryColor.colorAliasInteractiveSecondaryDefault), optionBackground = SirioColorState( - default = Color.Transparent, + default = StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight0, disabled = StyleDictionaryColor.colorAliasBackgroundColorDisabled, focused = StyleDictionaryColor.colorSpecificOptionBackgroundColorFocus, hovered = StyleDictionaryColor.colorSpecificOptionBackgroundColorHover, @@ -1085,9 +1569,10 @@ internal val DarkColorPalette = SirioColors( focused = StyleDictionaryColor.colorSpecificDataEntryLabelColorFocus, hovered = StyleDictionaryColor.colorSpecificDataEntryLabelColorHover, pressed = StyleDictionaryColor.colorSpecificDataEntryLabelColorValued, - alert = StyleDictionaryColor.colorSpecificDataEntryBorderColorError, - warning = StyleDictionaryColor.colorSpecificDataEntryBorderColorWarning, - success = StyleDictionaryColor.colorSpecificDataEntryBorderColorSuccess, + valued = StyleDictionaryColor.colorSpecificDataEntryLabelColorValued, + alert = StyleDictionaryColor.colorSpecificDataEntryLabelColorAlert, + warning = StyleDictionaryColor.colorSpecificDataEntryLabelColorWarning, + success = StyleDictionaryColor.colorSpecificDataEntryLabelColorSuccess, info = StyleDictionaryColor.colorSpecificDataEntryLabelColorDefault, ), icon = SirioColorState( @@ -1096,7 +1581,8 @@ internal val DarkColorPalette = SirioColors( focused = StyleDictionaryColor.colorAliasInteractivePrimaryDefault, hovered = StyleDictionaryColor.colorAliasInteractivePrimaryHover, pressed = StyleDictionaryColor.colorAliasInteractiveSecondaryDefault, - alert = StyleDictionaryColor.colorSpecificDataEntryBorderColorError, + valued = StyleDictionaryColor.colorAliasInteractiveSecondaryDefault, + alert = StyleDictionaryColor.colorGlobalSemanticAlert100, warning = StyleDictionaryColor.colorSpecificDataEntryBorderColorWarning, success = StyleDictionaryColor.colorSpecificDataEntryBorderColorSuccess, info = StyleDictionaryColor.colorAliasInteractiveSecondaryDefault, @@ -1107,6 +1593,7 @@ internal val DarkColorPalette = SirioColors( focused = StyleDictionaryColor.colorAliasInteractivePrimaryDefault, hovered = StyleDictionaryColor.colorAliasInteractivePrimaryHover, pressed = StyleDictionaryColor.colorAliasInteractiveSecondaryDefault, + valued = StyleDictionaryColor.colorAliasInteractiveSecondaryDefault, alert = StyleDictionaryColor.colorGlobalSemanticAlert100, warning = StyleDictionaryColor.colorGlobalSemanticWarning100, success = StyleDictionaryColor.colorGlobalSemanticSuccess100, @@ -1118,9 +1605,10 @@ internal val DarkColorPalette = SirioColors( focused = StyleDictionaryColor.colorSpecificDataEntryPlaceholderColorFocus, hovered = StyleDictionaryColor.colorSpecificDataEntryPlaceholderColorHover, pressed = StyleDictionaryColor.colorSpecificDataEntryPlaceholderColorValued, - alert = StyleDictionaryColor.colorSpecificDataEntryBorderColorError, - warning = StyleDictionaryColor.colorSpecificDataEntryBorderColorWarning, - success = StyleDictionaryColor.colorSpecificDataEntryBorderColorSuccess, + valued = StyleDictionaryColor.colorSpecificDataEntryPlaceholderColorValued, + alert = StyleDictionaryColor.colorSpecificDataEntryPlaceholderColorDefault, + warning = StyleDictionaryColor.colorSpecificDataEntryPlaceholderColorDefault, + success = StyleDictionaryColor.colorSpecificDataEntryPlaceholderColorDefault, info = StyleDictionaryColor.colorSpecificDataEntryPlaceholderColorDefault, ), text = SirioColorState( @@ -1129,12 +1617,17 @@ internal val DarkColorPalette = SirioColors( focused = StyleDictionaryColor.colorSpecificDataEntryPlaceholderColorFocus, hovered = StyleDictionaryColor.colorSpecificDataEntryPlaceholderColorHover, pressed = StyleDictionaryColor.colorSpecificDataEntryPlaceholderColorValued, - alert = StyleDictionaryColor.colorSpecificDataEntryBorderColorError, + valued = StyleDictionaryColor.colorSpecificDataEntryPlaceholderColorValued, + alert = StyleDictionaryColor.colorGlobalSemanticAlert100, warning = StyleDictionaryColor.colorSpecificDataEntryBorderColorWarning, success = StyleDictionaryColor.colorSpecificDataEntryBorderColorSuccess, info = StyleDictionaryColor.colorSpecificDataEntryPlaceholderColorDefault, ), ), + titleBar = SirioTitleBarColors( + container = StyleDictionaryColor.colorAliasInteractivePrimaryDefault, + content = StyleDictionaryColor.colorAliasInteractivePrimary000Default, + ), toggle = SirioToggleColors( background = SirioColorState.all( StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight0, @@ -1181,32 +1674,3 @@ data class ButtonColors( ) } } - -@Keep -@Immutable -data class NotificationColors( - val background: Color, - val title: Color, - val text: Color, - val icon: Color, - val close: Color, - val alert: Color, - val info: Color, - val warning: Color, - val success: Color, -) { - companion object { - @Stable - val Unspecified = NotificationColors( - background = Color.Unspecified, - title = Color.Unspecified, - text = Color.Unspecified, - icon = Color.Unspecified, - close = Color.Unspecified, - alert = Color.Unspecified, - info = Color.Unspecified, - warning = Color.Unspecified, - success = Color.Unspecified, - ) - } -} diff --git a/design/src/main/java/it/inps/sirio/theme/Size.kt b/design/src/main/java/it/inps/sirio/theme/Size.kt index d6d9ca0..4aa9437 100644 --- a/design/src/main/java/it/inps/sirio/theme/Size.kt +++ b/design/src/main/java/it/inps/sirio/theme/Size.kt @@ -8,7 +8,6 @@ package it.inps.sirio.theme -import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp internal const val tabBarHeight = 56 @@ -74,21 +73,21 @@ internal const val checkboxCornerRadius = 4 internal const val checkboxFocusExtraBorderWidth = 1 internal const val checkboxFocusBorderPadding = 1 -internal val radioSafeAreaPadding = 10.dp -internal val radioSize = 24.dp -internal val radioDotSize = 14.dp -internal val radioBorderWidth = 1.dp -internal val radioFocusExtraBorderWidth = 1.dp -internal val radioFocusBorderPadding = 1.dp +internal const val radioSize = 24 +internal const val radioPaddingText = 10 +internal const val radioDotSize = 14 +internal const val radioBorderWidth = 1 +internal const val radioFocusExtraBorderWidth = 1 +internal const val radioFocusBorderPadding = 1 -internal val toggleHeight = 26.dp -internal val toggleWidth: Dp = 54.dp -internal val toggleIndicatorSize = 18.dp +internal const val toggleHeight = 26 +internal const val toggleWidth = 54 +internal const val togglePaddingText = 8 +internal const val toggleIndicatorSize = 18 internal const val toggleIndicatorHorizontalOffset = 14 -internal val toggleBorderWidth = 1.dp -internal val toggleFocusExtraBorderWidth = 1.dp -internal val toggleFocusExtraBorderPadding = 1.dp -internal val toggleSafeAreaPadding = 10.dp +internal const val toggleBorderWidth = 1 +internal const val toggleFocusExtraBorderWidth = 1 +internal const val toggleFocusExtraBorderPadding = 1 internal val sliderTitlePaddingBottom = 8.dp internal val sliderTextPaddingBottom = 22.dp @@ -122,22 +121,22 @@ internal const val fileUploadTitlePaddingBottom = 8 internal const val fileUploadTextPaddingBottom = 8 internal const val fileUploadItemsPadding = 8 -internal val notificationInlineIconSize = 24.dp -internal val notificationInlineHeight = 68.dp -internal val notificationInlineStateWidth = 68.dp -internal val notificationInlineHorizontalPadding = 16.dp -internal val notificationInlineVerticalPadding = 8.dp -internal val notificationInlineVerticalSpacer = 4.dp -internal val notificationInlineCloseSize = 18.dp - -internal val notificationToastIconSize = 24.dp -internal val notificationToastStateWidth = 24.dp -internal val notificationToastHorizontalPadding = 24.dp -internal val notificationToastVerticalPadding = 26.dp -internal val notificationToastTitleBottomSpacer = 8.dp -internal val notificationToastTextBottomSpacer = 24.dp -internal val notificationToastCloseSize = 23.dp -internal val notificationToastPadding = 0.dp +internal const val notificationInlineIconSize = 24 +internal const val notificationInlineIconPaddingTop = 20 +internal const val notificationInlineStateWidth = 62 +internal const val notificationInlinePaddingHorizontal = 20 +internal const val notificationInlinePaddingVertical = 20 +internal const val notificationInlineSpacerVertical = 16 +internal const val notificationInlineCloseSize = 16 + +internal const val notificationToastIconSize = 24 +internal const val notificationToastStateWidth = 62 +internal const val notificationToastHorizontalPadding = 24 +internal const val notificationToastVerticalPadding = 26 +internal const val notificationToastTitleBottomSpacer = 8 +internal const val notificationToastTextBottomSpacer = 24 +internal const val notificationToastCloseSize = 23 +internal const val notificationToastPadding = 0 internal val textFieldInfoIconSize = 14.dp internal val textFieldIconSize = 16.dp @@ -217,4 +216,89 @@ internal const val carouselPaddingTop = 40 internal const val carouselPaddingBottom = 24 internal const val carouselContentPaddingHorizontal = 36 internal const val carouselPaddingIntra = 16 -internal const val carouselPageSpacing = 16 \ No newline at end of file +internal const val carouselPageSpacing = 16 + +internal const val titleBarHeight = 48 +internal const val titleBarPaddingHorizontal = 16 +internal const val titleBarItemSpacing = 16 +internal const val titleBarItemPadding = 8 +internal const val titleBarIconSize = 16 + +internal const val tableComponentBorderWidth = 1 +internal const val tableComponentHeightLarge = 72 +internal const val tableComponentHeightMedium = 56 +internal const val tableComponentHeightSmall = 40 +internal const val tableComponentHeightExtraSmall = 36 +internal const val tableComponentPaddingHorizontalLarge = 16 +internal const val tableComponentPaddingHorizontalMedium = 12 +internal const val tableComponentPaddingHorizontalSmall = 8 +internal const val tableComponentPaddingHorizontalExtraSmall = 8 +internal const val tableComponentScrollIndicatorWidth = 4 +internal const val tableHeaderIconSize = 16 +internal const val tableHeaderSpacingCheckBoxTitle = 10 +internal const val tableHeaderSpacingTitleIcon = 16 +internal const val tableCellAvatarImageTextSpacing = 8 +internal const val tableDrawerPaddingHorizontal = 16 +internal const val tableDrawerPaddingTop = 32 +internal const val tableDrawerPaddingTitle = 24 +internal const val tableDrawerItemPaddingVertical = 24 +internal const val tableDrawerItemPaddingInternal = 16 +internal const val tableDrawerItemBorderWidth = 1 +internal const val tableDrawerIconsPaddingVertical = 8 +internal const val tableDrawerIconsPaddingHorizontal = 16 +internal const val tableVerticalItemPadding = 8 +internal const val tableVerticalItemBorderWidth = 1 +internal const val tableVerticalItemTagPadding = 4 +internal const val tableVerticalPaddingHorizontal = 16 +internal const val tableVerticalPaddingCells = 18 + +internal const val avvisoPaddingHorizontal = 16 +internal const val avvisoPaddingTop = 16 +internal const val avvisoPaddingBottom = 24 +internal const val avvisoIconPaddingTop = 12 +internal const val avvisoIconPaddingEnd = 16 +internal const val avvisoSpacerTitleText = 8 +internal const val avvisoSpacerTextButton = 24 + +internal const val menuSpallaDrawerItemBorderWidth = 1 +internal const val menuSpallaDrawerItemHeight = 72 +internal const val menuSpallaDrawerItemIconSize = 24 +internal const val menuSpallaDrawerItemPaddingHorizontal = 24 +internal const val menuSpallaDrawerItemInfoBorderWidth = 1 +internal const val menuSpallaDrawerItemInfoHeight = 87 +internal const val menuSpallaDrawerItemInfoIconSize = 24 +internal const val menuSpallaDrawerItemInfoPaddingHorizontal = 24 +internal const val menuSpallaItemTitleSectionBorderWidth = 4 +internal const val menuSpallaItemTitleSectionHeight = 49 +internal const val menuSpallaItemTitleSectionPaddingHorizontal = 16 +internal const val menuSpallaItemTitleSectionPaddingTop = 4 +internal const val menuSpallaItemHeight = 49 +internal const val menuSpallaItemIndicatorWidth = 4 +internal const val menuSpallaItemDividerHeight = 1 +internal const val menuSpallaItemBorderWidth = 1 +internal const val menuSpallaItemPaddingEnd = 16 +internal const val menuSpallaItemPrimaryPaddingStart = 16 +internal const val menuSpallaItemSecondaryPaddingStart = 24 +internal const val menuSpallaItemTertiaryPaddingStart = 32 +internal const val menuSpallaSectionPaddingTop = 16 + +internal const val filterPadding = 16 +internal const val filterChipsPadding = 16 +internal const val filterFooterPaddingHorizontal = 10 +internal const val filterFooterPaddingVertical = 24 +internal const val filterFooterButtonSpacing = 16 +internal const val filterHeaderPaddingHorizontal = 16 +internal const val filterHeaderPaddingVertical = 24 +internal const val filterHeaderCloseSize = 24 +internal const val filterSelectedPaddingVertical = 24 +internal const val filterInfoPadding = 8 +internal const val filterInfoSize = 16 + +internal const val dropdownBorderWidth = 1 +internal const val dropdownCornerSize = 4 + +internal const val stepSelectionHeight = 56 +internal const val stepSelectionPaddingHorizontal = 16 +internal const val stepControlsHeight = 56 +internal const val stepControlsIconSize = 16 +internal const val stepControlsHorizontalPadding = 20 diff --git a/design/src/main/java/it/inps/sirio/theme/Theme.kt b/design/src/main/java/it/inps/sirio/theme/Theme.kt index c49e54b..1b7bec1 100644 --- a/design/src/main/java/it/inps/sirio/theme/Theme.kt +++ b/design/src/main/java/it/inps/sirio/theme/Theme.kt @@ -22,6 +22,8 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.text.TextStyle import androidx.compose.ui.unit.Dp import it.inps.sirio.ui.accordion.SirioAccordionColors +import it.inps.sirio.ui.avviso.SirioAvvisoColors +import it.inps.sirio.ui.avviso.SirioAvvisoTypography import it.inps.sirio.ui.badge.SirioBadgeColors import it.inps.sirio.ui.card.SirioCardsColors import it.inps.sirio.ui.card.SirioCardsTypography @@ -29,16 +31,30 @@ import it.inps.sirio.ui.carousel.SirioCarouselColors import it.inps.sirio.ui.checkbox.SirioCheckboxColors import it.inps.sirio.ui.checkbox.SirioCheckboxTypography import it.inps.sirio.ui.dialog.SirioDialogColors +import it.inps.sirio.ui.dropdown.SirioDropdownColors +import it.inps.sirio.ui.dropdown.SirioDropdownTypography +import it.inps.sirio.ui.filter.SirioFilterColors +import it.inps.sirio.ui.filter.SirioFilterTypography import it.inps.sirio.ui.hero.SirioHeroColors import it.inps.sirio.ui.hero.SirioHeroTypography +import it.inps.sirio.ui.menuspalla.SirioMenuSpallaColors +import it.inps.sirio.ui.menuspalla.SirioMenuSpallaTypography +import it.inps.sirio.ui.notification.NotificationColors +import it.inps.sirio.ui.notification.SirioNotificationTypography import it.inps.sirio.ui.pagination.SirioPaginationColors import it.inps.sirio.ui.radiobutton.SirioRadioButtonColors import it.inps.sirio.ui.radiobutton.SirioRadioButtonTypography import it.inps.sirio.ui.searchbar.SirioSearchBarColors +import it.inps.sirio.ui.stepprogressbar.SirioStepProgressBarColors +import it.inps.sirio.ui.stepprogressbar.SirioStepProgressBarTypography +import it.inps.sirio.ui.table.SirioTableColors +import it.inps.sirio.ui.table.SirioTableTypography import it.inps.sirio.ui.tabs.SirioTabsColors import it.inps.sirio.ui.tag.SirioTagsColors import it.inps.sirio.ui.textarea.SirioTextAreaColors import it.inps.sirio.ui.textfield.SirioTextFieldColors +import it.inps.sirio.ui.titlebar.SirioTitleBarColors +import it.inps.sirio.ui.titlebar.SirioTitleBarTypography import it.inps.sirio.ui.toggle.SirioToggleColors import it.inps.sirio.ui.toggle.SirioToggleTypography @@ -88,20 +104,21 @@ data class SirioTypography( val appNavigationTitle: TextStyle, val appNavigationTitleBig: TextStyle, val appNavigationUsername: TextStyle, + val avviso: SirioAvvisoTypography, val buttonText: TextStyle, val card: SirioCardsTypography, val checkbox: SirioCheckboxTypography, val chipText: TextStyle, val dialogText: TextStyle, val dialogTitle: TextStyle, + val dropdown: SirioDropdownTypography, val fabText: TextStyle, val fileUploadText: TextStyle, val fileUploadTitle: TextStyle, + val filter: SirioFilterTypography, val hero: SirioHeroTypography, - val notificationInlineText: TextStyle, - val notificationInlineTitle: TextStyle, - val notificationToastText: TextStyle, - val notificationToastTitle: TextStyle, + val menuSpalla: SirioMenuSpallaTypography, + val notification: SirioNotificationTypography, val paginationTileNumber: TextStyle, val progressBarLabel: TextStyle, val progressBarNumber: TextStyle, @@ -109,7 +126,9 @@ data class SirioTypography( val sliderNumber: TextStyle, val sliderText: TextStyle, val sliderTitle: TextStyle, + val stepProgressBar: SirioStepProgressBarTypography, val tabBarItemText: TextStyle, + val table: SirioTableTypography, val tabTextDefault: TextStyle, val tabTextSelected: TextStyle, val tagText: TextStyle, @@ -122,6 +141,7 @@ data class SirioTypography( val textFieldLabel: TextStyle, val textFieldPlaceholder: TextStyle, val textFieldText: TextStyle, + val titleBar: SirioTitleBarTypography, val toggle: SirioToggleTypography, ) @@ -142,6 +162,7 @@ data class SirioColors( val appNavigationText: Color, val appNavigationUsernameBackground: Color, val appNavigationUsernameText: Color, + val avviso: SirioAvvisoColors, val badge: SirioBadgeColors, val buttons: ButtonColors, val card: SirioCardsColors, @@ -168,6 +189,7 @@ data class SirioColors( val chipWithCloseHoverBackground: Color, val chipWithClosePressedBackground: Color, val dialog: SirioDialogColors, + val dropdown: SirioDropdownColors, val fabBorderFocus: Color, val fabContent: Color, val fabDefaultBackground: Color, @@ -176,7 +198,9 @@ data class SirioColors( val fabPressedBackground: Color, val fileUploadText: Color, val fileUploadTitle: Color, + val filter: SirioFilterColors, val hero: SirioHeroColors, + val menuSpalla: SirioMenuSpallaColors, val notificationColors: NotificationColors, val pagination: SirioPaginationColors, val progressBarBackground: Color, @@ -208,13 +232,16 @@ data class SirioColors( val sliderText: Color, val sliderThumb: Color, val sliderTitle: Color, + val stepProgressBar: SirioStepProgressBarColors, val tabBarActive: Color, val tabBarBackground: Color, val tabBarContent: Color, + val table: SirioTableColors, val tabs: SirioTabsColors, val tag: SirioTagsColors, val textArea: SirioTextAreaColors, val textField: SirioTextFieldColors, + val titleBar: SirioTitleBarColors, val toggle: SirioToggleColors, val isDark: Boolean, ) @@ -232,35 +259,45 @@ data class SirioColorState( val focused: Color, val hovered: Color, val pressed: Color, + val valued: Color, val alert: Color, val warning: Color, val success: Color, val info: Color, ) { constructor( - default: Color, - disabled: Color, - focused: Color, - hovered: Color, - pressed: Color, + default: Color = Color.Unspecified, + disabled: Color = Color.Unspecified, + focused: Color = Color.Unspecified, + hovered: Color = Color.Unspecified, + pressed: Color = Color.Unspecified, + valued: Color = Color.Unspecified, ) : this( default = default, disabled = disabled, focused = focused, hovered = hovered, pressed = pressed, + valued = valued, alert = Color.Unspecified, warning = Color.Unspecified, success = Color.Unspecified, info = Color.Unspecified, ) - fun get(disabled: Boolean, focused: Boolean, pressed: Boolean, hovered: Boolean): Color = + fun get( + disabled: Boolean, + focused: Boolean, + pressed: Boolean, + hovered: Boolean, + valued: Boolean = false, + ): Color = when { disabled -> this.disabled focused -> this.focused pressed -> this.pressed hovered -> this.hovered + valued -> this.valued else -> this.default } @@ -282,6 +319,7 @@ data class SirioColorState( focused = color, hovered = color, pressed = color, + valued = color, alert = color, warning = color, success = color, @@ -304,6 +342,7 @@ private val localSirioColors = staticCompositionLocalOf { appNavigationText = Color.Unspecified, appNavigationUsernameBackground = Color.Unspecified, appNavigationUsernameText = Color.Unspecified, + avviso = SirioAvvisoColors.Unspecified, badge = SirioBadgeColors.Unspecified, buttons = ButtonColors.Unspecified, card = SirioCardsColors.Unspecified, @@ -330,6 +369,7 @@ private val localSirioColors = staticCompositionLocalOf { chipWithCloseHoverBackground = Color.Unspecified, chipWithClosePressedBackground = Color.Unspecified, dialog = SirioDialogColors.Unspecified, + dropdown = SirioDropdownColors.Unspecified, fabBorderFocus = Color.Unspecified, fabContent = Color.Unspecified, fabDefaultBackground = Color.Unspecified, @@ -338,7 +378,9 @@ private val localSirioColors = staticCompositionLocalOf { fabPressedBackground = Color.Unspecified, fileUploadText = Color.Unspecified, fileUploadTitle = Color.Unspecified, + filter = SirioFilterColors.Unspecified, hero = SirioHeroColors.Unspecified, + menuSpalla = SirioMenuSpallaColors.Unspecified, notificationColors = NotificationColors.Unspecified, pagination = SirioPaginationColors.Unspecified, progressBarBackground = Color.Unspecified, @@ -370,13 +412,16 @@ private val localSirioColors = staticCompositionLocalOf { sliderText = Color.Unspecified, sliderThumb = Color.Unspecified, sliderTitle = Color.Unspecified, + stepProgressBar = SirioStepProgressBarColors.Unspecified, tabBarActive = Color.Unspecified, tabBarBackground = Color.Unspecified, tabBarContent = Color.Unspecified, + table = SirioTableColors.Unspecified, tabs = SirioTabsColors.Unspecified, tag = SirioTagsColors.Unspecified, textArea = SirioTextAreaColors.Unspecified, textField = SirioTextFieldColors.Unspecified, + titleBar = SirioTitleBarColors.Unspecified, toggle = SirioToggleColors.Unspecified, isDark = false, ) @@ -390,20 +435,21 @@ internal val LocalSirioTypography = staticCompositionLocalOf { appNavigationTitle = TextStyle.Default, appNavigationTitleBig = TextStyle.Default, appNavigationUsername = TextStyle.Default, + avviso = SirioAvvisoTypography.Default, buttonText = TextStyle.Default, card = SirioCardsTypography.Default, checkbox = SirioCheckboxTypography.Default, chipText = TextStyle.Default, dialogText = TextStyle.Default, dialogTitle = TextStyle.Default, + dropdown = SirioDropdownTypography.Default, fabText = TextStyle.Default, fileUploadText = TextStyle.Default, fileUploadTitle = TextStyle.Default, + filter = SirioFilterTypography.Default, hero = SirioHeroTypography.Default, - notificationInlineText = TextStyle.Default, - notificationInlineTitle = TextStyle.Default, - notificationToastText = TextStyle.Default, - notificationToastTitle = TextStyle.Default, + menuSpalla = SirioMenuSpallaTypography.Default, + notification = SirioNotificationTypography.Default, paginationTileNumber = TextStyle.Default, progressBarLabel = TextStyle.Default, progressBarNumber = TextStyle.Default, @@ -411,7 +457,9 @@ internal val LocalSirioTypography = staticCompositionLocalOf { sliderNumber = TextStyle.Default, sliderText = TextStyle.Default, sliderTitle = TextStyle.Default, + stepProgressBar = SirioStepProgressBarTypography.Default, tabBarItemText = TextStyle.Default, + table = SirioTableTypography.Default, tabTextDefault = TextStyle.Default, tabTextSelected = TextStyle.Default, tagText = TextStyle.Default, @@ -424,6 +472,7 @@ internal val LocalSirioTypography = staticCompositionLocalOf { textFieldLabel = TextStyle.Default, textFieldPlaceholder = TextStyle.Default, textFieldText = TextStyle.Default, + titleBar = SirioTitleBarTypography.Default, toggle = SirioToggleTypography.Default, ) } diff --git a/design/src/main/java/it/inps/sirio/theme/Type.kt b/design/src/main/java/it/inps/sirio/theme/Type.kt index 32763de..9d83561 100644 --- a/design/src/main/java/it/inps/sirio/theme/Type.kt +++ b/design/src/main/java/it/inps/sirio/theme/Type.kt @@ -21,11 +21,30 @@ import androidx.compose.ui.unit.sp import it.inps.sirio.styleDictionary.StyleDictionaryColor import it.inps.sirio.styleDictionary.StyleDictionarySize import it.inps.sirio.styleDictionary.StyleDictionaryTypography +import it.inps.sirio.ui.avviso.SirioAvvisoTypography import it.inps.sirio.ui.card.SirioCardTypography import it.inps.sirio.ui.card.SirioCardsTypography import it.inps.sirio.ui.checkbox.SirioCheckboxTypography +import it.inps.sirio.ui.dropdown.SirioDropdownOptionTypography +import it.inps.sirio.ui.dropdown.SirioDropdownTypography +import it.inps.sirio.ui.filter.SirioFilterTypography import it.inps.sirio.ui.hero.SirioHeroTypography +import it.inps.sirio.ui.menuspalla.SirioMenuSpallaDrawerItemInfoTypography +import it.inps.sirio.ui.menuspalla.SirioMenuSpallaDrawerItemTypography +import it.inps.sirio.ui.menuspalla.SirioMenuSpallaItemTitleSectionTypography +import it.inps.sirio.ui.menuspalla.SirioMenuSpallaItemTypography +import it.inps.sirio.ui.menuspalla.SirioMenuSpallaTypography +import it.inps.sirio.ui.notification.SirioNotificationTypography import it.inps.sirio.ui.radiobutton.SirioRadioButtonTypography +import it.inps.sirio.ui.stepprogressbar.SirioStepControlsTypography +import it.inps.sirio.ui.stepprogressbar.SirioStepProgressBarTypography +import it.inps.sirio.ui.stepprogressbar.SirioStepSelectionTypography +import it.inps.sirio.ui.table.SirioTableHeaderTypography +import it.inps.sirio.ui.table.SirioTableTypography +import it.inps.sirio.ui.table.cell.SirioTableCellTypography +import it.inps.sirio.ui.table.drawer.SirioTableDrawerTypography +import it.inps.sirio.ui.table.vertical.SirioTableVerticalTypography +import it.inps.sirio.ui.titlebar.SirioTitleBarTypography import it.inps.sirio.ui.toggle.SirioToggleTypography internal val Titillium_Web = TitilliumWebFamily @@ -48,6 +67,14 @@ val appNavigationTitleXl = TextStyle( fontStyle = StyleDictionaryTypography.typographySpecificAppNavigationTitleFontWeight600.getFontStyle(), ) +val labelXl600 = TextStyle( + fontFamily = StyleDictionaryTypography.typographyGlobalFontFamily01, + fontSize = StyleDictionarySize.typographyAliasLabelXlSize06.sp, + lineHeight = StyleDictionarySize.typographyAliasLabelLineHeight06.sp, + fontWeight = StyleDictionaryTypography.typographyAliasLabelFontWeight700.getFontWeight(), + fontStyle = StyleDictionaryTypography.typographyAliasLabelFontWeight700.getFontStyle(), +) + val labelXl400 = TextStyle( fontFamily = StyleDictionaryTypography.typographyGlobalFontFamily01, fontSize = StyleDictionarySize.typographyAliasLabelXlSize06.sp, @@ -56,6 +83,19 @@ val labelXl400 = TextStyle( fontStyle = StyleDictionaryTypography.typographyAliasLabelFontWeight400.getFontStyle(), ) +val labelLg700 = TextStyle( + fontSize = StyleDictionarySize.typographyAliasLabelLgSize05.sp, + fontWeight = StyleDictionaryTypography.typographyAliasLabelFontWeight700.getFontWeight(), + fontStyle = StyleDictionaryTypography.typographyAliasLabelFontWeight700.getFontStyle(), + fontFamily = StyleDictionaryTypography.typographyGlobalFontFamily01, + lineHeight = StyleDictionarySize.typographyAliasPLgLineHeight05.sp, +// platformStyle = PlatformTextStyle(includeFontPadding = false), +// lineHeightStyle = LineHeightStyle( +// alignment = LineHeightStyle.Alignment.Center, +// trim = LineHeightStyle.Trim.Both +// ), +) + val labelMd700 = TextStyle( fontSize = StyleDictionarySize.typographyAliasLabelMdSize04.sp, fontWeight = StyleDictionaryTypography.typographyAliasLabelFontWeight700.getFontWeight(), @@ -116,6 +156,14 @@ val labelProgressBarNumber = TextStyle( fontStyle = StyleDictionaryTypography.typographyAliasLabelFontWeight400.getFontStyle(), ) +val pLg01 = TextStyle( + fontFamily = StyleDictionaryTypography.typographyGlobalFontFamily01, + fontSize = StyleDictionarySize.typographyAliasLabelLgSize05.sp, + lineHeight = StyleDictionarySize.typographyAliasPLgLineHeight05.sp, + fontWeight = StyleDictionaryTypography.typographyAliasPFontWeight400.getFontWeight(), + fontStyle = StyleDictionaryTypography.typographyAliasPFontWeight400.getFontStyle(), +) + val pMd01 = TextStyle( fontFamily = StyleDictionaryTypography.typographyGlobalFontFamily01, fontSize = StyleDictionarySize.typographyGlobalFontSize04.sp, @@ -124,6 +172,16 @@ val pMd01 = TextStyle( fontStyle = StyleDictionaryTypography.typographyAliasLabelFontWeight400.getFontStyle(), ) + +val linkPLg01 = TextStyle( + fontFamily = StyleDictionaryTypography.typographyGlobalFontFamily01, + fontSize = StyleDictionarySize.typographyAliasLabelLgSize05.sp, + lineHeight = StyleDictionarySize.typographyAliasPLgLineHeight05.sp, + fontWeight = StyleDictionaryTypography.typographyAliasLinkFontWeight700.getFontWeight(), + fontStyle = StyleDictionaryTypography.typographyAliasLinkFontWeight700.getFontStyle(), + textDecoration = TextDecoration.Underline, +) + val linkPMd01 = TextStyle( fontFamily = StyleDictionaryTypography.typographyGlobalFontFamily01, fontSize = StyleDictionarySize.typographyGlobalFontSize04.sp, @@ -144,18 +202,10 @@ val linkH4Md01 = TextStyle( textDecoration = TextDecoration.Underline ) -val mPMd01_700 = TextStyle( - fontFamily = StyleDictionaryTypography.typographyGlobalFontFamily01, - fontSize = StyleDictionarySize.typographyGlobalFontSize04.sp, - lineHeight = StyleDictionarySize.typographyAliasLinkPMdLineHeight04.sp, - fontWeight = StyleDictionaryTypography.typographyAliasLabelFontWeight700.getFontWeight(), - fontStyle = StyleDictionaryTypography.typographyAliasLabelFontWeight700.getFontStyle(), -) - val labelMd400 = TextStyle( fontFamily = StyleDictionaryTypography.typographyGlobalFontFamily01, fontSize = StyleDictionarySize.typographyAliasLabelMdSize04.sp, - lineHeight = StyleDictionarySize.typographyAliasLabelLineHeight04.sp, + lineHeight = StyleDictionarySize.typographyAliasPMdLineHeight04.sp, fontWeight = StyleDictionaryTypography.typographyAliasLabelFontWeight400.getFontWeight(), fontStyle = StyleDictionaryTypography.typographyAliasLabelFontWeight400.getFontStyle(), ) @@ -181,6 +231,14 @@ val h2Md = TextStyle( fontStyle = StyleDictionaryTypography.typographyAliasH2FontWeight700.getFontStyle(), ) +val h4Lg = TextStyle( + fontFamily = StyleDictionaryTypography.typographyGlobalFontFamily01, + fontSize = StyleDictionarySize.typographyAliasH4LgSize08.sp, + lineHeight = StyleDictionarySize.typographyAliasH4LgLineHeight08.sp, + fontWeight = StyleDictionaryTypography.typographyAliasH4FontWeight700.getFontWeight(), + fontStyle = StyleDictionaryTypography.typographyAliasH4FontWeight700.getFontStyle(), +) + val h4Md = TextStyle( fontFamily = StyleDictionaryTypography.typographyGlobalFontFamily01, fontSize = StyleDictionarySize.typographyAliasH4MdSize07.sp, @@ -220,6 +278,10 @@ internal val Typography = SirioTypography( appNavigationTitle = appNavigationTitleMd, appNavigationTitleBig = appNavigationTitleXl, appNavigationUsername = labelMd700, + avviso = SirioAvvisoTypography( + title = h4Lg, + text = pLg01, + ), buttonText = labelMd700, card = SirioCardsTypography( editorial = SirioCardTypography( @@ -241,18 +303,37 @@ internal val Typography = SirioTypography( chipText = labelMd700, dialogText = pMd01, dialogTitle = h4Md, + dropdown = SirioDropdownTypography( + option = SirioDropdownOptionTypography( + text = placeholderMd400, + ) + ), fabText = labelMd700, fileUploadText = helperTextXs400, fileUploadTitle = labelMd600, + filter = SirioFilterTypography(header = h4Lg, title = labelLg700), hero = SirioHeroTypography( title = h2Md, subtitle = h4Md, text = pMd01, ), - notificationInlineText = pMd01, - notificationInlineTitle = mPMd01_700, - notificationToastText = pMd01, - notificationToastTitle = labelMd700, + menuSpalla = SirioMenuSpallaTypography( + drawerItem = SirioMenuSpallaDrawerItemTypography( + title = labelLg700, + subtitle = labelMd400, + ), + drawerItemInfo = SirioMenuSpallaDrawerItemInfoTypography( + title = labelLg700, + subtitle = labelMd400, + ), + itemTitleSection = SirioMenuSpallaItemTitleSectionTypography(title = labelXl600), + item = SirioMenuSpallaItemTypography(title = labelMd600), + ), + notification = SirioNotificationTypography( + title = labelMd700, + text = pMd01, + link = linkPMd01, + ), paginationTileNumber = labelMdNumber400, progressBarLabel = labelMd600, progressBarNumber = labelProgressBarNumber, @@ -260,7 +341,41 @@ internal val Typography = SirioTypography( sliderNumber = labelMdNumber400, sliderText = helperTextXs400, sliderTitle = labelMd600, + stepProgressBar = SirioStepProgressBarTypography( + controls = SirioStepControlsTypography( + previous = labelLg700, + next = labelLg700, + ), + selection = SirioStepSelectionTypography( + progress = labelMd400, + currentStep = labelLg700, + ) + ), tabBarItemText = tabBarLabelXs, + table = SirioTableTypography( + cell = SirioTableCellTypography( + text = labelMd400, + number = labelMdNumber400, + link = linkPMd01, + avatarTitle = placeholderMd400, + avatarSubtitle = helperTextXs400 + ), + drawer = SirioTableDrawerTypography( + actionsText = labelMd700, + title = h5Md, + itemTitle = labelMd600, + itemText = pMd01, + itemNumber = labelMdNumber400, + itemLink = linkPMd01, + ), + header = SirioTableHeaderTypography(title = labelMd600), + vertical = SirioTableVerticalTypography( + itemTitle = labelMd700, + itemText = pMd01, + itemNumber = labelMdNumber400, + itemLink = linkPMd01, + ) + ), tabTextDefault = labelMd400, tabTextSelected = labelMd700, tagText = labelMd700, @@ -273,6 +388,7 @@ internal val Typography = SirioTypography( textFieldLabel = labelMd600, textFieldPlaceholder = placeholderMd400, textFieldText = placeholderMd400, + titleBar = SirioTitleBarTypography(title = h5Md, iconText = labelMd600), toggle = SirioToggleTypography(text = labelMd400), ) diff --git a/design/src/main/java/it/inps/sirio/ui/avviso/SirioAvviso.kt b/design/src/main/java/it/inps/sirio/ui/avviso/SirioAvviso.kt new file mode 100644 index 0000000..f85dd50 --- /dev/null +++ b/design/src/main/java/it/inps/sirio/ui/avviso/SirioAvviso.kt @@ -0,0 +1,18 @@ +package it.inps.sirio.ui.avviso + +import androidx.compose.runtime.Composable + +@Composable +fun SirioAvviso( + title: String, + text: String, + buttonText: String, + onButtonClick: () -> Unit, +) { + SirioAvvisoCommon( + title = title, + text = text, + buttonText = buttonText, + onButtonClick = onButtonClick, + ) +} \ No newline at end of file diff --git a/design/src/main/java/it/inps/sirio/ui/avviso/SirioAvvisoCommon.kt b/design/src/main/java/it/inps/sirio/ui/avviso/SirioAvvisoCommon.kt new file mode 100644 index 0000000..ee56d5e --- /dev/null +++ b/design/src/main/java/it/inps/sirio/ui/avviso/SirioAvvisoCommon.kt @@ -0,0 +1,161 @@ +// +// SirioAvvisoCommon.kt +// +// SPDX-FileCopyrightText: 2024 Istituto Nazionale Previdenza Sociale +// +// SPDX-License-Identifier: BSD-3-Clause +// + +package it.inps.sirio.ui.avviso + +import androidx.annotation.Keep +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.runtime.Composable +import androidx.compose.runtime.Stable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.guru.fontawesomecomposelib.FaIcons +import it.inps.sirio.theme.SirioTheme +import it.inps.sirio.theme.avvisoIconPaddingEnd +import it.inps.sirio.theme.avvisoIconPaddingTop +import it.inps.sirio.theme.avvisoPaddingBottom +import it.inps.sirio.theme.avvisoPaddingHorizontal +import it.inps.sirio.theme.avvisoPaddingTop +import it.inps.sirio.theme.avvisoSpacerTextButton +import it.inps.sirio.theme.avvisoSpacerTitleText +import it.inps.sirio.ui.button.ButtonSize +import it.inps.sirio.ui.button.SirioButtonCommon +import it.inps.sirio.ui.text.SirioTextCommon +import it.inps.sirio.utils.SirioFaIcon + +@Composable +internal fun SirioAvvisoCommon( + title: String, + text: String, + buttonText: String, + onButtonClick: () -> Unit, +) { + Box( + modifier = Modifier.background(SirioTheme.colors.avviso.background), + contentAlignment = Alignment.BottomCenter, + ) { + Row( + Modifier + .fillMaxWidth() + .padding( + avvisoPaddingHorizontal.dp, + avvisoPaddingTop.dp, + avvisoPaddingHorizontal.dp, + avvisoPaddingBottom.dp + ) + ) { + SirioFaIcon( + faIcon = FaIcons.InfoCircle, + modifier = Modifier.padding( + top = avvisoIconPaddingTop.dp, + end = avvisoIconPaddingEnd.dp + ), + tint = SirioTheme.colors.avviso.icon, + ) + Column { + SirioTextCommon( + text = title, + color = SirioTheme.colors.avviso.title, + typography = SirioTheme.typography.avviso.title, + ) + Spacer(modifier = Modifier.height(avvisoSpacerTitleText.dp)) + SirioTextCommon( + text = text, + color = SirioTheme.colors.avviso.text, + typography = SirioTheme.typography.avviso.text, + ) + Spacer(modifier = Modifier.height(avvisoSpacerTextButton.dp)) + SirioButtonCommon( + size = ButtonSize.Large, + colors = SirioTheme.colors.buttons.tertiary, + text = buttonText, + onClick = onButtonClick, + ) + } + } + Box( + modifier = Modifier + .fillMaxWidth() + .height(1.dp) + .background(SirioTheme.colors.avviso.borderBottom) + ) + } +} + +@Keep +data class SirioAvvisoColors( + val background: Color, + val borderBottom: Color, + val title: Color, + val text: Color, + val icon: Color, +) { + companion object { + @Stable + val Unspecified = SirioAvvisoColors( + background = Color.Unspecified, + borderBottom = Color.Unspecified, + title = Color.Unspecified, + text = Color.Unspecified, + icon = Color.Unspecified, + ) + } +} + +@Keep +data class SirioAvvisoTypography( + val title: TextStyle, + val text: TextStyle, +) { + companion object { + @Stable + val Default = SirioAvvisoTypography( + title = TextStyle.Default, + text = TextStyle.Default, + ) + } +} + +@Preview +@Composable +private fun SirioAvvisoCommonPreview() { + Column { + val title = "Titolo avviso" + val text = + "Ac iaculis posuere turpis diam mi non viverra tempus eget. Nunc volutpat nunc erat risus eleifend convallis viverra bibendum. Mattis ante mauris sit montes. Scelerisque dui arcu tempus proin massa massa ultricies nunc duis." + val buttonText = "Text" + val onButtonClick = {} + SirioTheme { + SirioAvvisoCommon( + title = title, + text = text, + buttonText = buttonText, + onButtonClick = onButtonClick, + ) + } + SirioTheme(darkTheme = true) { + SirioAvvisoCommon( + title = title, + text = text, + buttonText = buttonText, + onButtonClick = onButtonClick, + ) + } + } +} \ No newline at end of file diff --git a/design/src/main/java/it/inps/sirio/ui/button/SirioButtonCommon.kt b/design/src/main/java/it/inps/sirio/ui/button/SirioButtonCommon.kt index 9efc58d..533484f 100644 --- a/design/src/main/java/it/inps/sirio/ui/button/SirioButtonCommon.kt +++ b/design/src/main/java/it/inps/sirio/ui/button/SirioButtonCommon.kt @@ -45,6 +45,7 @@ import androidx.compose.runtime.getValue import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp @@ -264,6 +265,7 @@ private fun ButtonContent( SirioTextCommon( text = text, color = textColor, + textAlign = TextAlign.Center, typography = SirioTheme.typography.buttonText, ) } diff --git a/design/src/main/java/it/inps/sirio/ui/card/SirioCardCommon.kt b/design/src/main/java/it/inps/sirio/ui/card/SirioCardCommon.kt index df81aa0..e52e50e 100644 --- a/design/src/main/java/it/inps/sirio/ui/card/SirioCardCommon.kt +++ b/design/src/main/java/it/inps/sirio/ui/card/SirioCardCommon.kt @@ -29,7 +29,9 @@ import androidx.compose.ui.draw.shadow import androidx.compose.ui.graphics.Color import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import coil.compose.AsyncImage @@ -100,16 +102,19 @@ internal fun SirioCardCommon( items: List = listOf(), onClickCard: () -> Unit = {}, ) { + val elevation = + with(LocalDensity.current) { StyleDictionaryBoxShadow.elevationElevation01.blurRadius.toDp() } + Card( onClick = onClickCard, modifier = Modifier .shadow( ambientColor = StyleDictionaryBoxShadow.elevationElevation01.color, - elevation = StyleDictionaryBoxShadow.elevationElevation01.blurRadius.dp + elevation = elevation ) .then(modifier), shape = Shapes.small, - colors = CardDefaults.cardColors(containerColor = colors.background) + colors = CardDefaults.cardColors(containerColor = colors.background), ) { imageUrl?.let { AsyncImage( @@ -166,6 +171,7 @@ internal fun SirioCardCommon( text = title, modifier = Modifier.padding(top = cardTextPaddingTop.dp), color = colors.title, + overflow = TextOverflow.Ellipsis, maxLines = 2, typography = typography.title, ) diff --git a/design/src/main/java/it/inps/sirio/ui/carousel/SirioCarouselCommon.kt b/design/src/main/java/it/inps/sirio/ui/carousel/SirioCarouselCommon.kt index d717e92..5e836e4 100644 --- a/design/src/main/java/it/inps/sirio/ui/carousel/SirioCarouselCommon.kt +++ b/design/src/main/java/it/inps/sirio/ui/carousel/SirioCarouselCommon.kt @@ -5,13 +5,11 @@ // // SPDX-License-Identifier: BSD-3-Clause // -@file:OptIn(ExperimentalFoundationApi::class) package it.inps.sirio.ui.carousel import androidx.annotation.Keep import androidx.compose.animation.animateContentSize -import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement @@ -94,7 +92,9 @@ internal fun SirioCarouselCommon( pageSpacing = carouselPageSpacing.dp, ) { content(items[it]) } Spacer(modifier = Modifier.height(carouselPaddingIntra.dp)) - SirioCarouselIndicator(pagerState) { coroutineScope.launch { pagerState.scrollToPage(it) } } + SirioCarouselIndicator(pagerState) { + coroutineScope.launch { pagerState.animateScrollToPage(it) } + } } } @@ -179,7 +179,7 @@ private fun SirioCarouselCommonPreview() { icon = FaIcons.Book, date = "13 Nov 2021", title = "Titolo della card 1", - text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt.", + text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor", button = "Text" ), CarouselSampleData( @@ -211,6 +211,7 @@ private fun SirioCarouselCommonPreview() { background = SirioCarouselBackground.MEDIUM, ) { sample -> SirioProcessCard( + modifier = Modifier.height(300.dp), title = sample.title, text = sample.text, buttonText = sample.button, @@ -222,4 +223,4 @@ private fun SirioCarouselCommonPreview() { ) } } -} \ No newline at end of file +} diff --git a/design/src/main/java/it/inps/sirio/ui/checkbox/SirioCheckboxCommon.kt b/design/src/main/java/it/inps/sirio/ui/checkbox/SirioCheckboxCommon.kt index e1cd739..bc7b0f3 100644 --- a/design/src/main/java/it/inps/sirio/ui/checkbox/SirioCheckboxCommon.kt +++ b/design/src/main/java/it/inps/sirio/ui/checkbox/SirioCheckboxCommon.kt @@ -21,6 +21,7 @@ import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width @@ -58,6 +59,7 @@ import it.inps.sirio.utils.SirioIcon * Sirio checkbox implementation * * @param text The string on the checkbox right + * @param modifier the Modifier to be applied to this checkbox * @param checked Whether the checkbox is checked * @param enabled Whether the checkbox is enabled * @param onCheckedChange The callback when the checkbox state change @@ -65,6 +67,7 @@ import it.inps.sirio.utils.SirioIcon @Composable internal fun SirioCheckboxCommon( checked: Boolean, + modifier: Modifier = Modifier, text: String? = null, enabled: Boolean = true, overflow: TextOverflow = TextOverflow.Clip, @@ -73,6 +76,7 @@ internal fun SirioCheckboxCommon( ) { SirioCheckboxWithText( checked = checked, + modifier = modifier, text = text, enabled = enabled, overflow = overflow, @@ -85,6 +89,7 @@ internal fun SirioCheckboxCommon( * Sirio checkbox implementation * * @param text The string on the checkbox right + * @param modifier the Modifier to be applied to this checkbox * @param checked Whether the checkbox is checked * @param enabled Whether the checkbox is enabled * @param onCheckedChange The callback when the checkbox state change @@ -93,6 +98,7 @@ internal fun SirioCheckboxCommon( internal fun SirioCheckboxCommon( checked: Boolean, text: AnnotatedString, + modifier: Modifier = Modifier, enabled: Boolean = true, overflow: TextOverflow = TextOverflow.Clip, maxLines: Int = Int.MAX_VALUE, @@ -100,6 +106,7 @@ internal fun SirioCheckboxCommon( ) { SirioCheckboxWithText( checked = checked, + modifier = modifier, annotatedText = text, enabled = enabled, overflow = overflow, @@ -111,6 +118,7 @@ internal fun SirioCheckboxCommon( @Composable private fun SirioCheckboxWithText( checked: Boolean, + modifier: Modifier = Modifier, text: String? = null, annotatedText: AnnotatedString? = null, enabled: Boolean = true, @@ -134,14 +142,14 @@ private fun SirioCheckboxWithText( Row( verticalAlignment = Alignment.CenterVertically, - modifier = Modifier + modifier = modifier .focusable(enabled = enabled, interactionSource = interactionSource) .toggleable( value = checked, interactionSource = interactionSource, indication = null, + enabled = enabled, role = Role.Checkbox, - enabled = enabled ) { onCheckedChange(it) } @@ -164,6 +172,7 @@ private fun SirioCheckboxWithText( typography = SirioTheme.typography.checkbox.text, ) } ?: annotatedText?.let { + Spacer(modifier = Modifier.width(checkboxPaddingText.dp)) SirioTextCommon( text = it, color = textColor, @@ -275,19 +284,15 @@ private fun CheckboxCommonPreview() { SirioCheckboxCommon(checked = true, enabled = true) {} SirioCheckboxCommon(checked = false, enabled = false) {} SirioCheckboxCommon(checked = true, enabled = false) {} - SirioCheckboxCommon(checked = false, text = text, enabled = true) {} + SirioCheckboxCommon( + checked = false, + modifier = Modifier.fillMaxWidth(), + text = text, + enabled = true + ) {} SirioCheckboxCommon(checked = true, text = text, enabled = true) {} SirioCheckboxCommon(checked = false, text = text, enabled = false) {} SirioCheckboxCommon(checked = true, text = text, enabled = false) {} } } } - -@Preview -@Composable -private fun SirioCustomCheckboxPreview() { - SirioTheme { - Column { - } - } -} diff --git a/design/src/main/java/it/inps/sirio/ui/chip/ChipCommon.kt b/design/src/main/java/it/inps/sirio/ui/chip/SirioChipCommon.kt similarity index 97% rename from design/src/main/java/it/inps/sirio/ui/chip/ChipCommon.kt rename to design/src/main/java/it/inps/sirio/ui/chip/SirioChipCommon.kt index 2207229..f1e057a 100644 --- a/design/src/main/java/it/inps/sirio/ui/chip/ChipCommon.kt +++ b/design/src/main/java/it/inps/sirio/ui/chip/SirioChipCommon.kt @@ -1,5 +1,5 @@ // -// ChipCommon.kt +// SirioChipCommon.kt // // SPDX-FileCopyrightText: 2024 Istituto Nazionale Previdenza Sociale // @@ -80,7 +80,7 @@ import it.inps.sirio.utils.SirioIcon * @param onStateChange The callback when the chip active state change */ @Composable -internal fun ChipCommon( +internal fun SirioChipCommon( text: String, icon: FaIconType?, withClose: Boolean, @@ -327,10 +327,10 @@ data class ChipParams( @Preview @Composable -private fun ChipCommonPreview() { +private fun SirioChipCommonPreview() { SirioTheme { Column { - ChipCommon( + SirioChipCommon( text = "Chips", icon = FaIcons.User, withClose = true, @@ -338,7 +338,7 @@ private fun ChipCommonPreview() { onClose = {}, enabled = true, onStateChange = {}) - ChipCommon( + SirioChipCommon( text = "Chips", icon = FaIcons.User, withClose = true, @@ -346,7 +346,7 @@ private fun ChipCommonPreview() { onClose = {}, enabled = false, onStateChange = {}) - ChipCommon( + SirioChipCommon( text = "Chips", icon = null, withClose = true, @@ -354,7 +354,7 @@ private fun ChipCommonPreview() { onClose = {}, enabled = true, onStateChange = {}) - ChipCommon( + SirioChipCommon( text = "Chips", icon = null, withClose = true, @@ -362,7 +362,7 @@ private fun ChipCommonPreview() { onClose = {}, enabled = false, onStateChange = {}) - ChipCommon( + SirioChipCommon( text = "Chips", icon = FaIcons.Check, withClose = false, @@ -370,7 +370,7 @@ private fun ChipCommonPreview() { onClose = {}, enabled = true, onStateChange = {}) - ChipCommon( + SirioChipCommon( text = "Chips", icon = FaIcons.Check, withClose = false, @@ -378,7 +378,7 @@ private fun ChipCommonPreview() { onClose = {}, enabled = false, onStateChange = {}) - ChipCommon( + SirioChipCommon( text = "Chips", icon = FaIcons.Check, withClose = false, @@ -386,7 +386,7 @@ private fun ChipCommonPreview() { onClose = {}, enabled = true, onStateChange = {}) - ChipCommon( + SirioChipCommon( text = "Chips", icon = null, withClose = false, @@ -394,7 +394,7 @@ private fun ChipCommonPreview() { onClose = {}, enabled = true, onStateChange = {}) - ChipCommon( + SirioChipCommon( text = "Chips", icon = null, withClose = false, @@ -403,7 +403,7 @@ private fun ChipCommonPreview() { enabled = false, onStateChange = {} ) - ChipCommon( + SirioChipCommon( text = "Chips", icon = null, withClose = false, @@ -413,4 +413,4 @@ private fun ChipCommonPreview() { onStateChange = {}) } } -} +} \ No newline at end of file diff --git a/design/src/main/java/it/inps/sirio/ui/chip/ChipLabel.kt b/design/src/main/java/it/inps/sirio/ui/chip/SirioChipLabel.kt similarity index 62% rename from design/src/main/java/it/inps/sirio/ui/chip/ChipLabel.kt rename to design/src/main/java/it/inps/sirio/ui/chip/SirioChipLabel.kt index 85dbc01..8723568 100644 --- a/design/src/main/java/it/inps/sirio/ui/chip/ChipLabel.kt +++ b/design/src/main/java/it/inps/sirio/ui/chip/SirioChipLabel.kt @@ -1,5 +1,5 @@ // -// ChipLabel.kt +// SirioChipLabel.kt // // SPDX-FileCopyrightText: 2024 Istituto Nazionale Previdenza Sociale // @@ -11,10 +11,11 @@ package it.inps.sirio.ui.chip import androidx.compose.foundation.layout.Column import androidx.compose.runtime.Composable import androidx.compose.ui.tooling.preview.Preview +import com.guru.fontawesomecomposelib.FaIcons import it.inps.sirio.theme.SirioTheme /** - * The Sirio chip with only label + * The Sirio chip with only label. If active, the chip has a check icon. * * @param label The string on the chip * @param enabled Whether the chip is enabled @@ -22,15 +23,16 @@ import it.inps.sirio.theme.SirioTheme * @param onStateChange The callback when the chip active state change */ @Composable -fun ChipLabel( +fun SirioChipLabel( label: String, enabled: Boolean, active: Boolean, onStateChange: (active: Boolean) -> Unit ) { - ChipCommon( + val icon = if (active) FaIcons.Check else null + SirioChipCommon( text = label, - icon = null, + icon = icon, withClose = false, isActive = active, enabled = enabled, @@ -40,21 +42,33 @@ fun ChipLabel( @Preview @Composable -private fun ChipLabelPreview() { +private fun SirioChipLabelPreview() { SirioTheme { Column { - ChipLabel( + SirioChipLabel( label = "Chips", enabled = true, active = true, onStateChange = {}, ) - ChipLabel( + SirioChipLabel( + label = "Chips", + enabled = true, + active = false, + onStateChange = {}, + ) + SirioChipLabel( label = "Chips", enabled = false, active = true, onStateChange = {}, ) + SirioChipLabel( + label = "Chips", + enabled = false, + active = false, + onStateChange = {}, + ) } } } \ No newline at end of file diff --git a/design/src/main/java/it/inps/sirio/ui/chip/ChipLabelClose.kt b/design/src/main/java/it/inps/sirio/ui/chip/SirioChipLabelClose.kt similarity index 87% rename from design/src/main/java/it/inps/sirio/ui/chip/ChipLabelClose.kt rename to design/src/main/java/it/inps/sirio/ui/chip/SirioChipLabelClose.kt index 5ca6455..3a0b905 100644 --- a/design/src/main/java/it/inps/sirio/ui/chip/ChipLabelClose.kt +++ b/design/src/main/java/it/inps/sirio/ui/chip/SirioChipLabelClose.kt @@ -1,5 +1,5 @@ // -// ChipLabelClose.kt +// SirioChipLabelClose.kt // // SPDX-FileCopyrightText: 2024 Istituto Nazionale Previdenza Sociale // @@ -22,12 +22,12 @@ import it.inps.sirio.theme.SirioTheme * @param onClose The callback when the chip close button is clicked */ @Composable -fun ChipLabelClose( +fun SirioChipLabelClose( label: String, enabled: Boolean, closeContentDescription: String? = null, onClose: () -> Unit, ) { - ChipCommon( + SirioChipCommon( text = label, icon = null, withClose = true, @@ -41,19 +41,19 @@ fun ChipLabelClose( @Preview @Composable -private fun ChipLabelClosePreview() { +private fun SirioChipLabelClosePreview() { SirioTheme { Column { - ChipLabelClose( + SirioChipLabelClose( label = "Chips", enabled = true, onClose = {}, ) - ChipLabelClose( + SirioChipLabelClose( label = "Chips", enabled = false, onClose = {}, ) } } -} +} \ No newline at end of file diff --git a/design/src/main/java/it/inps/sirio/ui/chip/ChipLabelIcon.kt b/design/src/main/java/it/inps/sirio/ui/chip/SirioChipLabelIcon.kt similarity index 89% rename from design/src/main/java/it/inps/sirio/ui/chip/ChipLabelIcon.kt rename to design/src/main/java/it/inps/sirio/ui/chip/SirioChipLabelIcon.kt index 1157995..4473902 100644 --- a/design/src/main/java/it/inps/sirio/ui/chip/ChipLabelIcon.kt +++ b/design/src/main/java/it/inps/sirio/ui/chip/SirioChipLabelIcon.kt @@ -1,5 +1,5 @@ // -// ChipLabelIcon.kt +// SirioChipLabelIcon.kt // // SPDX-FileCopyrightText: 2024 Istituto Nazionale Previdenza Sociale // @@ -25,14 +25,14 @@ import it.inps.sirio.theme.SirioTheme * @param onStateChange The callback when the chip active state change */ @Composable -fun ChipLabelIcon( +fun SirioChipLabelIcon( label: String, icon: FaIconType, enabled: Boolean, isActive: Boolean, onStateChange: (active: Boolean) -> Unit ) { - ChipCommon( + SirioChipCommon( text = label, icon = icon, withClose = false, @@ -44,17 +44,17 @@ fun ChipLabelIcon( @Preview @Composable -private fun ChipLabelIconPreview() { +private fun SirioChipLabelIconPreview() { SirioTheme { Column { - ChipLabelIcon( + SirioChipLabelIcon( label = "Chips", icon = FaIcons.User, enabled = true, isActive = true, onStateChange = {}, ) - ChipLabelIcon( + SirioChipLabelIcon( label = "Chips", icon = FaIcons.User, enabled = false, diff --git a/design/src/main/java/it/inps/sirio/ui/chip/ChipLabelIconClose.kt b/design/src/main/java/it/inps/sirio/ui/chip/SirioChipLabelIconClose.kt similarity index 88% rename from design/src/main/java/it/inps/sirio/ui/chip/ChipLabelIconClose.kt rename to design/src/main/java/it/inps/sirio/ui/chip/SirioChipLabelIconClose.kt index 008948c..c1137f4 100644 --- a/design/src/main/java/it/inps/sirio/ui/chip/ChipLabelIconClose.kt +++ b/design/src/main/java/it/inps/sirio/ui/chip/SirioChipLabelIconClose.kt @@ -1,5 +1,5 @@ // -// ChipLabelIconClose.kt +// SirioChipLabelIconClose.kt // // SPDX-FileCopyrightText: 2024 Istituto Nazionale Previdenza Sociale // @@ -25,14 +25,14 @@ import it.inps.sirio.theme.SirioTheme * @param onClose The callback when the chip close button is clicked */ @Composable -fun ChipLabelIconClose( +fun SirioChipLabelIconClose( label: String, icon: FaIconType, enabled: Boolean, closeContentDescription: String? = null, onClose: () -> Unit, ) { - ChipCommon( + SirioChipCommon( text = label, icon = icon, withClose = true, @@ -46,16 +46,16 @@ fun ChipLabelIconClose( @Preview @Composable -private fun ChipLabelIconClosePreview() { +private fun SirioChipLabelIconClosePreview() { SirioTheme { Column { - ChipLabelIconClose( + SirioChipLabelIconClose( label = "Chips", icon = FaIcons.User, enabled = true, onClose = {}, ) - ChipLabelIconClose( + SirioChipLabelIconClose( label = "Chips", icon = FaIcons.User, enabled = false, @@ -63,4 +63,4 @@ private fun ChipLabelIconClosePreview() { ) } } -} +} \ No newline at end of file diff --git a/design/src/main/java/it/inps/sirio/ui/dropdown/SirioDropdown.kt b/design/src/main/java/it/inps/sirio/ui/dropdown/SirioDropdown.kt new file mode 100644 index 0000000..7d957c9 --- /dev/null +++ b/design/src/main/java/it/inps/sirio/ui/dropdown/SirioDropdown.kt @@ -0,0 +1,144 @@ +// +// SirioDropdown.kt +// +// SPDX-FileCopyrightText: 2022 Istituto Nazionale Previdenza Sociale +// +// SPDX-License-Identifier: BSD-3-Clause +// +package it.inps.sirio.ui.dropdown + +import androidx.annotation.Keep +import androidx.compose.foundation.ScrollState +import androidx.compose.foundation.border +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.ColumnScope +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.wrapContentSize +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.DropdownMenu +import androidx.compose.runtime.Composable +import androidx.compose.runtime.Stable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.layout.layout +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.DpOffset +import androidx.compose.ui.unit.dp +import androidx.compose.ui.window.PopupProperties +import it.inps.sirio.theme.SirioTheme +import it.inps.sirio.theme.dropdownBorderWidth +import it.inps.sirio.ui.button.ButtonSize +import it.inps.sirio.ui.button.ButtonStyle +import it.inps.sirio.ui.button.SirioButton + +@Composable +fun SirioDropdown( + expanded: Boolean, + onDismissRequest: () -> Unit, + modifier: Modifier = Modifier, + offset: DpOffset = DpOffset(0.dp, 0.dp), + scrollState: ScrollState = rememberScrollState(), + properties: PopupProperties = PopupProperties(focusable = true), + content: @Composable ColumnScope.() -> Unit, +) { + DropdownMenu( + expanded = expanded, + onDismissRequest = onDismissRequest, + modifier = modifier + .crop(vertical = 8.dp) + .border( + width = dropdownBorderWidth.dp, + color = SirioTheme.colors.dropdown.option.border.default, + shape = RoundedCornerShape(4.dp) + ) +// .clip(RoundedCornerShape(4.dp)) + , + offset = offset, + scrollState = scrollState, + properties = properties, + content = content + ) +} + +fun Modifier.crop( + horizontal: Dp = 0.dp, + vertical: Dp = 0.dp, +): Modifier = this.layout { measurable, constraints -> + val placeable = measurable.measure(constraints) + fun Dp.toPxInt(): Int = this.toPx().toInt() + + layout( + placeable.width - (horizontal * 2).toPxInt(), + placeable.height - (vertical * 2).toPxInt() + ) { + placeable.placeRelative(-horizontal.toPx().toInt(), -vertical.toPx().toInt()) + } +} + +@Keep +data class SirioDropdownColors( + val option: SirioDropdownOptionColors, +) { + companion object { + @Stable + val Unspecified = SirioDropdownColors( + option = SirioDropdownOptionColors.Unspecified, + ) + } +} + +@Keep +data class SirioDropdownTypography( + val option: SirioDropdownOptionTypography, +) { + companion object { + @Stable + val Default = SirioDropdownTypography( + option = SirioDropdownOptionTypography.Default, + ) + } +} + +@Preview(showSystemUi = true) +@Composable +private fun SirioDropdownPreview() { + SirioTheme { + var show by remember { mutableStateOf(false) } + Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) { + Box(Modifier.wrapContentSize(align = Alignment.TopEnd)) { + SirioButton(text = "Show", size = ButtonSize.Large, style = ButtonStyle.Primary) { + show = true + } + SirioDropdown(show, { show = false }) { + val text = "Option Value" + SirioDropdownOptionItem( + text = text, + selected = false, + enabled = true, + onCLick = {}) + SirioDropdownOptionItem( + text = text, + selected = true, + enabled = true, + onCLick = {}) + SirioDropdownOptionItem( + text = text, + selected = false, + enabled = false, + onCLick = {}) + SirioDropdownOptionItem( + text = text, + selected = true, + enabled = false, + onCLick = {}) + } + } + } + } +} \ No newline at end of file diff --git a/design/src/main/java/it/inps/sirio/ui/dropdown/SirioDropdownOptionItem.kt b/design/src/main/java/it/inps/sirio/ui/dropdown/SirioDropdownOptionItem.kt new file mode 100644 index 0000000..afc8fa1 --- /dev/null +++ b/design/src/main/java/it/inps/sirio/ui/dropdown/SirioDropdownOptionItem.kt @@ -0,0 +1,132 @@ +// +// SirioDropdownOptionItem.kt +// +// SPDX-FileCopyrightText: 2022 Istituto Nazionale Previdenza Sociale +// +// SPDX-License-Identifier: BSD-3-Clause +// +package it.inps.sirio.ui.dropdown + +import androidx.annotation.Keep +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.foundation.interaction.collectIsFocusedAsState +import androidx.compose.foundation.interaction.collectIsHoveredAsState +import androidx.compose.foundation.interaction.collectIsPressedAsState +import androidx.compose.foundation.layout.Column +import androidx.compose.material3.DropdownMenuItem +import androidx.compose.runtime.Composable +import androidx.compose.runtime.Stable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.guru.fontawesomecomposelib.FaIcons +import it.inps.sirio.theme.SirioColorState +import it.inps.sirio.theme.SirioTheme +import it.inps.sirio.theme.dropdownBorderWidth +import it.inps.sirio.ui.text.SirioText +import it.inps.sirio.utils.SirioIcon + +@Composable +fun SirioDropdownOptionItem( + text: String, + selected: Boolean, + enabled: Boolean = true, + onCLick: () -> Unit, +) { + val interactionSource = remember { MutableInteractionSource() } + val isPressed by interactionSource.collectIsPressedAsState() + val isFocused by interactionSource.collectIsFocusedAsState() + val isHovered by interactionSource.collectIsHoveredAsState() + + val backgroundColor = SirioTheme.colors.dropdown.option.background.get( + disabled = !enabled, + focused = isFocused, + pressed = isPressed, + hovered = isHovered, + valued = selected + ) + + val contentColor = SirioTheme.colors.dropdown.option.content.get( + disabled = !enabled, + focused = isFocused, + pressed = isPressed, + hovered = isHovered, + valued = selected + ) + + val borderColor = SirioTheme.colors.dropdown.option.border.get( + disabled = !enabled, + focused = isFocused, + pressed = isPressed, + hovered = isHovered, + valued = selected + ) + + DropdownMenuItem( + text = { + SirioText( + text = text, + color = contentColor, + typography = SirioTheme.typography.dropdown.option.text, + ) + }, + onClick = onCLick, + modifier = Modifier + .background(backgroundColor) + .border(width = dropdownBorderWidth.dp, color = borderColor), + trailingIcon = if (selected) { + { + SirioIcon(faIcon = FaIcons.Check, iconColor = contentColor) + } + } else null, + enabled = enabled, + interactionSource = interactionSource, + ) +} + +@Keep +data class SirioDropdownOptionColors( + val background: SirioColorState, + val border: SirioColorState, + val content: SirioColorState, +) { + companion object { + @Stable + val Unspecified = SirioDropdownOptionColors( + background = SirioColorState.Unspecified, + border = SirioColorState.Unspecified, + content = SirioColorState.Unspecified, + ) + } +} + +@Keep +data class SirioDropdownOptionTypography( + val text: TextStyle, +) { + companion object { + @Stable + val Default = SirioDropdownOptionTypography( + text = TextStyle.Default, + ) + } +} + +@Preview +@Composable +private fun SirioDropdownOptionItemPreview() { + SirioTheme { + Column { + val text = "Option Value" + SirioDropdownOptionItem(text = text, selected = false, enabled = true, onCLick = {}) + SirioDropdownOptionItem(text = text, selected = true, enabled = true, onCLick = {}) + SirioDropdownOptionItem(text = text, selected = false, enabled = false, onCLick = {}) + SirioDropdownOptionItem(text = text, selected = true, enabled = false, onCLick = {}) + } + } +} \ No newline at end of file diff --git a/design/src/main/java/it/inps/sirio/ui/dropdown/SirioPopup.kt b/design/src/main/java/it/inps/sirio/ui/dropdown/SirioPopup.kt new file mode 100644 index 0000000..aa35d05 --- /dev/null +++ b/design/src/main/java/it/inps/sirio/ui/dropdown/SirioPopup.kt @@ -0,0 +1,358 @@ +// +// SirioPopup.kt +// +// SPDX-FileCopyrightText: 2022 Istituto Nazionale Previdenza Sociale +// +// SPDX-License-Identifier: BSD-3-Clause +// +package it.inps.sirio.ui.dropdown + +import androidx.compose.animation.core.MutableTransitionState +import androidx.compose.animation.core.animateFloat +import androidx.compose.animation.core.tween +import androidx.compose.animation.core.updateTransition +import androidx.compose.foundation.BorderStroke +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.ColumnScope +import androidx.compose.foundation.layout.IntrinsicSize +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.foundation.verticalScroll +import androidx.compose.material3.Surface +import androidx.compose.runtime.Composable +import androidx.compose.runtime.Immutable +import androidx.compose.runtime.Stable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.GraphicsLayerScope +import androidx.compose.ui.graphics.TransformOrigin +import androidx.compose.ui.graphics.graphicsLayer +import androidx.compose.ui.platform.LocalDensity +import androidx.compose.ui.unit.Density +import androidx.compose.ui.unit.DpOffset +import androidx.compose.ui.unit.IntOffset +import androidx.compose.ui.unit.IntRect +import androidx.compose.ui.unit.IntSize +import androidx.compose.ui.unit.LayoutDirection +import androidx.compose.ui.unit.dp +import androidx.compose.ui.window.Popup +import androidx.compose.ui.window.PopupPositionProvider +import androidx.compose.ui.window.PopupProperties +import it.inps.sirio.theme.SirioTheme +import it.inps.sirio.theme.dropdownBorderWidth +import it.inps.sirio.theme.dropdownCornerSize + +/** + * Class that defines the state of a popup. + * + * @property isVisible Boolean that defines whether the popup is currently visible or not. + */ +@Stable +class SirioPopupState( + isVisible: Boolean = false, +) { + /** + * Horizontal alignment from which the popup will expand from and shrink to. + */ + var horizontalAlignment: Alignment.Horizontal by mutableStateOf(Alignment.CenterHorizontally) + + /** + * Boolean that defines whether the popup is displayed above or below the anchor. + */ + var isTop: Boolean by mutableStateOf(false) + + /** + * Boolean that defines whether the popup is currently visible or not. + */ + var isVisible: Boolean by mutableStateOf(isVisible) +} + + +/** + * Composable for displaying a custom popup. + * + * @param sirioPopupState the [SirioPopupState] used to track whether the popup is visible + * @param onDismissRequest callback to be invoked when the popup is dismissed + * @param modifier [Modifier] used to modify the composable's layout and behavior + * @param offset the [DpOffset] to apply to the popup's position + * @param properties the [PopupProperties] used to configure the popup + * @param content the [ColumnScope] composable that defines the popup's content + */ +@Composable +fun SirioPopup( + sirioPopupState: SirioPopupState, + onDismissRequest: () -> Unit, + modifier: Modifier = Modifier, + offset: DpOffset = DpOffset(0.dp, 0.dp), + properties: PopupProperties = PopupProperties(focusable = true), + content: @Composable ColumnScope.() -> Unit, +) { + // Create a transition state to track whether the popup is expanded. + val expandedStates = remember { MutableTransitionState(false) } + expandedStates.targetState = sirioPopupState.isVisible + + // Only show the popup if it's visible. + if (expandedStates.currentState || expandedStates.targetState) { + val density = LocalDensity.current + + // Instantiate a CustomPopupPositionProvider with the given offset. + val popupPositionProvider = SirioPopupPositionProvider( + contentOffset = offset, + density = density + ) { alignment, isTop -> + // Update the PopupState's alignment and direction. + sirioPopupState.horizontalAlignment = alignment + sirioPopupState.isTop = isTop + } + + // Display the popup using the Popup composable. + Popup( + onDismissRequest = onDismissRequest, + popupPositionProvider = popupPositionProvider, + properties = properties + ) { + // Display the popup's content using the CustomPopupContent composable. + SirioPopupContent( + expandedStates = expandedStates, + transformOrigin = TransformOrigin( + pivotFractionX = when (sirioPopupState.horizontalAlignment) { + Alignment.Start -> 0f + Alignment.CenterHorizontally -> 0.5f + else -> 1f + }, + pivotFractionY = if (sirioPopupState.isTop) 1f else 0f + ), + modifier = modifier, + content = content + ) + } + } +} + +/** + * A custom implementation of PopupPositionProvider. + * This calculates the position of the popup relative to the anchor + * + * @property contentOffset The offset of the popup content from the anchor position. + * @property density The density of the display. + * @property onPopupPositionFound A callback that is called once the popup position is found. + */ +@Immutable +private data class SirioPopupPositionProvider( + val contentOffset: DpOffset, + val density: Density, + val onPopupPositionFound: (Alignment.Horizontal, Boolean) -> Unit, +) : PopupPositionProvider { + + override fun calculatePosition( + anchorBounds: IntRect, + windowSize: IntSize, + layoutDirection: LayoutDirection, + popupContentSize: IntSize, + ): IntOffset { + // The content offset specified using the dropdown offset parameter. + val contentOffsetX = with(density) { contentOffset.x.roundToPx() } + // The content offset specified using the dropdown offset parameter. + val contentOffsetY = with(density) { contentOffset.y.roundToPx() } + + val isFitEnd = + (anchorBounds.left + contentOffsetX + popupContentSize.width) < windowSize.width + val isFitStart = (anchorBounds.left - contentOffsetX - popupContentSize.width) > 0 + val popupHalfWidth = popupContentSize.width / 2 + val halfAnchor = (anchorBounds.right - anchorBounds.left) / 2 + val isFitCenter = + ((anchorBounds.left + halfAnchor + popupHalfWidth) < windowSize.width) && + ((anchorBounds.left + halfAnchor - popupHalfWidth) > 0) + + val endPlacementOffset = anchorBounds.left - contentOffsetX + val centerPlacementOffset = anchorBounds.left - popupHalfWidth + contentOffsetX + val startPlacementOffset = anchorBounds.right + contentOffsetX - popupContentSize.width + + val bottomCoordinatesY = anchorBounds.bottom + contentOffsetY + popupContentSize.height + val isFitBottom = bottomCoordinatesY <= windowSize.height + val topCoordinatesY = anchorBounds.top - contentOffsetY - popupContentSize.height + val isFitTop = topCoordinatesY > 0 || anchorBounds.top > windowSize.height + + // Compute vertical position. + val toBottom = anchorBounds.bottom + contentOffsetY + val toTop = anchorBounds.top - contentOffsetY - popupContentSize.height + val toCenter = anchorBounds.top - popupContentSize.height / 2 + val toDisplayBottom = windowSize.height - popupContentSize.height + val yOffset = sequenceOf( + if (isFitTop) toTop else toBottom, + toCenter, + toDisplayBottom + ).firstOrNull { + it + popupContentSize.height <= windowSize.height + } ?: toTop + + val horizontalAndOffset = getHorizontalOffset( + isFitsStart = isFitStart, + isFitsEnd = isFitEnd, + isFitsCenter = isFitCenter, + endPlacementOffset = endPlacementOffset, + startPlacementOffset = startPlacementOffset, + centerPlacementOffset = centerPlacementOffset + ) + + onPopupPositionFound(horizontalAndOffset.first, isFitTop) + return IntOffset(horizontalAndOffset.second, yOffset) + } +} + + +@Suppress("ModifierParameter") +/** + * Composable that defines custom animations for a popup and applies them to a [Surface]. + * + * @param expandedStates [MutableTransitionState] that determines whether the popup is expanding or shrinking. + * @param transformOrigin [TransformOrigin] determining from which position the popup (dis)appears from. + * @param modifier [Modifier] for this composable. + * @param content content that will be displayed within the popup. + */ +@Composable +private fun SirioPopupContent( + expandedStates: MutableTransitionState, + transformOrigin: TransformOrigin, + modifier: Modifier = Modifier, + content: @Composable ColumnScope.() -> Unit, +) { + // Menu open/close animation. + val transition = updateTransition(expandedStates, "Popup") + + // Scale animation. + val scale by transition.animateFloat( + transitionSpec = { + if (false isTransitioningTo true) { + // Dismissed to expanded. + tween(durationMillis = 200) + } else { + // Expanded to dismissed. + tween(durationMillis = 200) + } + }, + label = "Popup Scale" + ) { + if (it) { + // Popup is expanded. + 1f + } else { + // Popup is dismissed. + 0f + } + } + + // Alpha animation. + val alpha by transition.animateFloat( + transitionSpec = { + if (false isTransitioningTo true) { + // Dismissed to expanded. + tween(durationMillis = 200) + } else { + // Expanded to dismissed. + tween(durationMillis = 200) + } + }, + label = "Popup Alpha" + ) { + if (it) { + // Popup is expanded. + 1f + } else { + // Popup is dismissed. + 0f + } + } + + // Helper function for applying animations to graphics layer. + fun GraphicsLayerScope.graphicsLayerAnim() { + scaleX = scale + scaleY = scale + this.alpha = alpha + this.transformOrigin = transformOrigin + } + + Surface( + modifier = Modifier + .graphicsLayer { + graphicsLayerAnim() + }, + shape = RoundedCornerShape(dropdownCornerSize.dp), + border = BorderStroke( + width = dropdownBorderWidth.dp, + color = SirioTheme.colors.dropdown.option.border.default + ) + ) { + Column( + modifier = modifier + .width(IntrinsicSize.Max) + .verticalScroll(rememberScrollState()), + content = content + ) + } +} + +/** + * Get the horizontal offset of the popup based on fitting and placement. + * + * @param isFitsStart Whether the popup fits when placed at the start. + * @param isFitsEnd Whether the popup fits when placed at the end. + * @param isFitsCenter Whether the popup fits when placed at the center. + * @param endPlacementOffset The offset when the popup is placed at the end. + * @param startPlacementOffset The offset when the popup is placed at the start. + * @param centerPlacementOffset The offset when the popup is placed at the center. + * @return A pair consisting of the horizontal alignment and the horizontal offset. + */ +private fun getHorizontalOffset( + isFitsStart: Boolean, + isFitsEnd: Boolean, + isFitsCenter: Boolean, + endPlacementOffset: Int, + startPlacementOffset: Int, + centerPlacementOffset: Int, +): Pair { + + // Check which alignment fits the best. + val alignments = listOf( + Alignment.Start, + Alignment.CenterHorizontally, + Alignment.End + ) + + // Check the corresponding offsets. + val offsets = listOf( + endPlacementOffset, + centerPlacementOffset, + startPlacementOffset + ) + + // Check which alignment and offset fits the best. + val fallbacks = mutableListOf>() + for (index in 0..2) { + if (listOf(isFitsEnd, isFitsCenter, isFitsStart)[index]) { + fallbacks.add(Pair(alignments[index], offsets[index])) + } + } + + // If there is a fallback, choose it as the alignment and offset. + val fallback = fallbacks.firstOrNull() + if (fallback != null) { + return fallback + } + + // If there is no fallback, calculate the horizontal offset. + val finalHorizontalFallback = if (isFitsStart) { + 0 + } else if (isFitsEnd) { + 2 + } else { + 1 + } + val fallbackHorizontalOffset = offsets[finalHorizontalFallback] + return Pair(alignments[finalHorizontalFallback], fallbackHorizontalOffset) +} \ No newline at end of file diff --git a/design/src/main/java/it/inps/sirio/ui/fileupload/FileUploadCommon.kt b/design/src/main/java/it/inps/sirio/ui/fileupload/FileUploadCommon.kt index 998af0e..fda77fb 100644 --- a/design/src/main/java/it/inps/sirio/ui/fileupload/FileUploadCommon.kt +++ b/design/src/main/java/it/inps/sirio/ui/fileupload/FileUploadCommon.kt @@ -34,7 +34,7 @@ import it.inps.sirio.theme.fileUploadTitlePaddingBottom import it.inps.sirio.ui.button.ButtonSize import it.inps.sirio.ui.button.ButtonStyle import it.inps.sirio.ui.button.SirioButton -import it.inps.sirio.ui.chip.ChipLabelClose +import it.inps.sirio.ui.chip.SirioChipLabelClose import it.inps.sirio.ui.text.SirioTextCommon /** @@ -96,7 +96,7 @@ internal fun FileUploadCommon( // lastLineMainAxisAlignment = FlowMainAxisAlignment.Start, ) { uploadList.forEachIndexed { index, item -> - ChipLabelClose( + SirioChipLabelClose( label = item, enabled = enabled, closeContentDescription = closeContentDescription, diff --git a/design/src/main/java/it/inps/sirio/ui/filter/SirioFilterCheckbox.kt b/design/src/main/java/it/inps/sirio/ui/filter/SirioFilterCheckbox.kt new file mode 100644 index 0000000..c9b074f --- /dev/null +++ b/design/src/main/java/it/inps/sirio/ui/filter/SirioFilterCheckbox.kt @@ -0,0 +1,84 @@ +// +// SirioFilterCheckbox.kt +// +// SPDX-FileCopyrightText: 2022 Istituto Nazionale Previdenza Sociale +// +// SPDX-License-Identifier: BSD-3-Clause +// +package it.inps.sirio.ui.filter + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import it.inps.sirio.theme.SirioTheme +import it.inps.sirio.theme.filterPadding +import it.inps.sirio.ui.checkbox.SirioCheckboxCommon + +/** + * A filter checkbox component. + * + * @param checked Whether the checkbox is currently checked. + * @param text The text to display next to the checkbox. + * @param enabled Whether the checkbox is enabled. + * @param onCheckedChange The callback to be invoked when the checked state of the checkbox changes. + */ +@Composable +fun SirioFilterCheckbox( + checked: Boolean, + text: String? = null, + enabled: Boolean = true, + onCheckedChange: (Boolean) -> Unit, +) { + Box( + modifier = Modifier + .background(SirioTheme.colors.filter.background) + .padding(filterPadding.dp) + ) { + SirioCheckboxCommon( + checked = checked, + modifier = Modifier.fillMaxWidth(), + text = text, + enabled = enabled, + onCheckedChange = onCheckedChange, + ) + } +} + +@Preview +@Composable +private fun SirioFilterCheckboxPreview() { + SirioTheme { + Column { + SirioFilterCheckbox( + checked = false, + text = "Title", + enabled = true, + onCheckedChange = {}, + ) + SirioFilterCheckbox( + checked = true, + text = "Title", + enabled = true, + onCheckedChange = {}, + ) + SirioFilterCheckbox( + checked = false, + text = "Title", + enabled = false, + onCheckedChange = {}, + ) + SirioFilterCheckbox( + checked = true, + text = "Title", + enabled = false, + onCheckedChange = {}, + ) + } + } +} \ No newline at end of file diff --git a/design/src/main/java/it/inps/sirio/ui/filter/SirioFilterChips.kt b/design/src/main/java/it/inps/sirio/ui/filter/SirioFilterChips.kt new file mode 100644 index 0000000..6bf7de6 --- /dev/null +++ b/design/src/main/java/it/inps/sirio/ui/filter/SirioFilterChips.kt @@ -0,0 +1,85 @@ +// +// SirioFilterChips.kt +// +// SPDX-FileCopyrightText: 2022 Istituto Nazionale Previdenza Sociale +// +// SPDX-License-Identifier: BSD-3-Clause +// +package it.inps.sirio.ui.filter + +import androidx.compose.foundation.background +import androidx.compose.foundation.horizontalScroll +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.rememberScrollState +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import it.inps.sirio.theme.SirioTheme +import it.inps.sirio.theme.filterChipsPadding +import it.inps.sirio.theme.filterPadding +import it.inps.sirio.ui.chip.SirioChipLabel + +/** + * A filter row of chips with horizontal scrolling. + * + * @param texts The list of text labels for the chips. + * @param selectedTexts The list of currently selected text labels. + * @param onSelectedChanges The callback to be invoked when the selected chips change. + */ +@Composable +fun SirioFilterChips( + texts: List, + selectedTexts: List = emptyList(), + onSelectedChanges: (List) -> Unit, +) { + Row( + modifier = Modifier + .fillMaxWidth() + .background(SirioTheme.colors.filter.background) + .horizontalScroll(rememberScrollState()) + .padding(filterPadding.dp), + horizontalArrangement = Arrangement.spacedBy(filterChipsPadding.dp), + verticalAlignment = Alignment.CenterVertically, + ) { + texts.forEach { text -> + SirioChipLabel( + label = text, + enabled = true, + active = selectedTexts.contains(text), + onStateChange = { + if (it) { + onSelectedChanges(selectedTexts + text) + } else { + onSelectedChanges(selectedTexts - text) + } + }, + ) + } + } +} + +@Preview +@Composable +private fun SirioFilterChipsPreview() { + SirioTheme { + Column { + SirioFilterChips( + texts = listOf( + "Valore selezionato", + "Valore", + "Valore", + "Valore", + "Valore" + ), + selectedTexts = listOf("Valore selezionato"), + onSelectedChanges = {}, + ) + } + } +} \ No newline at end of file diff --git a/design/src/main/java/it/inps/sirio/ui/filter/SirioFilterChipsWrap.kt b/design/src/main/java/it/inps/sirio/ui/filter/SirioFilterChipsWrap.kt new file mode 100644 index 0000000..bb1a813 --- /dev/null +++ b/design/src/main/java/it/inps/sirio/ui/filter/SirioFilterChipsWrap.kt @@ -0,0 +1,84 @@ +// +// SirioFilterChipsWrap.kt +// +// SPDX-FileCopyrightText: 2022 Istituto Nazionale Previdenza Sociale +// +// SPDX-License-Identifier: BSD-3-Clause +// +@file:OptIn(ExperimentalLayoutApi::class) + +package it.inps.sirio.ui.filter + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.ExperimentalLayoutApi +import androidx.compose.foundation.layout.FlowRow +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import it.inps.sirio.theme.SirioTheme +import it.inps.sirio.theme.filterChipsPadding +import it.inps.sirio.theme.filterPadding +import it.inps.sirio.ui.chip.SirioChipLabel + +/** + * A component that wraps a list of chips. + * + * @param texts The list of text labels for the chips. + * @param selectedTexts The list of currently selected text labels. + * @param onSelectedChanges The callback to be invoked when the selected chips change. + */ +@Composable +fun SirioFilterChipsWrap( + texts: List, + selectedTexts: List = emptyList(), + onSelectedChanges: (List) -> Unit, +) { + FlowRow( + modifier = Modifier + .fillMaxWidth() + .background(SirioTheme.colors.filter.background) + .padding(filterPadding.dp), + horizontalArrangement = Arrangement.spacedBy(filterChipsPadding.dp), + verticalArrangement = Arrangement.spacedBy(filterChipsPadding.dp), + ) { + texts.forEach { text -> + SirioChipLabel( + label = text, + enabled = true, + active = selectedTexts.contains(text), + onStateChange = { + if (it) { + onSelectedChanges(selectedTexts + text) + } else { + onSelectedChanges(selectedTexts - text) + } + }, + ) + } + } +} + +@Preview +@Composable +private fun SirioFilterChipsWrapPreview() { + SirioTheme { + Column { + SirioFilterChipsWrap( + texts = listOf( + "Valore selezionato", + "Valore", + "Valore", + "Valore", + "Valore" + ), + selectedTexts = listOf("Valore selezionato"), + onSelectedChanges = {}, + ) + } + } +} \ No newline at end of file diff --git a/design/src/main/java/it/inps/sirio/ui/filter/SirioFilterCommon.kt b/design/src/main/java/it/inps/sirio/ui/filter/SirioFilterCommon.kt new file mode 100644 index 0000000..dc74bb9 --- /dev/null +++ b/design/src/main/java/it/inps/sirio/ui/filter/SirioFilterCommon.kt @@ -0,0 +1,49 @@ +// +// SirioFilterCommon.kt +// +// SPDX-FileCopyrightText: 2022 Istituto Nazionale Previdenza Sociale +// +// SPDX-License-Identifier: BSD-3-Clause +// +package it.inps.sirio.ui.filter + +import androidx.annotation.Keep +import androidx.compose.runtime.Stable +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.TextStyle + +@Keep +data class SirioFilterColors( + val background: Color, + val close: Color, + val header: Color, + val info: Color, + val selectedBackground: Color, + val title: Color, +) { + companion object { + @Stable + val Unspecified = SirioFilterColors( + background = Color.Unspecified, + close = Color.Unspecified, + header = Color.Unspecified, + info = Color.Unspecified, + selectedBackground = Color.Unspecified, + title = Color.Unspecified + ) + } +} + +@Keep +data class SirioFilterTypography( + val header: TextStyle, + val title: TextStyle, +) { + companion object { + @Stable + val Default = SirioFilterTypography( + header = TextStyle.Default, + title = TextStyle.Default, + ) + } +} diff --git a/design/src/main/java/it/inps/sirio/ui/filter/SirioFilterFooter.kt b/design/src/main/java/it/inps/sirio/ui/filter/SirioFilterFooter.kt new file mode 100644 index 0000000..7255d93 --- /dev/null +++ b/design/src/main/java/it/inps/sirio/ui/filter/SirioFilterFooter.kt @@ -0,0 +1,74 @@ +// +// SirioFilterFooter.kt +// +// SPDX-FileCopyrightText: 2022 Istituto Nazionale Previdenza Sociale +// +// SPDX-License-Identifier: BSD-3-Clause +// +package it.inps.sirio.ui.filter + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import it.inps.sirio.theme.SirioTheme +import it.inps.sirio.theme.filterFooterButtonSpacing +import it.inps.sirio.theme.filterFooterPaddingHorizontal +import it.inps.sirio.theme.filterFooterPaddingVertical +import it.inps.sirio.ui.button.ButtonSize +import it.inps.sirio.ui.button.ButtonStyle +import it.inps.sirio.ui.button.SirioButton + +@Composable +fun SirioFilterFooter( + neutralText: String, + positiveText: String, + onNeutral: () -> Unit, + onPositive: () -> Unit, +) { + Row( + modifier = Modifier + .fillMaxWidth() + .background(SirioTheme.colors.filter.background) + .padding(vertical = filterFooterPaddingVertical.dp, horizontal = filterFooterPaddingHorizontal.dp), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy(filterFooterButtonSpacing.dp) + ) { + SirioButton( + modifier = Modifier.weight(1f), + text = neutralText, + size = ButtonSize.Large, + style = ButtonStyle.Secondary, + onClick = onNeutral, + ) + SirioButton( + modifier = Modifier.weight(1f), + text = positiveText, + size = ButtonSize.Large, + style = ButtonStyle.Primary, + onClick = onPositive, + ) + } +} + +@Preview +@Composable +private fun SirioFilterFooterPreview() { + SirioTheme { + Column { + SirioFilterFooter( + neutralText = "Elimina filtri", + positiveText = "Applica filtri", + onNeutral = {}, + onPositive = {}, + ) + } + } +} \ No newline at end of file diff --git a/design/src/main/java/it/inps/sirio/ui/filter/SirioFilterHeader.kt b/design/src/main/java/it/inps/sirio/ui/filter/SirioFilterHeader.kt new file mode 100644 index 0000000..7ba4271 --- /dev/null +++ b/design/src/main/java/it/inps/sirio/ui/filter/SirioFilterHeader.kt @@ -0,0 +1,79 @@ +// +// SirioFilterHeader.kt +// +// SPDX-FileCopyrightText: 2022 Istituto Nazionale Previdenza Sociale +// +// SPDX-License-Identifier: BSD-3-Clause +// +package it.inps.sirio.ui.filter + +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.semantics.Role +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.guru.fontawesomecomposelib.FaIcons +import it.inps.sirio.theme.SirioTheme +import it.inps.sirio.theme.filterHeaderCloseSize +import it.inps.sirio.theme.filterHeaderPaddingHorizontal +import it.inps.sirio.theme.filterHeaderPaddingVertical +import it.inps.sirio.ui.text.SirioText +import it.inps.sirio.utils.SirioFaIcon + +/** + * A header component for filter sections. + * + * @param title The title text to display in the header. + * @param closeContentDescription The content description for the close icon, for accessibility purposes. + * @param onClose The callback to be invoked when the close icon is clicked. + */ +@Composable +fun SirioFilterHeader( + title: String, + closeContentDescription: String? = null, + onClose: () -> Unit, +) { + Column( + modifier = Modifier + .fillMaxWidth() + .background(SirioTheme.colors.filter.background) + .padding( + horizontal = filterHeaderPaddingHorizontal.dp, + vertical = filterHeaderPaddingVertical.dp + ), + verticalArrangement = Arrangement.spacedBy(filterHeaderPaddingVertical.dp) + ) { + SirioFaIcon( + faIcon = FaIcons.Times, + modifier = Modifier + .align(Alignment.End) + .clickable(role = Role.Button, onClick = onClose), + size = filterHeaderCloseSize.dp, + tint = SirioTheme.colors.filter.close, + contentDescription = closeContentDescription, + ) + SirioText( + text = title, + modifier = Modifier.fillMaxWidth(), + color = SirioTheme.colors.filter.header, + typography = SirioTheme.typography.filter.header, + ) + } +} + +@Preview +@Composable +private fun SirioFilterHeaderPreview() { + SirioTheme { + Column { + SirioFilterHeader(title = "Filtri", onClose = {}) + } + } +} \ No newline at end of file diff --git a/design/src/main/java/it/inps/sirio/ui/filter/SirioFilterInput.kt b/design/src/main/java/it/inps/sirio/ui/filter/SirioFilterInput.kt new file mode 100644 index 0000000..78872c4 --- /dev/null +++ b/design/src/main/java/it/inps/sirio/ui/filter/SirioFilterInput.kt @@ -0,0 +1,100 @@ +// +// SirioFilterInput.kt +// +// SPDX-FileCopyrightText: 2022 Istituto Nazionale Previdenza Sociale +// +// SPDX-License-Identifier: BSD-3-Clause +// +package it.inps.sirio.ui.filter + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.text.KeyboardActions +import androidx.compose.foundation.text.KeyboardOptions +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.guru.fontawesomecomposelib.FaIconType +import it.inps.sirio.theme.SirioTheme +import it.inps.sirio.theme.filterPadding +import it.inps.sirio.ui.textfield.SirioTextFieldCommon +import it.inps.sirio.ui.textfield.TextFieldSemantic + +/** + * A filter input component. + * + * @param label The label to display above the input field. + * @param text The current text value of the input field. + * @param placeholder The placeholder text to display when the input field is empty. + * @param secureText Whether the input field should display text securely (e.g., for passwords). + * @param icon The optional icon to display within the input field. + * @param iconContentDescription The content description for the icon, for accessibility purposes. + * @param onInfoClick The callback to be invoked when the info icon is clicked. + * @param infoContentDescription The content description for the info icon, for accessibility purposes. + * @param helperText The helper text to display below the input field. + * @param type The semantic type of the text field [@see TextFieldSemantic] + * @param keyboardOptions The keyboard options to configure the soft keyboard. + * @param keyboardActions The keyboard actions to handle specific keyboard events. + * @param onIconClick The callback to be invoked when the icon is clicked. + * @param onTextFieldClick The callback to be invoked when the text field is clicked. + * @param onValueChange The callback to be invoked when the text value of the input field changes. + */ +@Composable +fun SirioFilterInput( + label: String, + text: String, + placeholder: String? = null, + secureText: Boolean = false, + icon: FaIconType? = null, + iconContentDescription: String? = null, + onInfoClick: (() -> Unit)? = null, + infoContentDescription: String? = null, + helperText: String? = null, + type: TextFieldSemantic? = null, + keyboardOptions: KeyboardOptions = KeyboardOptions.Default, + keyboardActions: KeyboardActions = KeyboardActions.Default, + onIconClick: (() -> Unit)? = null, + onTextFieldClick: (() -> Unit)? = null, + onValueChange: (String) -> Unit, +) { + Box( + modifier = Modifier + .background(SirioTheme.colors.filter.background) + .padding(filterPadding.dp) + ) { + SirioTextFieldCommon( + text = text, + secureText = secureText, + onValueChange = onValueChange, + placeholder = placeholder, + icon = icon, + iconContentDescription = iconContentDescription, + label = label, + onInfoClick = onInfoClick, + infoContentDescription = infoContentDescription, + helperText = helperText, + type = type, + keyboardOptions = keyboardOptions, + keyboardActions = keyboardActions, + onIconClick = onIconClick, + onTextFieldClick = onTextFieldClick, + ) + } +} + +@Preview +@Composable +private fun SirioFilterInputPreview() { + SirioTheme { + Column { + SirioFilterInput( + label = "Label", + text = "Text", + onValueChange = {}, + ) + } + } +} \ No newline at end of file diff --git a/design/src/main/java/it/inps/sirio/ui/filter/SirioFilterRadio.kt b/design/src/main/java/it/inps/sirio/ui/filter/SirioFilterRadio.kt new file mode 100644 index 0000000..8a439f4 --- /dev/null +++ b/design/src/main/java/it/inps/sirio/ui/filter/SirioFilterRadio.kt @@ -0,0 +1,84 @@ +// +// SirioFilterRadio.kt +// +// SPDX-FileCopyrightText: 2022 Istituto Nazionale Previdenza Sociale +// +// SPDX-License-Identifier: BSD-3-Clause +// +package it.inps.sirio.ui.filter + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import it.inps.sirio.theme.SirioTheme +import it.inps.sirio.theme.filterPadding +import it.inps.sirio.ui.radiobutton.SirioRadioButtonCommon + +/** + * A filter radio button component. + * + * @param selected Whether the radio button is currently selected. + * @param text The text to display next to the radio button. + * @param enabled Whether the radio button is enabled. + * @param onClick The callback to be invoked when the radio button is clicked. + */ +@Composable +fun SirioFilterRadio( + selected: Boolean, + text: String? = null, + enabled: Boolean = true, + onClick: () -> Unit, +) { + Box( + modifier = Modifier + .background(SirioTheme.colors.filter.background) + .padding(filterPadding.dp) + ) { + SirioRadioButtonCommon( + selected = selected, + modifier = Modifier.fillMaxWidth(), + text = text, + enabled = enabled, + onClick = onClick, + ) + } +} + +@Preview +@Composable +private fun SirioFilterRadioPreview() { + SirioTheme { + Column { + SirioFilterRadio( + selected = false, + text = "Title", + enabled = true, + onClick = {}, + ) + SirioFilterRadio( + selected = true, + text = "Title", + enabled = true, + onClick = {}, + ) + SirioFilterRadio( + selected = false, + text = "Title", + enabled = false, + onClick = {}, + ) + SirioFilterRadio( + selected = true, + text = "Title", + enabled = false, + onClick = {}, + ) + } + } +} \ No newline at end of file diff --git a/design/src/main/java/it/inps/sirio/ui/filter/SirioFilterSelected.kt b/design/src/main/java/it/inps/sirio/ui/filter/SirioFilterSelected.kt new file mode 100644 index 0000000..412bac3 --- /dev/null +++ b/design/src/main/java/it/inps/sirio/ui/filter/SirioFilterSelected.kt @@ -0,0 +1,78 @@ +// +// SirioFilterSelected.kt +// +// SPDX-FileCopyrightText: 2022 Istituto Nazionale Previdenza Sociale +// +// SPDX-License-Identifier: BSD-3-Clause +// +@file:OptIn(ExperimentalLayoutApi::class) + +package it.inps.sirio.ui.filter + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.ExperimentalLayoutApi +import androidx.compose.foundation.layout.FlowRow +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import it.inps.sirio.theme.SirioTheme +import it.inps.sirio.theme.filterChipsPadding +import it.inps.sirio.theme.filterPadding +import it.inps.sirio.theme.filterSelectedPaddingVertical +import it.inps.sirio.ui.chip.SirioChipLabelClose + +/** + * A composable function that displays a row of selected filter values as chips with close icons. + * + * @param values The list of selected filter values to display. + * @param closeContentDescription The content description for the close icon, for accessibility purposes. + * @param onDeleteValue The callback to be invoked when a chip's close icon is clicked. + */ +@Composable +fun SirioFilterSelected( + values: List, + closeContentDescription: String? = null, + onDeleteValue: (String) -> Unit, +) { + FlowRow( + modifier = Modifier + .fillMaxWidth() + .background(SirioTheme.colors.filter.selectedBackground) + .padding(horizontal = filterPadding.dp, vertical = filterSelectedPaddingVertical.dp), + horizontalArrangement = Arrangement.spacedBy(filterChipsPadding.dp), + verticalArrangement = Arrangement.spacedBy(filterChipsPadding.dp), + ) { + values.forEach { text -> + SirioChipLabelClose( + label = text, + enabled = true, + closeContentDescription = closeContentDescription, + onClose = { onDeleteValue(text) }, + ) + } + } +} + +@Preview +@Composable +private fun SirioFilterSelectedPreview() { + SirioTheme { + Column { + SirioFilterSelected( + values = listOf( + "Valore A", + "Valore B", + "Valore C", + "Valore D", + "Valore E" + ), + onDeleteValue = {}, + ) + } + } +} \ No newline at end of file diff --git a/design/src/main/java/it/inps/sirio/ui/filter/SirioFilterTabs.kt b/design/src/main/java/it/inps/sirio/ui/filter/SirioFilterTabs.kt new file mode 100644 index 0000000..eedcda2 --- /dev/null +++ b/design/src/main/java/it/inps/sirio/ui/filter/SirioFilterTabs.kt @@ -0,0 +1,99 @@ +// +// SirioFilterTabs.kt +// +// SPDX-FileCopyrightText: 2022 Istituto Nazionale Previdenza Sociale +// +// SPDX-License-Identifier: BSD-3-Clause +// +package it.inps.sirio.ui.filter + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.tooling.preview.Preview +import com.guru.fontawesomecomposelib.FaIcons +import it.inps.sirio.theme.SirioTheme +import it.inps.sirio.ui.button.ButtonSize +import it.inps.sirio.ui.button.ButtonStyle +import it.inps.sirio.ui.button.SirioButton +import it.inps.sirio.ui.tabs.SirioTabGroupCommon +import it.inps.sirio.ui.tabs.TabItemData +import it.inps.sirio.ui.tabs.TabSelectionIndicatorPosition + +/** + * A composable function that displays a row of tabs for filtering. + * + * @param items The list of tab data to display. + * @param selectedIndex The index of the currently selected tab. + * @param withScroll Whether to display scroll buttons for navigating between tabs. + * @param onTabSelected The callback to be invoked when a tab is selected. + */ +@Composable +fun SirioFilterTabs( + items: List, + selectedIndex: Int = 0, + withScroll: Boolean = false, + onTabSelected: (Int) -> Unit, +) { + Row( + modifier = Modifier + .fillMaxWidth() + .background(SirioTheme.colors.filter.background), + verticalAlignment = Alignment.Bottom, + ) { + if (withScroll) { + SirioButton( + size = ButtonSize.Medium, + style = ButtonStyle.Ghost, + icon = FaIcons.ChevronLeft, + enabled = selectedIndex != 0, + onClick = { onTabSelected(selectedIndex - 1) } + ) + } + SirioTabGroupCommon( + items = items, + selectedIndex = selectedIndex, + selection = TabSelectionIndicatorPosition.TOP, + modifier = Modifier.weight(1f), + onTabSelected = onTabSelected, + ) + if (withScroll) { + SirioButton( + size = ButtonSize.Medium, + style = ButtonStyle.Ghost, + icon = FaIcons.ChevronRight, + enabled = selectedIndex != items.lastIndex, + onClick = { onTabSelected(selectedIndex + 1) } + ) + } + } +} + +@Preview +@Composable +private fun SirioFilterTabsPreview() { + SirioTheme { + Column { + SirioFilterTabs( + items = listOf( + TabItemData("Label tab"), + TabItemData("Label tab"), + ), + onTabSelected = {}, + ) + SirioFilterTabs( + items = listOf( + TabItemData("Label tab"), + TabItemData("Label tab"), + ), + selectedIndex = 1, + onTabSelected = {}, + withScroll = true, + ) + } + } +} \ No newline at end of file diff --git a/design/src/main/java/it/inps/sirio/ui/filter/SirioFilterTitle.kt b/design/src/main/java/it/inps/sirio/ui/filter/SirioFilterTitle.kt new file mode 100644 index 0000000..fcc982d --- /dev/null +++ b/design/src/main/java/it/inps/sirio/ui/filter/SirioFilterTitle.kt @@ -0,0 +1,72 @@ +// +// SirioFilterTitle.kt +// +// SPDX-FileCopyrightText: 2022 Istituto Nazionale Previdenza Sociale +// +// SPDX-License-Identifier: BSD-3-Clause +// +package it.inps.sirio.ui.filter + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.guru.fontawesomecomposelib.FaIcons +import it.inps.sirio.theme.SirioTheme +import it.inps.sirio.theme.filterInfoPadding +import it.inps.sirio.theme.filterInfoSize +import it.inps.sirio.theme.filterPadding +import it.inps.sirio.ui.text.SirioTextCommon +import it.inps.sirio.utils.SirioIcon + +/** + * A title component for filter sections. + * + * @param text The text to display as the title. + */ +@Composable +fun SirioFilterTitle( + text: String, + onInfoClick: (() -> Unit)? = null, +) { + Row( + modifier = Modifier + .fillMaxWidth() + .background(SirioTheme.colors.filter.background) + .padding(filterPadding.dp), + verticalAlignment = Alignment.CenterVertically, + ) { + SirioTextCommon( + text = text, + color = SirioTheme.colors.filter.title, + typography = SirioTheme.typography.filter.title, + ) + onInfoClick?.let { + Spacer(modifier = Modifier.width(filterInfoPadding.dp)) + SirioIcon( + faIcon = FaIcons.InfoCircle, + iconColor = SirioTheme.colors.filter.info, + size = filterInfoSize.dp, + onclick = onInfoClick, + ) + } + } +} + +@Preview +@Composable +private fun SirioFilterTitlePreview() { + SirioTheme { + Column { + SirioFilterTitle(text = "Section Title #") + } + } +} \ No newline at end of file diff --git a/design/src/main/java/it/inps/sirio/ui/filter/SirioFilterToggle.kt b/design/src/main/java/it/inps/sirio/ui/filter/SirioFilterToggle.kt new file mode 100644 index 0000000..946dadc --- /dev/null +++ b/design/src/main/java/it/inps/sirio/ui/filter/SirioFilterToggle.kt @@ -0,0 +1,84 @@ +// +// SirioFilterToggle.kt +// +// SPDX-FileCopyrightText: 2022 Istituto Nazionale Previdenza Sociale +// +// SPDX-License-Identifier: BSD-3-Clause +// +package it.inps.sirio.ui.filter + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import it.inps.sirio.theme.SirioTheme +import it.inps.sirio.theme.filterPadding +import it.inps.sirio.ui.toggle.SirioToggleCommon + +/** + * A filter toggle component. + * + * @param isOn Whether the toggle is currently on. + * @param text The text to display next to the toggle. + * @param enabled Whether the toggle is enabled. + * @param onToggleChange The callback to be invoked when the toggle state changes. + */ +@Composable +fun SirioFilterToggle( + isOn: Boolean, + text: String? = null, + enabled: Boolean = true, + onToggleChange: (Boolean) -> Unit, +) { + Box( + modifier = Modifier + .background(SirioTheme.colors.filter.background) + .padding(filterPadding.dp) + ) { + SirioToggleCommon( + isOn = isOn, + modifier = Modifier.fillMaxWidth(), + text = text, + enabled = enabled, + onToggleChange = onToggleChange, + ) + } +} + +@Preview +@Composable +private fun SirioFilterTogglePreview() { + SirioTheme { + Column { + SirioFilterToggle( + isOn = false, + text = "Title", + enabled = true, + onToggleChange = {}, + ) + SirioFilterToggle( + isOn = true, + text = "Title", + enabled = true, + onToggleChange = {}, + ) + SirioFilterToggle( + isOn = false, + text = "Title", + enabled = false, + onToggleChange = {}, + ) + SirioFilterToggle( + isOn = true, + text = "Title", + enabled = false, + onToggleChange = {}, + ) + } + } +} \ No newline at end of file diff --git a/design/src/main/java/it/inps/sirio/ui/menuspalla/SirioMenuSpalla.kt b/design/src/main/java/it/inps/sirio/ui/menuspalla/SirioMenuSpalla.kt new file mode 100644 index 0000000..9ef962d --- /dev/null +++ b/design/src/main/java/it/inps/sirio/ui/menuspalla/SirioMenuSpalla.kt @@ -0,0 +1,319 @@ +// +// SirioMenuSpalla.kt +// +// SPDX-FileCopyrightText: 2022 Istituto Nazionale Previdenza Sociale +// +// SPDX-License-Identifier: BSD-3-Clause +// +package it.inps.sirio.ui.menuspalla + +import android.util.Log +import androidx.annotation.Keep +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Column +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.Stable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.tooling.preview.Preview +import it.inps.sirio.theme.SirioTheme + +@Composable +fun SirioMenuSpalla( + title: String, + subtitle: String, + sections: List, + open: Boolean = false, + onStateChange: (open: Boolean) -> Unit, +) { + LaunchedEffect(sections) { + sections.any { section -> section.items.any { item -> item.hasInvalidDeep() } } + .let { if (it) throw IllegalArgumentException("Menu spalla invalid deep > 3") } + } + var isOpen by remember { mutableStateOf(open) } + var selectedId by remember { mutableStateOf("") } + Column(modifier = Modifier.background(SirioTheme.colors.menuSpalla.background)) { + SirioMenuSpallaDrawerItem( + title = title, + subtitle = subtitle, + open = isOpen, + onStateChange = { newOpenState -> + if (newOpenState.not()) selectedId = "" + isOpen = newOpenState + onStateChange(newOpenState) + } + ) + if (isOpen) { + sections.forEach { + SirioMenuSpallaSection( + title = it.title, + items = it.items, + selectedId = selectedId, + onChildSelected = { newSelectedId -> selectedId = newSelectedId } + ) + } + } + } +} + +@Preview +@Composable +private fun SirioMenuSpallaPreview() { + SirioTheme { + SirioMenuSpalla( + title = "Title", + subtitle = "Subtitle", + sections = listOf( + SirioMenuSpallaSectionItemData( + title = "Titolo sezione", + items = listOf( + SirioMenuSpallaItemData( + title = "Label tag", + tag = "3", + onClick = { + Log.d( + "SirioMenuSpallaPreview", + "SirioMenuSpallaPreview: label tag" + ) + }, + ), + SirioMenuSpallaItemData( + title = "Label 1", + tag = "1", + children = listOf( + SirioMenuSpallaItemData( + title = "Label 1.1", + tag = "1.1", + onClick = { + Log.d( + "SirioMenuSpallaPreview", + "SirioMenuSpallaPreview: label 1.1" + ) + } + ), + SirioMenuSpallaItemData( + title = "Label 1.2", + tag = "1.2", + children = listOf( + SirioMenuSpallaItemData( + title = "Label 1.2.1", + tag = "1.2.1", + onClick = { + Log.d( + "SirioMenuSpallaPreview", + "SirioMenuSpallaPreview: label 1.2.1" + ) + } + ), + SirioMenuSpallaItemData( + title = "Label 1.2.2", + tag = "1.2.2", + onClick = { + Log.d( + "SirioMenuSpallaPreview", + "SirioMenuSpallaPreview: label 1.2.2" + ) + } + ) + ), + onClick = { + Log.d( + "SirioMenuSpallaPreview", + "SirioMenuSpallaPreview: label 1.2" + ) + } + ) + ), + onClick = { + Log.d( + "SirioMenuSpallaPreview", + "SirioMenuSpallaPreview: label 1" + ) + }, + ), + SirioMenuSpallaItemData( + title = "Label 2", + tag = "2", + children = listOf( + SirioMenuSpallaItemData( + title = "Label 2.1", + tag = "2.1", + onClick = { + Log.d( + "SirioMenuSpallaPreview", + "SirioMenuSpallaPreview: label 2.1" + ) + } + ) + ), + onClick = { + Log.d( + "SirioMenuSpallaPreview", + "SirioMenuSpallaPreview: label 2" + ) + }, + ), + SirioMenuSpallaItemData( + title = "Label 3", + onClick = { + Log.d( + "SirioMenuSpallaPreview", + "SirioMenuSpallaPreview: label 3" + ) + }, + ), + ), + ), + SirioMenuSpallaSectionItemData( + title = "Titolo sezione", + items = listOf( + SirioMenuSpallaItemData( + title = "Label tag", + tag = "3", + onClick = { + Log.d( + "SirioMenuSpallaPreview", + "SirioMenuSpallaPreview: label tag" + ) + }, + ), + SirioMenuSpallaItemData( + title = "Label 1", + tag = "1", + children = listOf( + SirioMenuSpallaItemData( + title = "Label 1.1", + tag = "1.1", + onClick = { + Log.d( + "SirioMenuSpallaPreview", + "SirioMenuSpallaPreview: label 1.1" + ) + } + ), + SirioMenuSpallaItemData( + title = "Label 1.2", + tag = "1.2", + children = listOf( + SirioMenuSpallaItemData( + title = "Label 1.2.1", + tag = "1.2.1", + onClick = { + Log.d( + "SirioMenuSpallaPreview", + "SirioMenuSpallaPreview: label 1.2.1" + ) + } + ), + SirioMenuSpallaItemData( + title = "Label 1.2.2", + tag = "1.2.2", + onClick = { + Log.d( + "SirioMenuSpallaPreview", + "SirioMenuSpallaPreview: label 1.2.2" + ) + } + ) + ), + onClick = { + Log.d( + "SirioMenuSpallaPreview", + "SirioMenuSpallaPreview: label 1.2" + ) + } + ) + ), + onClick = { + Log.d( + "SirioMenuSpallaPreview", + "SirioMenuSpallaPreview: label 1" + ) + }, + ), + SirioMenuSpallaItemData( + title = "Label 2", + tag = "2", + children = listOf( + SirioMenuSpallaItemData( + title = "Label 2.1", + tag = "2.1", + onClick = { + Log.d( + "SirioMenuSpallaPreview", + "SirioMenuSpallaPreview: label 2.1" + ) + } + ) + ), + onClick = { + Log.d( + "SirioMenuSpallaPreview", + "SirioMenuSpallaPreview: label 2" + ) + }, + ), + SirioMenuSpallaItemData( + title = "Label 3", + onClick = { + Log.d( + "SirioMenuSpallaPreview", + "SirioMenuSpallaPreview: label 3" + ) + }, + ), + ), + ) + + ), + onStateChange = {}, + ) + } +} + +@Keep +data class SirioMenuSpallaColors( + val background: Color, + val drawerItem: SirioMenuSpallaDrawerItemColors, + val drawerItemInfo: SirioMenuSpallaDrawerItemInfoColors, + val itemTitleSection: SirioMenuSpallaItemTitleSectionColors, + val itemPrimary: SirioMenuSpallaItemColors, + val itemSecondary: SirioMenuSpallaItemColors, + val itemTertiary: SirioMenuSpallaItemColors, +) { + companion object { + @Stable + val Unspecified = SirioMenuSpallaColors( + background = Color.Unspecified, + drawerItem = SirioMenuSpallaDrawerItemColors.Unspecified, + drawerItemInfo = SirioMenuSpallaDrawerItemInfoColors.Unspecified, + itemTitleSection = SirioMenuSpallaItemTitleSectionColors.Unspecified, + itemPrimary = SirioMenuSpallaItemColors.Unspecified, + itemSecondary = SirioMenuSpallaItemColors.Unspecified, + itemTertiary = SirioMenuSpallaItemColors.Unspecified, + ) + } +} + +@Keep +data class SirioMenuSpallaTypography( + val drawerItem: SirioMenuSpallaDrawerItemTypography, + val drawerItemInfo: SirioMenuSpallaDrawerItemInfoTypography, + val itemTitleSection: SirioMenuSpallaItemTitleSectionTypography, + val item: SirioMenuSpallaItemTypography, +) { + companion object { + @Stable + val Default = SirioMenuSpallaTypography( + drawerItem = SirioMenuSpallaDrawerItemTypography.Default, + drawerItemInfo = SirioMenuSpallaDrawerItemInfoTypography.Default, + itemTitleSection = SirioMenuSpallaItemTitleSectionTypography.Default, + item = SirioMenuSpallaItemTypography.Default, + ) + } +} \ No newline at end of file diff --git a/design/src/main/java/it/inps/sirio/ui/menuspalla/SirioMenuSpallaDrawerItem.kt b/design/src/main/java/it/inps/sirio/ui/menuspalla/SirioMenuSpallaDrawerItem.kt new file mode 100644 index 0000000..4ed36c3 --- /dev/null +++ b/design/src/main/java/it/inps/sirio/ui/menuspalla/SirioMenuSpallaDrawerItem.kt @@ -0,0 +1,158 @@ +// +// SirioMenuSpallaDrawerItem.kt +// +// SPDX-FileCopyrightText: 2022 Istituto Nazionale Previdenza Sociale +// +// SPDX-License-Identifier: BSD-3-Clause +// +package it.inps.sirio.ui.menuspalla + +import androidx.annotation.Keep +import androidx.compose.foundation.BorderStroke +import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.foundation.interaction.collectIsFocusedAsState +import androidx.compose.foundation.interaction.collectIsHoveredAsState +import androidx.compose.foundation.interaction.collectIsPressedAsState +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.LocalContentColor +import androidx.compose.material3.Surface +import androidx.compose.runtime.Composable +import androidx.compose.runtime.Stable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.remember +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.guru.fontawesomecomposelib.FaIcons +import it.inps.sirio.theme.SirioColorState +import it.inps.sirio.theme.SirioTheme +import it.inps.sirio.theme.menuSpallaDrawerItemBorderWidth +import it.inps.sirio.theme.menuSpallaDrawerItemHeight +import it.inps.sirio.theme.menuSpallaDrawerItemIconSize +import it.inps.sirio.theme.menuSpallaDrawerItemPaddingHorizontal +import it.inps.sirio.ui.text.SirioTextCommon +import it.inps.sirio.utils.SirioIcon + +@Composable +fun SirioMenuSpallaDrawerItem( + title: String, + subtitle: String, + open: Boolean, + onStateChange: (open: Boolean) -> Unit, +) { + val interactionSource = remember { MutableInteractionSource() } + val isPressed by interactionSource.collectIsPressedAsState() + val isFocused by interactionSource.collectIsFocusedAsState() + val isHovered by interactionSource.collectIsHoveredAsState() + + val backgroundColor: Color = SirioTheme.colors.menuSpalla.drawerItem.background + .get(disabled = false, focused = isFocused, pressed = isPressed, hovered = isHovered) + val contentColor: Color = SirioTheme.colors.menuSpalla.drawerItem.content + .get(disabled = false, focused = isFocused, pressed = isPressed, hovered = isHovered) + val borderColor: Color = SirioTheme.colors.menuSpalla.drawerItem.border + .get(disabled = false, focused = isFocused, pressed = isPressed, hovered = isHovered) + + val icon = if (open) FaIcons.Times else FaIcons.AngleUp + + Surface( + checked = open, + onCheckedChange = onStateChange, + modifier = Modifier + .height(menuSpallaDrawerItemHeight.dp) + .fillMaxWidth(), + color = backgroundColor, + contentColor = contentColor, + border = BorderStroke(menuSpallaDrawerItemBorderWidth.dp, borderColor), + interactionSource = interactionSource, + ) { + Row( + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = menuSpallaDrawerItemPaddingHorizontal.dp), + verticalAlignment = Alignment.CenterVertically, + ) { + Column { + SirioTextCommon( + text = title, + overflow = TextOverflow.Ellipsis, + maxLines = 1, + typography = SirioTheme.typography.menuSpalla.drawerItem.title, + ) + SirioTextCommon( + text = subtitle, + overflow = TextOverflow.Ellipsis, + maxLines = 1, + typography = SirioTheme.typography.menuSpalla.drawerItem.subtitle, + ) + } + Spacer(Modifier.weight(1f)) + SirioIcon( + faIcon = icon, + iconColor = LocalContentColor.current, + size = menuSpallaDrawerItemIconSize.dp, + ) + } + } +} + +@Keep +data class SirioMenuSpallaDrawerItemColors( + val background: SirioColorState, + val border: SirioColorState, + val content: SirioColorState, +) { + companion object { + @Stable + val Unspecified = SirioMenuSpallaDrawerItemColors( + background = SirioColorState.Unspecified, + border = SirioColorState.Unspecified, + content = SirioColorState.Unspecified, + ) + } +} + +@Keep +data class SirioMenuSpallaDrawerItemTypography( + val title: TextStyle, + val subtitle: TextStyle, +) { + companion object { + @Stable + val Default = SirioMenuSpallaDrawerItemTypography( + title = TextStyle.Default, + subtitle = TextStyle.Default, + ) + } +} + +@Preview +@Composable +private fun SirioMenuSpallaDrawerItemPreview() { + SirioTheme { + Column { + val title = "Action Label" + val subtitle = "Placeholder Label" + SirioMenuSpallaDrawerItem( + title = title, + subtitle = subtitle, + open = true, + onStateChange = {}, + ) + SirioMenuSpallaDrawerItem( + title = title, + subtitle = subtitle, + open = false, + onStateChange = {}, + ) + } + } +} \ No newline at end of file diff --git a/design/src/main/java/it/inps/sirio/ui/menuspalla/SirioMenuSpallaDrawerItemInfo.kt b/design/src/main/java/it/inps/sirio/ui/menuspalla/SirioMenuSpallaDrawerItemInfo.kt new file mode 100644 index 0000000..2759355 --- /dev/null +++ b/design/src/main/java/it/inps/sirio/ui/menuspalla/SirioMenuSpallaDrawerItemInfo.kt @@ -0,0 +1,130 @@ +// +// SirioMenuSpallaDrawerItemInfo.kt +// +// SPDX-FileCopyrightText: 2022 Istituto Nazionale Previdenza Sociale +// +// SPDX-License-Identifier: BSD-3-Clause +// +package it.inps.sirio.ui.menuspalla + +import androidx.annotation.Keep +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.material3.LocalContentColor +import androidx.compose.material3.Surface +import androidx.compose.runtime.Composable +import androidx.compose.runtime.Stable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.guru.fontawesomecomposelib.FaIconType +import com.guru.fontawesomecomposelib.FaIcons +import it.inps.sirio.theme.SirioTheme +import it.inps.sirio.theme.menuSpallaDrawerItemInfoBorderWidth +import it.inps.sirio.theme.menuSpallaDrawerItemInfoHeight +import it.inps.sirio.theme.menuSpallaDrawerItemInfoIconSize +import it.inps.sirio.theme.menuSpallaDrawerItemInfoPaddingHorizontal +import it.inps.sirio.ui.text.SirioTextCommon +import it.inps.sirio.utils.Border +import it.inps.sirio.utils.SirioIcon +import it.inps.sirio.utils.border + +@Composable +fun SirioMenuSpallaDrawerItemInfo( + title: String, + subtitle: String, + icon: FaIconType, +) { + Surface( + modifier = Modifier + .height(menuSpallaDrawerItemInfoHeight.dp) + .fillMaxWidth() + .border( + bottom = Border( + menuSpallaDrawerItemInfoBorderWidth.dp, + SirioTheme.colors.menuSpalla.drawerItemInfo.border, + ) + ), + color = SirioTheme.colors.menuSpalla.drawerItemInfo.background, + contentColor = SirioTheme.colors.menuSpalla.drawerItemInfo.content, + ) { + Row( + Modifier + .fillMaxWidth() + .padding(horizontal = menuSpallaDrawerItemInfoPaddingHorizontal.dp), + verticalAlignment = Alignment.CenterVertically, + ) { + SirioIcon( + faIcon = icon, + iconColor = LocalContentColor.current, + size = menuSpallaDrawerItemInfoIconSize.dp + ) + Spacer(modifier = Modifier.width(menuSpallaDrawerItemInfoPaddingHorizontal.dp)) + Column { + SirioTextCommon( + text = title, + overflow = TextOverflow.Ellipsis, + maxLines = 1, + typography = SirioTheme.typography.menuSpalla.drawerItemInfo.title, + ) + SirioTextCommon( + text = subtitle, + overflow = TextOverflow.Ellipsis, + maxLines = 1, + typography = SirioTheme.typography.menuSpalla.drawerItemInfo.subtitle, + ) + } + } + } +} + +@Keep +data class SirioMenuSpallaDrawerItemInfoColors( + val background: Color, + val border: Color, + val content: Color, +) { + companion object { + @Stable + val Unspecified = SirioMenuSpallaDrawerItemInfoColors( + background = Color.Unspecified, + border = Color.Unspecified, + content = Color.Unspecified, + ) + } +} + +@Keep +data class SirioMenuSpallaDrawerItemInfoTypography( + val title: TextStyle, + val subtitle: TextStyle, +) { + companion object { + @Stable + val Default = SirioMenuSpallaDrawerItemInfoTypography( + title = TextStyle.Default, + subtitle = TextStyle.Default, + ) + } +} + +@Preview +@Composable +private fun SirioMenuSpallaDrawerItemInfoPreview() { + SirioTheme { + SirioMenuSpallaDrawerItemInfo( + title = "Mario Rossi", + subtitle = "Profilo Cittadino", + icon = FaIcons.User, + ) + } +} \ No newline at end of file diff --git a/design/src/main/java/it/inps/sirio/ui/menuspalla/SirioMenuSpallaExpandableItem.kt b/design/src/main/java/it/inps/sirio/ui/menuspalla/SirioMenuSpallaExpandableItem.kt new file mode 100644 index 0000000..846e581 --- /dev/null +++ b/design/src/main/java/it/inps/sirio/ui/menuspalla/SirioMenuSpallaExpandableItem.kt @@ -0,0 +1,49 @@ +package it.inps.sirio.ui.menuspalla + +import androidx.compose.foundation.layout.ColumnScope +import androidx.compose.runtime.Composable +import androidx.compose.runtime.derivedStateOf +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember + +@Composable +fun ColumnScope.SirioMenuSpallaExpandableItem( + item: SirioMenuSpallaItemData, + level: Int, + selectedId: String, + parentId: String, + onClick: (id: String) -> Unit, +) { + val hasChildred = item.children.isNotEmpty() + val isSelected by remember(selectedId) { derivedStateOf { item.hasChild(selectedId) } } + val isExpanded by remember(hasChildred, isSelected) + { mutableStateOf(hasChildred && isSelected) } + SirioMenuSpallaItem( + title = item.title, + level = SirioMenuSpallaItemLevel.fromInt(level), + tagText = item.tag, + selected = isSelected, + enabled = item.enabled, + hasSubItems = hasChildred, + onClick = { + if (isSelected && isExpanded) { + onClick(parentId) + } else { + onClick(item.id) + } + item.onClick() + }, + ) + if (isExpanded) { + item.children.forEach { child -> + SirioMenuSpallaExpandableItem( + item = child, + level = level + 1, + selectedId = selectedId, + parentId = item.id, + onClick = onClick, + ) + } + } +} \ No newline at end of file diff --git a/design/src/main/java/it/inps/sirio/ui/menuspalla/SirioMenuSpallaItem.kt b/design/src/main/java/it/inps/sirio/ui/menuspalla/SirioMenuSpallaItem.kt new file mode 100644 index 0000000..5374b28 --- /dev/null +++ b/design/src/main/java/it/inps/sirio/ui/menuspalla/SirioMenuSpallaItem.kt @@ -0,0 +1,330 @@ +// +// SirioMenuSpallaItem.kt +// +// SPDX-FileCopyrightText: 2022 Istituto Nazionale Previdenza Sociale +// +// SPDX-License-Identifier: BSD-3-Clause +// +package it.inps.sirio.ui.menuspalla + +import androidx.annotation.Keep +import androidx.compose.foundation.BorderStroke +import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.foundation.interaction.collectIsFocusedAsState +import androidx.compose.foundation.interaction.collectIsHoveredAsState +import androidx.compose.foundation.interaction.collectIsPressedAsState +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.LocalContentColor +import androidx.compose.material3.Surface +import androidx.compose.runtime.Composable +import androidx.compose.runtime.Stable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.remember +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.guru.fontawesomecomposelib.FaIcons +import it.inps.sirio.theme.SirioColorState +import it.inps.sirio.theme.SirioTheme +import it.inps.sirio.theme.menuSpallaItemBorderWidth +import it.inps.sirio.theme.menuSpallaItemDividerHeight +import it.inps.sirio.theme.menuSpallaItemHeight +import it.inps.sirio.theme.menuSpallaItemIndicatorWidth +import it.inps.sirio.theme.menuSpallaItemPaddingEnd +import it.inps.sirio.theme.menuSpallaItemPrimaryPaddingStart +import it.inps.sirio.theme.menuSpallaItemSecondaryPaddingStart +import it.inps.sirio.theme.menuSpallaItemTertiaryPaddingStart +import it.inps.sirio.ui.tag.SirioTagColors +import it.inps.sirio.ui.tag.SirioTagCommon +import it.inps.sirio.ui.text.SirioTextCommon +import it.inps.sirio.utils.Border +import it.inps.sirio.utils.SirioIcon +import it.inps.sirio.utils.border +import it.inps.sirio.utils.ifElse + +@Composable +fun SirioMenuSpallaItem( + title: String, + level: SirioMenuSpallaItemLevel, + tagText: String? = null, + selected: Boolean = false, + enabled: Boolean = true, + hasSubItems: Boolean = false, + onClick: () -> Unit, +) { + val interactionSource = remember { MutableInteractionSource() } + val pressed by interactionSource.collectIsPressedAsState() + val isFocused by interactionSource.collectIsFocusedAsState() + val isHovered by interactionSource.collectIsHoveredAsState() + val isPressed = pressed || selected + + val itemColors = when (level) { + SirioMenuSpallaItemLevel.FIRST -> SirioTheme.colors.menuSpalla.itemPrimary + SirioMenuSpallaItemLevel.SECOND -> SirioTheme.colors.menuSpalla.itemSecondary + SirioMenuSpallaItemLevel.THIRD -> SirioTheme.colors.menuSpalla.itemTertiary + } + val paddingStart = when (level) { + SirioMenuSpallaItemLevel.FIRST -> menuSpallaItemPrimaryPaddingStart + SirioMenuSpallaItemLevel.SECOND -> menuSpallaItemSecondaryPaddingStart + SirioMenuSpallaItemLevel.THIRD -> menuSpallaItemTertiaryPaddingStart + } + + val backgroundColor: Color = itemColors.background + .get( + disabled = enabled.not(), + focused = isFocused, + pressed = isPressed, + hovered = isHovered + ) + val contentColor: Color = itemColors.content + .get( + disabled = enabled.not(), + focused = isFocused, + pressed = isPressed, + hovered = isHovered + ) + val borderColor: Color = itemColors.border + .get( + disabled = enabled.not(), + focused = isFocused, + pressed = isPressed, + hovered = isHovered + ) + val indicatorColor: Color = itemColors.indicator + .get( + disabled = enabled.not(), + focused = isFocused, + pressed = isPressed, + hovered = isHovered + ) + val dividerColor: Color = itemColors.divider + .get( + disabled = enabled.not(), + focused = isFocused, + pressed = isPressed, + hovered = isHovered + ) + + val hasArrow = level != SirioMenuSpallaItemLevel.THIRD && hasSubItems + + val hasTag = hasArrow.not() + && level == SirioMenuSpallaItemLevel.FIRST + && tagText.isNullOrBlank().not() + + val hasDivider = dividerColor != Color.Unspecified + + val hasIndicator = indicatorColor != Color.Unspecified && (hasArrow && isPressed).not() + + Surface( + checked = selected, + onCheckedChange = { onClick() }, + modifier = Modifier + .height(menuSpallaItemHeight.dp) + .fillMaxWidth() + .ifElse( + condition = hasDivider, + ifTrueModifier = Modifier.border( + top = Border( + menuSpallaItemDividerHeight.dp, + dividerColor, + ) + ) + ) + .ifElse( + condition = hasIndicator, + ifTrueModifier = Modifier.border( + start = Border( + menuSpallaItemIndicatorWidth.dp, + indicatorColor, + ) + ) + ), + enabled = enabled, + color = backgroundColor, + contentColor = contentColor, + border = BorderStroke(width = menuSpallaItemBorderWidth.dp, color = borderColor), + interactionSource = interactionSource, + ) { + Row( + modifier = Modifier + .fillMaxWidth() + .padding(start = paddingStart.dp, end = menuSpallaItemPaddingEnd.dp), + verticalAlignment = Alignment.CenterVertically, + ) { + SirioTextCommon( + text = title, + modifier = Modifier.weight(1f), + overflow = TextOverflow.Ellipsis, + maxLines = 1, + typography = SirioTheme.typography.menuSpalla.item.title, + ) + if (hasTag) { + val tagColors = + if (enabled) SirioTheme.colors.menuSpalla.itemPrimary.tag + else SirioTheme.colors.menuSpalla.itemPrimary.tagDisabled + SirioTagCommon( + text = tagText!!, + colors = tagColors + ) + } + if (hasArrow) { + val icon = if (selected) FaIcons.AngleUp else FaIcons.AngleDown + SirioIcon( + faIcon = icon, + iconColor = LocalContentColor.current + ) + } + } + } +} + +enum class SirioMenuSpallaItemLevel { + FIRST, + SECOND, + THIRD; + + companion object { + fun fromInt(value: Int): SirioMenuSpallaItemLevel = when (value) { + 0 -> FIRST + 1 -> SECOND + 2 -> THIRD + else -> throw IllegalArgumentException("Invalid value: $value") + } + } +} + +@Keep +data class SirioMenuSpallaItemColors( + val background: SirioColorState, + val border: SirioColorState, + val indicator: SirioColorState, + val divider: SirioColorState, + val content: SirioColorState, + val tag: SirioTagColors = SirioTagColors.Unspecified, + val tagDisabled: SirioTagColors = SirioTagColors.Unspecified, +) { + companion object { + @Stable + val Unspecified = SirioMenuSpallaItemColors( + background = SirioColorState.Unspecified, + border = SirioColorState.Unspecified, + indicator = SirioColorState.Unspecified, + divider = SirioColorState.Unspecified, + content = SirioColorState.Unspecified, + tag = SirioTagColors.Unspecified, + tagDisabled = SirioTagColors.Unspecified, + ) + } +} + +@Keep +data class SirioMenuSpallaItemTypography( + val title: TextStyle, +) { + companion object { + @Stable + val Default = SirioMenuSpallaItemTypography( + title = TextStyle.Default, + ) + } +} + +@Preview +@Composable +private fun SirioMenuSpallaItemPreview() { + SirioTheme { + Column { + SirioMenuSpallaItem( + title = "Label", + level = SirioMenuSpallaItemLevel.FIRST, + tagText = "3", + enabled = true, + onClick = {}, + ) + SirioMenuSpallaItem( + title = "Label", + level = SirioMenuSpallaItemLevel.FIRST, + tagText = "3", + hasSubItems = true, + enabled = true, + onClick = {}, + ) + SirioMenuSpallaItem( + title = "Label", + level = SirioMenuSpallaItemLevel.FIRST, + tagText = "3", + selected = true, + hasSubItems = true, + enabled = true, + onClick = {}, + ) + SirioMenuSpallaItem( + title = "Label", + level = SirioMenuSpallaItemLevel.FIRST, + tagText = "3", + selected = true, + enabled = true, + onClick = {}, + ) + SirioMenuSpallaItem( + title = "Label", + level = SirioMenuSpallaItemLevel.FIRST, + tagText = "3", + enabled = false, + onClick = {}, + ) + SirioMenuSpallaItem( + title = "Label", + level = SirioMenuSpallaItemLevel.SECOND, + tagText = "3", + enabled = true, + onClick = {}, + ) + SirioMenuSpallaItem( + title = "Label", + level = SirioMenuSpallaItemLevel.SECOND, + tagText = "3", + selected = true, + enabled = true, + onClick = {}, + ) + SirioMenuSpallaItem( + title = "Label", + level = SirioMenuSpallaItemLevel.SECOND, + tagText = "3", + enabled = false, + onClick = {}, + ) + SirioMenuSpallaItem( + title = "Label", + level = SirioMenuSpallaItemLevel.THIRD, + tagText = "3", + enabled = true, + onClick = {}, + ) + SirioMenuSpallaItem( + title = "Label", + level = SirioMenuSpallaItemLevel.THIRD, + tagText = "3", + selected = true, + enabled = true, + onClick = {}, + ) + SirioMenuSpallaItem( + title = "Label", + level = SirioMenuSpallaItemLevel.THIRD, + tagText = "3", + enabled = false, + onClick = {}, + ) + } + } +} \ No newline at end of file diff --git a/design/src/main/java/it/inps/sirio/ui/menuspalla/SirioMenuSpallaItemData.kt b/design/src/main/java/it/inps/sirio/ui/menuspalla/SirioMenuSpallaItemData.kt new file mode 100644 index 0000000..7a3d13a --- /dev/null +++ b/design/src/main/java/it/inps/sirio/ui/menuspalla/SirioMenuSpallaItemData.kt @@ -0,0 +1,35 @@ +package it.inps.sirio.ui.menuspalla + +import androidx.annotation.Keep +import java.util.UUID + +@Keep +data class SirioMenuSpallaItemData( + val title: String, + val tag: String = "", + val enabled: Boolean = true, + val children: List = emptyList(), + val onClick: () -> Unit, +) { + val id: String = UUID.randomUUID().toString() + + fun hasChild(childId: String): Boolean { + if (this.id == childId) return true + + for (item in this.children) { + if (item.id == childId) return true + if (item.hasChild(childId)) return true + } + + return false + } +} + +fun SirioMenuSpallaItemData.hasInvalidDeep(): Boolean { + fun checkDepth(item: SirioMenuSpallaItemData, currentDepth: Int): Boolean { + if (currentDepth > 2) return true + if (item.children.isEmpty()) return false + return item.children.any { checkDepth(it, currentDepth + 1) } + } + return checkDepth(this, 0) +} \ No newline at end of file diff --git a/design/src/main/java/it/inps/sirio/ui/menuspalla/SirioMenuSpallaItemTitleSection.kt b/design/src/main/java/it/inps/sirio/ui/menuspalla/SirioMenuSpallaItemTitleSection.kt new file mode 100644 index 0000000..a5b5974 --- /dev/null +++ b/design/src/main/java/it/inps/sirio/ui/menuspalla/SirioMenuSpallaItemTitleSection.kt @@ -0,0 +1,88 @@ +package it.inps.sirio.ui.menuspalla + +import androidx.annotation.Keep +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.Surface +import androidx.compose.runtime.Composable +import androidx.compose.runtime.Stable +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import it.inps.sirio.theme.SirioTheme +import it.inps.sirio.theme.menuSpallaItemTitleSectionBorderWidth +import it.inps.sirio.theme.menuSpallaItemTitleSectionHeight +import it.inps.sirio.theme.menuSpallaItemTitleSectionPaddingHorizontal +import it.inps.sirio.theme.menuSpallaItemTitleSectionPaddingTop +import it.inps.sirio.ui.text.SirioTextCommon +import it.inps.sirio.utils.Border +import it.inps.sirio.utils.border + +@Composable +fun SirioMenuSpallaItemTitleSection( + title: String, +) { + Surface( + modifier = Modifier + .fillMaxWidth() + .height(menuSpallaItemTitleSectionHeight.dp) + .border( + bottom = Border( + menuSpallaItemTitleSectionBorderWidth.dp, + SirioTheme.colors.menuSpalla.itemTitleSection.border, + ) + ), + color = SirioTheme.colors.menuSpalla.itemTitleSection.background, + contentColor = SirioTheme.colors.menuSpalla.itemTitleSection.content, + ) { + SirioTextCommon( + text = title, + modifier = Modifier + .padding(horizontal = menuSpallaItemTitleSectionPaddingHorizontal.dp) + .padding(top = menuSpallaItemTitleSectionPaddingTop.dp), + overflow = TextOverflow.Ellipsis, + maxLines = 1, + typography = SirioTheme.typography.menuSpalla.itemTitleSection.title, + ) + } +} + +@Keep +data class SirioMenuSpallaItemTitleSectionColors( + val background: Color, + val border: Color, + val content: Color, +) { + companion object { + @Stable + val Unspecified = SirioMenuSpallaItemTitleSectionColors( + background = Color.Unspecified, + border = Color.Unspecified, + content = Color.Unspecified, + ) + } +} + +@Keep +data class SirioMenuSpallaItemTitleSectionTypography( + val title: TextStyle, +) { + companion object { + @Stable + val Default = SirioMenuSpallaItemTitleSectionTypography( + title = TextStyle.Default, + ) + } +} + +@Preview(showBackground = true) +@Composable +private fun SirioMenuSpallaItemTitleSectionPreview() { + SirioTheme { + SirioMenuSpallaItemTitleSection("Label menu") + } +} \ No newline at end of file diff --git a/design/src/main/java/it/inps/sirio/ui/menuspalla/SirioMenuSpallaSection.kt b/design/src/main/java/it/inps/sirio/ui/menuspalla/SirioMenuSpallaSection.kt new file mode 100644 index 0000000..2a60f79 --- /dev/null +++ b/design/src/main/java/it/inps/sirio/ui/menuspalla/SirioMenuSpallaSection.kt @@ -0,0 +1,31 @@ +package it.inps.sirio.ui.menuspalla + +import androidx.compose.foundation.layout.ColumnScope +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.height +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import it.inps.sirio.theme.menuSpallaSectionPaddingTop + +@Composable +fun ColumnScope.SirioMenuSpallaSection( + title: String?, + items: List, + selectedId: String, + onChildSelected: (String) -> Unit, +) { + title?.let { + Spacer(modifier = Modifier.height(menuSpallaSectionPaddingTop.dp)) + SirioMenuSpallaItemTitleSection(title = it) + } + items.forEach { item -> + SirioMenuSpallaExpandableItem( + item = item, + level = 0, + selectedId = selectedId, + parentId = "", + onClick = { onChildSelected(it) }, + ) + } +} \ No newline at end of file diff --git a/design/src/main/java/it/inps/sirio/ui/menuspalla/SirioMenuSpallaSectionItemData.kt b/design/src/main/java/it/inps/sirio/ui/menuspalla/SirioMenuSpallaSectionItemData.kt new file mode 100644 index 0000000..333b5cb --- /dev/null +++ b/design/src/main/java/it/inps/sirio/ui/menuspalla/SirioMenuSpallaSectionItemData.kt @@ -0,0 +1,9 @@ +package it.inps.sirio.ui.menuspalla + +import androidx.annotation.Keep + +@Keep +data class SirioMenuSpallaSectionItemData( + val title: String? = null, + val items: List, +) \ No newline at end of file diff --git a/design/src/main/java/it/inps/sirio/ui/notification/NotificationCommon.kt b/design/src/main/java/it/inps/sirio/ui/notification/NotificationCommon.kt index c2a2637..71c85ed 100644 --- a/design/src/main/java/it/inps/sirio/ui/notification/NotificationCommon.kt +++ b/design/src/main/java/it/inps/sirio/ui/notification/NotificationCommon.kt @@ -8,9 +8,158 @@ package it.inps.sirio.ui.notification +import androidx.annotation.Keep +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.IntrinsicSize +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.material3.IconButton import androidx.compose.runtime.Composable +import androidx.compose.runtime.Immutable +import androidx.compose.runtime.Stable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.semantics.CustomAccessibilityAction +import androidx.compose.ui.semantics.Role +import androidx.compose.ui.semantics.customActions +import androidx.compose.ui.semantics.semantics +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.guru.fontawesomecomposelib.FaIconType import com.guru.fontawesomecomposelib.FaIcons import it.inps.sirio.theme.SirioTheme +import it.inps.sirio.theme.notificationInlineCloseSize +import it.inps.sirio.theme.notificationInlineIconPaddingTop +import it.inps.sirio.theme.notificationInlineIconSize +import it.inps.sirio.theme.notificationInlinePaddingHorizontal +import it.inps.sirio.theme.notificationInlinePaddingVertical +import it.inps.sirio.theme.notificationInlineSpacerVertical +import it.inps.sirio.theme.notificationInlineStateWidth +import it.inps.sirio.ui.button.ButtonSize +import it.inps.sirio.ui.button.ButtonStyle +import it.inps.sirio.ui.button.SirioButton +import it.inps.sirio.ui.text.SirioText +import it.inps.sirio.ui.text.SirioTextCommon +import it.inps.sirio.utils.SirioIcon + +/** + * Inline notification implementation with an icon on the left and the state color, + * a title and a text in column and the close button + * + * @param title The notification title + * @param text The notification text + * @param icon The notification icon, placed on the left + * @param link The notification link, if any + * @param buttonText The string inside the action button + * @param stateColor The notification state color + * @param closeContentDescription The content description of the close button + * @param onAction The callback when the action button is pressed + * @param onClose The callback when the close button is pressed + */ +@Composable +internal fun NotificationCommon( + title: String, + text: String, + icon: FaIconType, + link: String? = null, + buttonText: String? = null, + stateColor: Color, + closeContentDescription: String? = null, + onLink: (() -> Unit)? = null, + onAction: (() -> Unit)? = null, + onClose: () -> Unit, +) { + Row( + Modifier + .height(IntrinsicSize.Min) + .background(color = SirioTheme.colors.notificationColors.background) + .semantics(mergeDescendants = true) { + customActions = listOf( + CustomAccessibilityAction( + label = title + text, + action = { + onClose() + true + } + ) + ) + }, + verticalAlignment = Alignment.Top, + ) { + Box( + Modifier + .width(notificationInlineStateWidth.dp) + .fillMaxHeight() + .background(color = stateColor) + .padding(top = notificationInlineIconPaddingTop.dp), + contentAlignment = Alignment.TopCenter, + ) { + SirioIcon( + faIcon = icon, + size = notificationInlineIconSize.dp, + iconColor = SirioTheme.colors.notificationColors.icon, + ) + } + Column( + modifier = Modifier + .weight(1f) + .padding( + start = notificationInlinePaddingHorizontal.dp, + top = notificationInlinePaddingVertical.dp, + bottom = notificationInlinePaddingVertical.dp, + ) + ) { + SirioTextCommon( + text = title, + color = SirioTheme.colors.notificationColors.title, + maxLines = 1, + typography = SirioTheme.typography.notification.title, + ) + Spacer(modifier = Modifier.height(notificationInlineSpacerVertical.dp)) + SirioTextCommon( + text = text, + color = SirioTheme.colors.notificationColors.text, + maxLines = 2, + typography = SirioTheme.typography.notification.text, + ) + if (!link.isNullOrEmpty() && onLink != null) { + Spacer(modifier = Modifier.height(notificationInlineSpacerVertical.dp)) + SirioText( + text = link, + modifier = Modifier.clickable(role = Role.Button, onClick = onLink), + color = SirioTheme.colors.notificationColors.link, + typography = SirioTheme.typography.notification.link, + ) + } + if (!buttonText.isNullOrEmpty() && onAction != null) { + Spacer(modifier = Modifier.height(notificationInlineSpacerVertical.dp)) + SirioButton( + text = buttonText, + onClick = onAction, + size = ButtonSize.Large, + style = ButtonStyle.Tertiary + ) + } + } + IconButton(onClick = onClose) { + SirioIcon( + faIcon = FaIcons.Times, + size = notificationInlineCloseSize.dp, + iconColor = SirioTheme.colors.notificationColors.icon, + contentDescription = closeContentDescription, + ) + } + } +} /** * Each type has proper icon and colors @@ -22,14 +171,17 @@ internal fun paramsByType(type: NotificationType) = FaIcons.ExclamationTriangle, SirioTheme.colors.notificationColors.alert ) + NotificationType.Info -> Pair( - FaIcons.ExclamationCircle, + FaIcons.InfoCircle, SirioTheme.colors.notificationColors.info ) + NotificationType.Warning -> Pair( FaIcons.ExclamationCircle, SirioTheme.colors.notificationColors.warning ) + NotificationType.Success -> Pair( FaIcons.Check, SirioTheme.colors.notificationColors.success @@ -44,4 +196,184 @@ enum class NotificationType { Info, Warning, Success -} \ No newline at end of file +} + +@Keep +data class SirioNotificationTypography( + val title: TextStyle, + val text: TextStyle, + val link: TextStyle, +) { + companion object { + @Stable + val Default = SirioNotificationTypography( + title = TextStyle.Default, + text = TextStyle.Default, + link = TextStyle.Default, + ) + } +} + +@Keep +@Immutable +data class NotificationColors( + val background: Color, + val title: Color, + val text: Color, + val link: Color, + val icon: Color, + val close: Color, + val alert: Color, + val info: Color, + val warning: Color, + val success: Color, +) { + companion object { + @Stable + val Unspecified = NotificationColors( + background = Color.Unspecified, + title = Color.Unspecified, + text = Color.Unspecified, + link = Color.Unspecified, + icon = Color.Unspecified, + close = Color.Unspecified, + alert = Color.Unspecified, + info = Color.Unspecified, + warning = Color.Unspecified, + success = Color.Unspecified, + ) + } +} + +@Preview +@Composable +private fun NotificationInlineCommonPreview() { + SirioTheme { + Column(Modifier.background(Color(0xFFE5E5E5))) { + val text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit." + NotificationCommon( + title = "Titolo di Errore", + text = text, + icon = FaIcons.ExclamationTriangle, + stateColor = SirioTheme.colors.notificationColors.alert, + ) {} + NotificationCommon( + title = "Titolo Informativo", + text = text, + icon = FaIcons.InfoCircle, + stateColor = SirioTheme.colors.notificationColors.info, + ) {} + NotificationCommon( + title = "Titolo di Avviso", + text = text, + icon = FaIcons.ExclamationCircle, + stateColor = SirioTheme.colors.notificationColors.warning, + ) {} + NotificationCommon( + title = "Titolo Successo", + text = text, + icon = FaIcons.Check, + stateColor = SirioTheme.colors.notificationColors.success, + ) {} + } + } +} + +@Preview +@Composable +private fun NotificationToastCommonPreview() { + SirioTheme(darkTheme = true) { + Column(Modifier.background(Color(0xFFE5E5E5))) { + val text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit." + val button = "Azione" + NotificationCommon( + title = "Titolo di Errore", + text = text, + icon = FaIcons.ExclamationTriangle, + buttonText = button, + stateColor = SirioTheme.colors.notificationColors.alert, + onAction = {}, + ) {} + NotificationCommon( + title = "Titolo Informativo", + text = text, + icon = FaIcons.InfoCircle, + buttonText = button, + stateColor = SirioTheme.colors.notificationColors.info, + onAction = {}, + ) {} + NotificationCommon( + title = "Titolo di Avviso", + text = text, + icon = FaIcons.ExclamationCircle, + buttonText = button, + stateColor = SirioTheme.colors.notificationColors.warning, + onAction = {}, + ) {} + NotificationCommon( + title = "Titolo Successo", + text = text, + icon = FaIcons.Check, + buttonText = button, + stateColor = SirioTheme.colors.notificationColors.success, + onAction = {}, + ) {} + } + } +} + +@Preview +@Composable +private fun NotificationToastLinkCommonPreview() { + SirioTheme(darkTheme = true) { + Column(Modifier.background(Color(0xFFE5E5E5))) { + val text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit." + val button = "Azione" + val link = "Testo Link" + NotificationCommon( + title = "Titolo di Errore", + text = text, + icon = FaIcons.ExclamationTriangle, + link = link, + buttonText = button, + stateColor = SirioTheme.colors.notificationColors.alert, + onLink = {}, + onAction = {}, + onClose = {}, + ) + NotificationCommon( + title = "Titolo Informativo", + text = text, + icon = FaIcons.ExclamationCircle, + link = link, + buttonText = button, + stateColor = SirioTheme.colors.notificationColors.info, + onLink = {}, + onAction = {}, + onClose = {}, + ) + NotificationCommon( + title = "Titolo di Avviso", + text = text, + icon = FaIcons.ExclamationCircle, + link = link, + buttonText = button, + stateColor = SirioTheme.colors.notificationColors.warning, + onLink = {}, + onAction = {}, + onClose = {}, + ) + NotificationCommon( + title = "Titolo Successo", + text = text, + icon = FaIcons.Check, + link = link, + buttonText = button, + stateColor = SirioTheme.colors.notificationColors.success, + onLink = {}, + onAction = {}, + onClose = {}, + ) + } + } +} diff --git a/design/src/main/java/it/inps/sirio/ui/notification/NotificationInline.kt b/design/src/main/java/it/inps/sirio/ui/notification/NotificationInline.kt index 023c429..deaeecc 100644 --- a/design/src/main/java/it/inps/sirio/ui/notification/NotificationInline.kt +++ b/design/src/main/java/it/inps/sirio/ui/notification/NotificationInline.kt @@ -43,7 +43,7 @@ fun NotificationInline( onClose: () -> Unit, ) { val (icon: FaIconType, color: Color) = paramsByType(type) - NotificationInlineCommon( + NotificationCommon( title = title, text = text, icon = icon, diff --git a/design/src/main/java/it/inps/sirio/ui/notification/NotificationInlineCommon.kt b/design/src/main/java/it/inps/sirio/ui/notification/NotificationInlineCommon.kt deleted file mode 100644 index fc28cf6..0000000 --- a/design/src/main/java/it/inps/sirio/ui/notification/NotificationInlineCommon.kt +++ /dev/null @@ -1,160 +0,0 @@ -// -// NotificationInlineCommon.kt -// -// SPDX-FileCopyrightText: 2024 Istituto Nazionale Previdenza Sociale -// -// SPDX-License-Identifier: BSD-3-Clause -// - -package it.inps.sirio.ui.notification - -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.fillMaxHeight -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.width -import androidx.compose.material3.IconButton -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.semantics.CustomAccessibilityAction -import androidx.compose.ui.semantics.customActions -import androidx.compose.ui.semantics.semantics -import androidx.compose.ui.tooling.preview.Preview -import com.guru.fontawesomecomposelib.FaIconType -import com.guru.fontawesomecomposelib.FaIcons -import it.inps.sirio.theme.SirioTheme -import it.inps.sirio.theme.notificationInlineCloseSize -import it.inps.sirio.theme.notificationInlineHeight -import it.inps.sirio.theme.notificationInlineHorizontalPadding -import it.inps.sirio.theme.notificationInlineIconSize -import it.inps.sirio.theme.notificationInlineStateWidth -import it.inps.sirio.theme.notificationInlineVerticalPadding -import it.inps.sirio.theme.notificationInlineVerticalSpacer -import it.inps.sirio.ui.text.SirioTextCommon -import it.inps.sirio.utils.SirioIcon - -/** - * Inline notification implementation with an icon on the left and the state color, - * a title and a text in column and the close button - * - * @param title The notification title - * @param text The notification text - * @param icon The notification icon, placed on the left - * @param stateColor The notification state color - * @param closeContentDescription The content description of the close button - * @param onClose The callback when the close button is pressed - */ -@Composable -internal fun NotificationInlineCommon( - title: String, - text: String, - icon: FaIconType, - stateColor: Color, - closeContentDescription: String? = null, - onClose: () -> Unit, -) { - Row( - Modifier - .fillMaxWidth() - .height(notificationInlineHeight) - .background(color = SirioTheme.colors.notificationColors.background) - .semantics(mergeDescendants = true) { - customActions = listOf( - CustomAccessibilityAction( - label = title + text, - action = { - onClose() - true - } - ) - ) - }, - verticalAlignment = Alignment.CenterVertically, - ) { - Box( - Modifier - .width(notificationInlineStateWidth) - .fillMaxHeight() - .background(color = stateColor), - contentAlignment = Alignment.Center, - ) { - SirioIcon( - faIcon = icon, - size = notificationInlineIconSize, - iconColor = SirioTheme.colors.notificationColors.icon, - ) - } - Column( - modifier = Modifier - .weight(1f) - .padding( - start = notificationInlineHorizontalPadding, - top = notificationInlineVerticalPadding, - bottom = notificationInlineVerticalPadding, - ) - ) { - SirioTextCommon( - text = title, - color = SirioTheme.colors.notificationColors.title, - maxLines = 1, - typography = SirioTheme.typography.notificationInlineTitle, - ) - Spacer(modifier = Modifier.height(notificationInlineVerticalSpacer)) - SirioTextCommon( - text = text, - color = SirioTheme.colors.notificationColors.text, - maxLines = 1, - typography = SirioTheme.typography.notificationInlineText, - ) - } - IconButton(onClick = onClose) { - SirioIcon( - faIcon = FaIcons.Times, - size = notificationInlineCloseSize, - iconColor = SirioTheme.colors.notificationColors.icon, - contentDescription = closeContentDescription, - ) - } - } -} - -@Preview -@Composable -private fun NotificationInlineCommonPreview() { - SirioTheme { - Column(Modifier.background(Color(0xFFE5E5E5))) { - val text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit." - NotificationInlineCommon( - title = "Titolo di errore", - text = text, - icon = FaIcons.ExclamationTriangle, - stateColor = SirioTheme.colors.notificationColors.alert, - ) {} - NotificationInlineCommon( - title = "Titolo informativo", - text = text, - icon = FaIcons.ExclamationCircle, - stateColor = SirioTheme.colors.notificationColors.info, - ) {} - NotificationInlineCommon( - title = "Titolo avviso", - text = text, - icon = FaIcons.ExclamationCircle, - stateColor = SirioTheme.colors.notificationColors.warning, - ) {} - NotificationInlineCommon( - title = "Titolo successo", - text = text, - icon = FaIcons.Check, - stateColor = SirioTheme.colors.notificationColors.success, - ) {} - } - } -} diff --git a/design/src/main/java/it/inps/sirio/ui/notification/NotificationToast.kt b/design/src/main/java/it/inps/sirio/ui/notification/NotificationToast.kt index a409695..56d377d 100644 --- a/design/src/main/java/it/inps/sirio/ui/notification/NotificationToast.kt +++ b/design/src/main/java/it/inps/sirio/ui/notification/NotificationToast.kt @@ -49,17 +49,19 @@ fun NotificationToast( closeContentDescription: String? = null, onClose: () -> Unit, ) { - val (icon: FaIconType, color: Color) = paramsByType(type) - NotificationToastCommon( - title = title, - text = text, - icon = icon, - buttonText = buttonText, - stateColor = color, - closeContentDescription = closeContentDescription, - onAction = onAction, - onClose = onClose, - ) + SirioTheme(darkTheme = true) { + val (icon: FaIconType, color: Color) = paramsByType(type) + NotificationCommon( + title = title, + text = text, + icon = icon, + buttonText = buttonText, + stateColor = color, + closeContentDescription = closeContentDescription, + onAction = onAction, + onClose = onClose, + ) + } } /** @@ -72,7 +74,7 @@ fun NotificationToastSnackbarHost(snackbarHostState: SnackbarHostState) { Box( Modifier .fillMaxSize() - .padding(notificationToastPadding), Alignment.Center + .padding(notificationToastPadding.dp), Alignment.Center ) { SnackbarHost( hostState = snackbarHostState diff --git a/design/src/main/java/it/inps/sirio/ui/notification/NotificationToastCommon.kt b/design/src/main/java/it/inps/sirio/ui/notification/NotificationToastCommon.kt deleted file mode 100644 index 9b8f3cd..0000000 --- a/design/src/main/java/it/inps/sirio/ui/notification/NotificationToastCommon.kt +++ /dev/null @@ -1,181 +0,0 @@ -// -// NotificationToastCommon.kt -// -// SPDX-FileCopyrightText: 2024 Istituto Nazionale Previdenza Sociale -// -// SPDX-License-Identifier: BSD-3-Clause -// - -package it.inps.sirio.ui.notification - -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.wrapContentSize -import androidx.compose.material3.IconButton -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.semantics.semantics -import androidx.compose.ui.tooling.preview.Preview -import com.guru.fontawesomecomposelib.FaIconType -import com.guru.fontawesomecomposelib.FaIcons -import it.inps.sirio.theme.SirioTheme -import it.inps.sirio.theme.notificationToastCloseSize -import it.inps.sirio.theme.notificationToastHorizontalPadding -import it.inps.sirio.theme.notificationToastIconSize -import it.inps.sirio.theme.notificationToastStateWidth -import it.inps.sirio.theme.notificationToastTextBottomSpacer -import it.inps.sirio.theme.notificationToastTitleBottomSpacer -import it.inps.sirio.theme.notificationToastVerticalPadding -import it.inps.sirio.ui.button.ButtonSize -import it.inps.sirio.ui.button.ButtonStyle -import it.inps.sirio.ui.button.SirioButton -import it.inps.sirio.ui.text.SirioTextCommon -import it.inps.sirio.utils.SirioIcon - -/** - * Toast notification implementation with an icon, the state color, - * a title, a text, an action and the close button - * - * @param title The notification title - * @param text The notification text - * @param icon The notification FA icon, placed on top - * @param buttonText The string inside the action button - * @param stateColor The notification state color, placed on the left - * @param closeContentDescription The content description of the close button - * @param onAction The callback when the action button is pressed - * @param onClose The callback when the close button is pressed - */ -@Composable -internal fun NotificationToastCommon( - title: String, - text: String, - icon: FaIconType, - buttonText: String? = null, - stateColor: Color, - closeContentDescription: String? = null, - onAction: (() -> Unit)? = null, - onClose: () -> Unit, -) { - Box( - Modifier - .wrapContentSize() - .background(color = stateColor), - ) { - Column( - modifier = Modifier - .padding(start = notificationToastStateWidth) - .wrapContentSize() - .background(SirioTheme.colors.notificationColors.background) - .padding( - horizontal = notificationToastHorizontalPadding, - vertical = notificationToastVerticalPadding, - ) - .semantics(mergeDescendants = true) { -// customActions = listOf( -// CustomAccessibilityAction( -// label = title + text, -// action = { -// onClose() -// true -// } -// ) -// ) - } - ) { - Row( - Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically, - ) { - SirioIcon( - faIcon = icon, - size = notificationToastIconSize, - iconColor = SirioTheme.colors.notificationColors.icon, - ) - IconButton(onClick = onClose) { - SirioIcon( - faIcon = FaIcons.Times, - size = notificationToastCloseSize, - iconColor = SirioTheme.colors.notificationColors.icon, - contentDescription = closeContentDescription, - ) - } - } - SirioTextCommon( - text = title, - modifier = Modifier.wrapContentSize(), - color = SirioTheme.colors.notificationColors.title, - maxLines = 1, - typography = SirioTheme.typography.notificationToastTitle, - ) - Spacer(modifier = Modifier.height(notificationToastTitleBottomSpacer)) - SirioTextCommon( - text = text, - modifier = Modifier.wrapContentSize(), - color = SirioTheme.colors.notificationColors.text, - typography = SirioTheme.typography.notificationToastText, - ) - if (!buttonText.isNullOrEmpty() && onAction != null) { - Spacer(modifier = Modifier.height(notificationToastTextBottomSpacer)) - SirioButton( - text = buttonText, - onClick = onAction, - size = ButtonSize.Large, - style = ButtonStyle.Tertiary - ) - } - } - } -} - -@Preview -@Composable -private fun NotificationToastCommonPreview() { - SirioTheme { - Column(Modifier.background(Color(0xFFE5E5E5))) { - val text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit." - val button = "Azione" - NotificationToastCommon( - title = "Titolo di errore", - text = text, - icon = FaIcons.ExclamationTriangle, - buttonText = button, - stateColor = SirioTheme.colors.notificationColors.alert, - onAction = {}, - ) {} - NotificationToastCommon( - title = "Titolo informativo", - text = text, - icon = FaIcons.ExclamationCircle, - buttonText = button, - stateColor = SirioTheme.colors.notificationColors.info, - onAction = {}, - ) {} - NotificationToastCommon( - title = "Titolo avviso", - text = text, - icon = FaIcons.ExclamationCircle, - buttonText = button, - stateColor = SirioTheme.colors.notificationColors.warning, - onAction = {}, - ) {} - NotificationToastCommon( - title = "Titolo successo", - text = text, - icon = FaIcons.Check, - buttonText = button, - stateColor = SirioTheme.colors.notificationColors.success, - onAction = {}, - ) {} - } - } -} \ No newline at end of file diff --git a/design/src/main/java/it/inps/sirio/ui/radiobutton/SirioRadioButton.kt b/design/src/main/java/it/inps/sirio/ui/radiobutton/SirioRadioButton.kt index 8094892..03c0b8b 100644 --- a/design/src/main/java/it/inps/sirio/ui/radiobutton/SirioRadioButton.kt +++ b/design/src/main/java/it/inps/sirio/ui/radiobutton/SirioRadioButton.kt @@ -28,8 +28,8 @@ fun SirioRadioButton( onClick: () -> Unit, ) { SirioRadioButtonCommon( + selected = selected, text = text, - isSelected = selected, enabled = enabled, onClick = onClick, ) @@ -48,4 +48,4 @@ private fun ChipLabelPreview() { ) } } -} \ No newline at end of file +} diff --git a/design/src/main/java/it/inps/sirio/ui/radiobutton/SirioRadioButtonCommon.kt b/design/src/main/java/it/inps/sirio/ui/radiobutton/SirioRadioButtonCommon.kt index 0cd815a..70133c0 100644 --- a/design/src/main/java/it/inps/sirio/ui/radiobutton/SirioRadioButtonCommon.kt +++ b/design/src/main/java/it/inps/sirio/ui/radiobutton/SirioRadioButtonCommon.kt @@ -18,11 +18,14 @@ import androidx.compose.foundation.interaction.collectIsPressedAsState import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width import androidx.compose.foundation.selection.selectable import androidx.compose.foundation.shape.CircleShape +import androidx.compose.material3.minimumInteractiveComponentSize import androidx.compose.runtime.Composable import androidx.compose.runtime.Stable import androidx.compose.runtime.getValue @@ -34,28 +37,31 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.semantics.Role import androidx.compose.ui.text.TextStyle import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp import it.inps.sirio.theme.SirioColorState import it.inps.sirio.theme.SirioTheme import it.inps.sirio.theme.radioBorderWidth import it.inps.sirio.theme.radioDotSize import it.inps.sirio.theme.radioFocusBorderPadding import it.inps.sirio.theme.radioFocusExtraBorderWidth -import it.inps.sirio.theme.radioSafeAreaPadding +import it.inps.sirio.theme.radioPaddingText import it.inps.sirio.theme.radioSize import it.inps.sirio.ui.text.SirioTextCommon /** * Radio button implementation * + * @param selected Whether the radio button is selected + * @param modifier the Modifier to be applied to this radio button * @param text The optional string on the right of the radio - * @param isSelected Whether the radio button is selected * @param enabled Whether the radio button is clickable * @param onClick The callback invoked when the component is tapped */ @Composable internal fun SirioRadioButtonCommon( + selected: Boolean, + modifier: Modifier = Modifier, text: String? = null, - isSelected: Boolean, enabled: Boolean = true, onClick: () -> Unit, ) { @@ -75,10 +81,10 @@ internal fun SirioRadioButtonCommon( Row( verticalAlignment = Alignment.CenterVertically, - modifier = Modifier - .focusable(enabled = true, interactionSource = interactionSource) + modifier = modifier + .focusable(enabled = enabled, interactionSource = interactionSource) .selectable( - selected = isSelected, + selected = selected, interactionSource = interactionSource, indication = null, enabled = enabled, @@ -88,13 +94,14 @@ internal fun SirioRadioButtonCommon( } ) { CustomRadioButton( - selected = isSelected, + selected = selected, isFocused = isFocused, backgroundColor = backgroundColor, dotColor = dotColor, borderColor = borderColor ) text?.let { + Spacer(modifier = Modifier.width(radioPaddingText.dp)) SirioTextCommon( text = it, color = textColor, @@ -125,17 +132,17 @@ private fun CustomRadioButton( } val size = Modifier - .padding(radioSafeAreaPadding) - .size(radioSize) + .size(radioSize.dp) + .minimumInteractiveComponentSize() Box( modifier = if (isFocused) { size .border( - radioFocusExtraBorderWidth, + radioFocusExtraBorderWidth.dp, color = SirioTheme.colors.radio.borderFocusExtra, shape = CircleShape, ) - .padding(focusPadding) + .padding(focusPadding.dp) } else size, contentAlignment = Alignment.Center, ) { @@ -143,14 +150,14 @@ private fun CustomRadioButton( modifier = Modifier .clip(CircleShape) .fillMaxSize() - .border(width = radioBorderWidth, color = borderColor, shape = CircleShape) + .border(width = radioBorderWidth.dp, color = borderColor, shape = CircleShape) .background(backgroundColor), contentAlignment = Alignment.Center ) { if (selected) { Box( modifier = Modifier - .size(radioDotSize) + .size(radioDotSize.dp) .background(dotColor, CircleShape) ) } @@ -196,14 +203,14 @@ private fun RadioCommonPreview() { SirioTheme { Column(Modifier.background(Color.White)) { val text = "Title" - SirioRadioButtonCommon(isSelected = false, onClick = {}, enabled = true) - SirioRadioButtonCommon(isSelected = true, onClick = {}, enabled = true) - SirioRadioButtonCommon(isSelected = false, onClick = {}, enabled = false) - SirioRadioButtonCommon(isSelected = true, onClick = {}, enabled = false) - SirioRadioButtonCommon(text = text, isSelected = false, onClick = {}, enabled = true) - SirioRadioButtonCommon(text = text, isSelected = true, onClick = {}, enabled = true) - SirioRadioButtonCommon(text = text, isSelected = false, onClick = {}, enabled = false) - SirioRadioButtonCommon(text = text, isSelected = true, onClick = {}, enabled = false) + SirioRadioButtonCommon(selected = false, enabled = true, onClick = {}) + SirioRadioButtonCommon(selected = true, enabled = true, onClick = {}) + SirioRadioButtonCommon(selected = false, enabled = false, onClick = {}) + SirioRadioButtonCommon(selected = true, enabled = false, onClick = {}) + SirioRadioButtonCommon(selected = false, text = text, enabled = true, onClick = {}) + SirioRadioButtonCommon(selected = true, text = text, enabled = true, onClick = {}) + SirioRadioButtonCommon(selected = false, text = text, enabled = false, onClick = {}) + SirioRadioButtonCommon(selected = true, text = text, enabled = false, onClick = {}) } } } diff --git a/design/src/main/java/it/inps/sirio/ui/searchbar/SirioSearchBar.kt b/design/src/main/java/it/inps/sirio/ui/searchbar/SirioSearchBar.kt index 1e653c4..2f00d26 100644 --- a/design/src/main/java/it/inps/sirio/ui/searchbar/SirioSearchBar.kt +++ b/design/src/main/java/it/inps/sirio/ui/searchbar/SirioSearchBar.kt @@ -33,6 +33,7 @@ import it.inps.sirio.theme.SirioTheme * @param optionValues The hints based on current [searchText] * @param queries The list of already searched queries * @param onQueriesChange The callback invoked when the [queries] list change + * @param onSearch The callback invoked when the user click on search button */ @Composable fun SirioSearchBar( @@ -44,6 +45,7 @@ fun SirioSearchBar( optionValues: Array = emptyArray(), queries: Array = emptyArray(), onQueriesChange: (queries: Array) -> Unit, + onSearch: ((text: String) -> Unit)? = null, ) { SirioSearchBarCommon( searchText = searchText, @@ -54,7 +56,8 @@ fun SirioSearchBar( optionValues = optionValues, queries = queries, onQueriesChange = onQueriesChange, - enabled = true + enabled = true, + onSearch = onSearch, ) } @@ -87,4 +90,4 @@ private fun SearchBarPreview() { ) } } -} \ No newline at end of file +} diff --git a/design/src/main/java/it/inps/sirio/ui/searchbar/SirioSearchBarCommon.kt b/design/src/main/java/it/inps/sirio/ui/searchbar/SirioSearchBarCommon.kt index 5316a32..dff7248 100644 --- a/design/src/main/java/it/inps/sirio/ui/searchbar/SirioSearchBarCommon.kt +++ b/design/src/main/java/it/inps/sirio/ui/searchbar/SirioSearchBarCommon.kt @@ -29,7 +29,6 @@ import androidx.compose.foundation.verticalScroll import androidx.compose.runtime.Composable import androidx.compose.runtime.Stable import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateListOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue @@ -44,7 +43,7 @@ import com.guru.fontawesomecomposelib.FaIcons import it.inps.sirio.theme.SirioTheme import it.inps.sirio.theme.searchBarQueriesPadding import it.inps.sirio.theme.searchBarQueriesVerticalPadding -import it.inps.sirio.ui.chip.ChipLabelClose +import it.inps.sirio.ui.chip.SirioChipLabelClose import it.inps.sirio.ui.textfield.SirioTextFieldCommon /** @@ -60,6 +59,7 @@ import it.inps.sirio.ui.textfield.SirioTextFieldCommon * @param onQueriesChange The callback invoked when the [queries] list change * @param onQueryAdded The callback invoked when the user add a query by search bar * @param enabled Whether the search bar allow to insert/remove [queries] + * @param onSearch The callback invoked when the user click on search button */ @Composable internal fun SirioSearchBarCommon( @@ -73,12 +73,21 @@ internal fun SirioSearchBarCommon( onQueriesChange: (queries: Array) -> Unit, onQueryAdded: ((newQuery: String) -> Unit)? = null, enabled: Boolean, -// onSearchBarClick: (() -> Unit)? = null, + onSearch: ((text: String) -> Unit)? = null, ) { val focusManager = LocalFocusManager.current - val chips = remember { mutableStateListOf(elements = queries) } var showChips by remember { mutableStateOf(true) } + fun addQuery(value: String) { + if (value.isNotBlank()) { + focusManager.clearFocus() + showChips = true + if (!queries.contains(value)) { + onQueryAdded?.invoke(value) + onQueriesChange((queries.plus(value))) + } + } + } Column { SirioTextFieldCommon( text = searchText, @@ -93,46 +102,27 @@ internal fun SirioSearchBarCommon( onInfoClick = null, helperText = helperText, optionValues = optionValues, - onOptionValueSelected = { - if (it.isNotBlank()) { - focusManager.clearFocus() - showChips = true - if (!chips.contains(it)) { - onQueryAdded?.invoke(it) - chips.add(it) - onQueriesChange(chips.toTypedArray()) - } - } - }, + onOptionValueSelected = { addQuery(it) }, type = null, enabled = enabled, disableExtraBorder = true, backgroundColor = SirioTheme.colors.searchBar.background, onDropdownStateChange = { open -> showChips = !open }, - onIconClick = { onSearchTextChange("") }, + onIconClick = { + onSearchTextChange("") + showChips = true + }, onIconButtonClick = { - if (it.isNotBlank()) { - focusManager.clearFocus() - showChips = true - if (!chips.contains(it)) { - onQueryAdded?.invoke(it) - chips.add(it) - onQueriesChange(chips.toTypedArray()) - } - } + onSearch?.invoke(it) + addQuery(it) }, keyboardOptions = KeyboardOptions(imeAction = ImeAction.Search), - keyboardActions = KeyboardActions(onAny = { - if (searchText.isNotBlank()) { - focusManager.clearFocus() - showChips = true - if (!chips.contains(searchText)) { - onQueryAdded?.invoke(searchText) - chips.add(searchText) - onQueriesChange(chips.toTypedArray()) - } + keyboardActions = KeyboardActions( + onAny = { + onSearch?.invoke(searchText) + addQuery(searchText) } - }), + ), ) if (showChips) { Spacer(modifier = Modifier.height(searchBarQueriesVerticalPadding.dp)) @@ -140,14 +130,18 @@ internal fun SirioSearchBarCommon( modifier = Modifier .fillMaxWidth() .wrapContentHeight(), - horizontalArrangement = Arrangement.spacedBy(searchBarQueriesPadding.dp, Alignment.Start), - verticalArrangement = Arrangement.spacedBy(searchBarQueriesPadding.dp, Alignment.Top) -// lastLineMainAxisAlignment = FlowMainAxisAlignment.Start, + horizontalArrangement = Arrangement.spacedBy( + searchBarQueriesPadding.dp, + Alignment.Start + ), + verticalArrangement = Arrangement.spacedBy( + searchBarQueriesPadding.dp, + Alignment.Top + ) ) { - chips.forEachIndexed { index, item -> - ChipLabelClose(label = item, enabled = enabled) { - chips.removeAt(index) - onQueriesChange(chips.toTypedArray()) + queries.forEach { item -> + SirioChipLabelClose(label = item, enabled = enabled) { + onQueriesChange(queries.filter { it != item }.toTypedArray()) } } } diff --git a/design/src/main/java/it/inps/sirio/ui/stepprogressbar/SirioStepControls.kt b/design/src/main/java/it/inps/sirio/ui/stepprogressbar/SirioStepControls.kt new file mode 100644 index 0000000..ec233ae --- /dev/null +++ b/design/src/main/java/it/inps/sirio/ui/stepprogressbar/SirioStepControls.kt @@ -0,0 +1,131 @@ +// +// SirioStepControls.kt +// +// SPDX-FileCopyrightText: 2022 Istituto Nazionale Previdenza Sociale +// +// SPDX-License-Identifier: BSD-3-Clause +// +package it.inps.sirio.ui.stepprogressbar + +import androidx.annotation.Keep +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.runtime.Composable +import androidx.compose.runtime.Stable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.semantics.Role +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.guru.fontawesomecomposelib.FaIcons +import it.inps.sirio.R +import it.inps.sirio.theme.SirioTheme +import it.inps.sirio.theme.stepControlsHeight +import it.inps.sirio.theme.stepControlsHorizontalPadding +import it.inps.sirio.theme.stepControlsIconSize +import it.inps.sirio.ui.text.SirioText +import it.inps.sirio.utils.SirioIcon + +@Composable +fun SirioStepControls( + previousEnabled: Boolean = true, + nextEnabled: Boolean = true, + onPrevious: () -> Unit, + onNext: () -> Unit, +) { + Row( + Modifier + .height(stepControlsHeight.dp) + .fillMaxWidth() + .background(SirioTheme.colors.stepProgressBar.controls.background), + verticalAlignment = Alignment.CenterVertically, + ) { + Row( + modifier = Modifier + .fillMaxHeight() + .padding(horizontal = stepControlsHorizontalPadding.dp) + .clickable(enabled = previousEnabled, role = Role.Button, onClick = onPrevious), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy(stepControlsHorizontalPadding.dp) + ) { + SirioIcon( + faIcon = FaIcons.AngleLeft, + iconColor = SirioTheme.colors.stepProgressBar.action, + size = stepControlsIconSize.dp, + ) + SirioText( + text = stringResource(id = R.string.sirio_step_controls_previous), + color = SirioTheme.colors.stepProgressBar.controls.previous, + typography = SirioTheme.typography.stepProgressBar.controls.previous, + ) + } + Spacer(modifier = Modifier.weight(1f)) + Row( + modifier = Modifier + .fillMaxHeight() + .padding(horizontal = stepControlsHorizontalPadding.dp) + .clickable(enabled = nextEnabled, role = Role.Button, onClick = onNext), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy(stepControlsHorizontalPadding.dp) + ) { + SirioText( + text = stringResource(id = R.string.sirio_step_controls_next), + color = SirioTheme.colors.stepProgressBar.controls.next, + typography = SirioTheme.typography.stepProgressBar.controls.next, + ) + SirioIcon( + faIcon = FaIcons.AngleRight, + iconColor = SirioTheme.colors.stepProgressBar.action, + size = stepControlsIconSize.dp, + ) + } + } +} + +@Keep +data class SirioStepControlsColors( + val background: Color, + val previous: Color, + val next: Color, +) { + companion object { + @Stable + val Unspecified = SirioStepControlsColors( + background = Color.Unspecified, + previous = Color.Unspecified, + next = Color.Unspecified, + ) + } +} + +@Keep +data class SirioStepControlsTypography( + val previous: TextStyle, + val next: TextStyle, +) { + companion object { + @Stable + val Default = SirioStepControlsTypography( + previous = TextStyle.Default, + next = TextStyle.Default, + ) + } +} + +@Preview +@Composable +private fun SirioStepControlsPreview() { + SirioTheme { + SirioStepControls(onPrevious = {}, onNext = {}) + } +} \ No newline at end of file diff --git a/design/src/main/java/it/inps/sirio/ui/stepprogressbar/SirioStepProgressBar.kt b/design/src/main/java/it/inps/sirio/ui/stepprogressbar/SirioStepProgressBar.kt new file mode 100644 index 0000000..a20629b --- /dev/null +++ b/design/src/main/java/it/inps/sirio/ui/stepprogressbar/SirioStepProgressBar.kt @@ -0,0 +1,42 @@ +// +// SirioStepProgressBar.kt +// +// SPDX-FileCopyrightText: 2022 Istituto Nazionale Previdenza Sociale +// +// SPDX-License-Identifier: BSD-3-Clause +// +package it.inps.sirio.ui.stepprogressbar + +import androidx.annotation.Keep +import androidx.compose.runtime.Stable +import androidx.compose.ui.graphics.Color + +@Keep +data class SirioStepProgressBarColors( + val action: Color, + val selection: SirioStepSelectionColors, + val controls: SirioStepControlsColors, +) { + companion object { + @Stable + val Unspecified = SirioStepProgressBarColors( + action = Color.Unspecified, + selection = SirioStepSelectionColors.Unspecified, + controls = SirioStepControlsColors.Unspecified, + ) + } +} + +@Keep +data class SirioStepProgressBarTypography( + val selection: SirioStepSelectionTypography, + val controls: SirioStepControlsTypography, +) { + companion object { + @Stable + val Default = SirioStepProgressBarTypography( + selection = SirioStepSelectionTypography.Default, + controls = SirioStepControlsTypography.Default, + ) + } +} \ No newline at end of file diff --git a/design/src/main/java/it/inps/sirio/ui/stepprogressbar/SirioStepSelection.kt b/design/src/main/java/it/inps/sirio/ui/stepprogressbar/SirioStepSelection.kt new file mode 100644 index 0000000..f944d7c --- /dev/null +++ b/design/src/main/java/it/inps/sirio/ui/stepprogressbar/SirioStepSelection.kt @@ -0,0 +1,96 @@ +// +// SirioStepSelection.kt +// +// SPDX-FileCopyrightText: 2022 Istituto Nazionale Previdenza Sociale +// +// SPDX-License-Identifier: BSD-3-Clause +// +package it.inps.sirio.ui.stepprogressbar + +import androidx.annotation.Keep +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.runtime.Composable +import androidx.compose.runtime.Stable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import it.inps.sirio.R +import it.inps.sirio.theme.SirioTheme +import it.inps.sirio.theme.stepSelectionHeight +import it.inps.sirio.theme.stepSelectionPaddingHorizontal +import it.inps.sirio.ui.text.SirioText + +@Composable +fun SirioStepSelection( + progress: Int, + total: Int, + currentStep: String, +) { + Row( + Modifier + .height(stepSelectionHeight.dp) + .fillMaxWidth() + .background(SirioTheme.colors.stepProgressBar.selection.background) + .padding(horizontal = stepSelectionPaddingHorizontal.dp), + verticalAlignment = Alignment.CenterVertically, + ) { + SirioText( + text = stringResource(id = R.string.sirio_step_selection_progress, progress, total), + color = SirioTheme.colors.stepProgressBar.selection.progress, + typography = SirioTheme.typography.stepProgressBar.selection.progress, + ) + Spacer(modifier = Modifier.weight(1f)) + SirioText( + text = currentStep, + color = SirioTheme.colors.stepProgressBar.selection.currentStep, + typography = SirioTheme.typography.stepProgressBar.selection.currentStep, + ) + } +} + +@Keep +data class SirioStepSelectionColors( + val background: Color, + val progress: Color, + val currentStep: Color, +) { + companion object { + @Stable + val Unspecified = SirioStepSelectionColors( + background = Color.Unspecified, + progress = Color.Unspecified, + currentStep = Color.Unspecified, + ) + } +} + +@Keep +data class SirioStepSelectionTypography( + val progress: TextStyle, + val currentStep: TextStyle, +) { + companion object { + @Stable + val Default = SirioStepSelectionTypography( + progress = TextStyle.Default, + currentStep = TextStyle.Default, + ) + } +} + +@Preview +@Composable +private fun SirioStepSelectionPreview() { + SirioTheme { + SirioStepSelection(progress = 1, total = 6, currentStep = "Nome Passaggio") + } +} \ No newline at end of file diff --git a/design/src/main/java/it/inps/sirio/ui/tabbar/SirioTabBar.kt b/design/src/main/java/it/inps/sirio/ui/tabbar/SirioTabBar.kt new file mode 100644 index 0000000..4744d82 --- /dev/null +++ b/design/src/main/java/it/inps/sirio/ui/tabbar/SirioTabBar.kt @@ -0,0 +1,108 @@ +// +// SirioTabBar.kt +// +// SPDX-FileCopyrightText: 2024 Istituto Nazionale Previdenza Sociale +// +// SPDX-License-Identifier: BSD-3-Clause +// + +package it.inps.sirio.ui.tabbar + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.material3.BadgedBox +import androidx.compose.material3.LocalContentColor +import androidx.compose.material3.NavigationBar +import androidx.compose.material3.NavigationBarItem +import androidx.compose.material3.NavigationBarItemDefaults +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.platform.LocalConfiguration +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import it.inps.sirio.theme.SirioTheme +import it.inps.sirio.theme.tabBarHeight +import it.inps.sirio.theme.tabBarItemIconSize +import it.inps.sirio.theme.tabBarItemStateIndicatorHeight +import it.inps.sirio.ui.badge.SirioBadgeCommon +import it.inps.sirio.ui.text.SirioTextCommon +import it.inps.sirio.utils.SirioIcon + +/** + * A bottom navigation with tabs + * + * @param items The items [SirioTabBarItemData] to be shown. Min 3 - Max 5 + * @param selectedIndex The index of the selected tab. Default 0 + */ +@Composable +fun SirioTabBar( + items: List, + selectedIndex: Int = 0, +) { + //TabBar should contain 3-5 tabs + assert(items.size in 3..5) + NavigationBar( + modifier = Modifier + .fillMaxWidth() + .height(tabBarHeight.dp), + containerColor = SirioTheme.colors.tabBarBackground, + ) { + val labelTypography = with(SirioTheme.typography.tabBarItemText) { + if (LocalConfiguration.current.fontScale > 1) copy(fontSize = 9.sp) else this + } + + items.take(5).forEachIndexed { index, tabItem -> + NavigationBarItem( + selected = index == selectedIndex, + onClick = tabItem.action, + icon = { + Column(horizontalAlignment = Alignment.CenterHorizontally) { + Box( + modifier = Modifier + .fillMaxWidth() + .height(tabBarItemStateIndicatorHeight.dp) + .background(if (index == selectedIndex) SirioTheme.colors.tabBarActive else SirioTheme.colors.tabBarBackground) + ) + Spacer(modifier = Modifier.height(3.dp)) + BadgedBox( + badge = { + if (tabItem.badge) { + SirioBadgeCommon() + } + }, + ) { + SirioIcon( + faIcon = tabItem.icon, + size = tabBarItemIconSize.dp, + iconColor = LocalContentColor.current + ) + } + } + }, + label = { + SirioTextCommon( + text = tabItem.label, + color = LocalContentColor.current, + overflow = TextOverflow.Ellipsis, + maxLines = 1, + typography = labelTypography, + ) + }, + colors = NavigationBarItemDefaults.colors( + selectedIconColor = SirioTheme.colors.tabBarActive, + selectedTextColor = SirioTheme.colors.tabBarActive, + indicatorColor = Color.Transparent, + unselectedIconColor = SirioTheme.colors.tabBarContent, + unselectedTextColor = SirioTheme.colors.tabBarContent, + ) + ) + } + } +} \ No newline at end of file diff --git a/design/src/main/java/it/inps/sirio/ui/tabbar/TabBarItemData.kt b/design/src/main/java/it/inps/sirio/ui/tabbar/SirioTabBarItemData.kt similarity index 76% rename from design/src/main/java/it/inps/sirio/ui/tabbar/TabBarItemData.kt rename to design/src/main/java/it/inps/sirio/ui/tabbar/SirioTabBarItemData.kt index 582f50d..c38a921 100644 --- a/design/src/main/java/it/inps/sirio/ui/tabbar/TabBarItemData.kt +++ b/design/src/main/java/it/inps/sirio/ui/tabbar/SirioTabBarItemData.kt @@ -1,5 +1,5 @@ // -// TabBarItemData.kt +// SirioTabBarItemData.kt // // SPDX-FileCopyrightText: 2024 Istituto Nazionale Previdenza Sociale // @@ -15,13 +15,13 @@ import com.guru.fontawesomecomposelib.FaIconType * A representation of a tab bar item * @param label The label of the item * @param icon The FA icon of the item - * @param route The route to navigate on item pressed * @param badge If the item's icon has a badge + * @param action The action to perform when the item is clicked */ @Keep -data class TabBarItemData( +data class SirioTabBarItemData( val label: String, val icon: FaIconType, - val route: String, val badge: Boolean = false, + val action: () -> Unit, ) \ No newline at end of file diff --git a/design/src/main/java/it/inps/sirio/ui/tabbar/TabBar.kt b/design/src/main/java/it/inps/sirio/ui/tabbar/TabBar.kt deleted file mode 100644 index ccf9d4f..0000000 --- a/design/src/main/java/it/inps/sirio/ui/tabbar/TabBar.kt +++ /dev/null @@ -1,194 +0,0 @@ -// -// TabBar.kt -// -// SPDX-FileCopyrightText: 2024 Istituto Nazionale Previdenza Sociale -// -// SPDX-License-Identifier: BSD-3-Clause -// - -package it.inps.sirio.ui.tabbar - -import android.util.Log -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.padding -import androidx.compose.material3.BadgedBox -import androidx.compose.material3.LocalContentColor -import androidx.compose.material3.NavigationBar -import androidx.compose.material3.NavigationBarItem -import androidx.compose.material3.NavigationBarItemDefaults -import androidx.compose.material3.Scaffold -import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.platform.LocalConfiguration -import androidx.compose.ui.tooling.preview.Devices -import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import androidx.navigation.NavHostController -import androidx.navigation.compose.currentBackStackEntryAsState -import androidx.navigation.compose.rememberNavController -import com.guru.fontawesomecomposelib.FaIcons -import it.inps.sirio.theme.SirioTheme -import it.inps.sirio.theme.tabBarHeight -import it.inps.sirio.theme.tabBarItemIconSize -import it.inps.sirio.theme.tabBarItemStateIndicatorHeight -import it.inps.sirio.ui.badge.SirioBadgeCommon -import it.inps.sirio.ui.text.SirioTextCommon -import it.inps.sirio.utils.SirioIcon - -/** - * A bottom navigation with tabs - * - * @param items The items [TabBarItemData] to be shown. Min 3 - Max 5 - * @param navController The navigation controller in which perform the routes - */ -@Composable -fun TabBar(items: List, navController: NavHostController) { - //TabBar should contain 3-5 tabs - assert(items.size in 3..5) - NavigationBar( - modifier = Modifier - .fillMaxWidth() - .height(tabBarHeight.dp), - containerColor = SirioTheme.colors.tabBarBackground, - ) { - // observe the backstack - val navBackStackEntry by navController.currentBackStackEntryAsState() - - // observe current route to change the icon - // color,label color when navigated - val currentRoute = navBackStackEntry?.destination?.route - - val labelTypography = with(SirioTheme.typography.tabBarItemText) { - if (LocalConfiguration.current.fontScale > 1) copy(fontSize = 9.sp) else this - } - - items.take(5).forEach { tabItem -> - val selected = currentRoute == tabItem.route - NavigationBarItem( - selected = selected, - onClick = { - try { - navController.navigate(tabItem.route) { - // Pop up to the start destination of the graph to - // avoid building up a large stack of destinations - // on the back stack as users select items - popUpTo(navController.graph.startDestinationId) { - saveState = true - } - // Avoid multiple copies of the same destination when - // reselecting the same item - launchSingleTop = true - // Restore state when reselecting a previously selected item - restoreState = true - } - } catch (e: Exception) { - Log.e("TabBar", "TabBar: onclick exception ", e) - } - }, - icon = { - Column(horizontalAlignment = Alignment.CenterHorizontally) { - Box( - modifier = Modifier - .fillMaxWidth() - .height(tabBarItemStateIndicatorHeight.dp) - .background(if (selected) SirioTheme.colors.tabBarActive else SirioTheme.colors.tabBarBackground) - ) - Spacer(modifier = Modifier.height(3.dp)) - BadgedBox( - badge = { - if (tabItem.badge) { - SirioBadgeCommon() - } - }, - ) { - SirioIcon( - faIcon = tabItem.icon, - size = tabBarItemIconSize.dp, - iconColor = LocalContentColor.current - ) - } - } - }, - label = { - SirioTextCommon( - text = tabItem.label, - color = LocalContentColor.current, - maxLines = 1, - typography = labelTypography, - ) - }, - colors = NavigationBarItemDefaults.colors( - selectedIconColor = SirioTheme.colors.tabBarActive, - selectedTextColor = SirioTheme.colors.tabBarActive, - indicatorColor = Color.Transparent, - unselectedIconColor = SirioTheme.colors.tabBarContent, - unselectedTextColor = SirioTheme.colors.tabBarContent, - ) - ) - } - } -} - -@Preview(showSystemUi = true) -@Preview(showSystemUi = true, device = Devices.NEXUS_10) -@Composable -private fun TabBarPreview() { - SirioTheme { - Scaffold( - bottomBar = { - TabBar( - items = listOf( - TabBarItemData( - label = "Home", - icon = FaIcons.Home, - route = "InpsScreen.HomeScreen.route", - badge = false, - ), - TabBarItemData( - label = "News", - icon = FaIcons.Newspaper, - route = "InpsScreen.NewsScreen.route", - badge = false, - ), - TabBarItemData( - label = "Mappe", - icon = FaIcons.Globe, - route = "InpsScreen.MapsScreen.route", - badge = false, - ), - TabBarItemData( - label = "Contattaci", - icon = FaIcons.CommentAlt, - route = "InpsScreen.ContattaciScreen.route", - badge = false, - ), - TabBarItemData( - label = "Servizi", - icon = FaIcons.GripHorizontal, - route = "InpsScreen.ServiziScreen.route", - badge = true, - ) - ), - navController = rememberNavController() - ) - } - ) { paddingValues -> - Box( - modifier = Modifier - .fillMaxSize() - .padding(paddingValues) - ) { - } - } - } -} diff --git a/design/src/main/java/it/inps/sirio/ui/table/SirioTable.kt b/design/src/main/java/it/inps/sirio/ui/table/SirioTable.kt new file mode 100644 index 0000000..4a5af44 --- /dev/null +++ b/design/src/main/java/it/inps/sirio/ui/table/SirioTable.kt @@ -0,0 +1,165 @@ +// +// SirioTable.kt +// +// SPDX-FileCopyrightText: 2022 Istituto Nazionale Previdenza Sociale +// +// SPDX-License-Identifier: BSD-3-Clause +// +package it.inps.sirio.ui.table + +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.tooling.preview.Preview +import com.guru.fontawesomecomposelib.FaIcons +import it.inps.sirio.theme.SirioTheme +import it.inps.sirio.ui.table.cell.SirioTableCellAvatar +import it.inps.sirio.ui.table.cell.SirioTableCellLink +import it.inps.sirio.ui.table.cell.SirioTableCellMultiIcons +import it.inps.sirio.ui.table.cell.SirioTableCellNumber +import it.inps.sirio.ui.table.cell.SirioTableCellNumberOnly +import it.inps.sirio.ui.table.cell.SirioTableCellTag +import it.inps.sirio.ui.table.cell.SirioTableCellText +import it.inps.sirio.ui.table.cell.SirioTableCellTextOnly +import it.inps.sirio.ui.titlebar.SirioTitleBar +import it.inps.sirio.ui.titlebar.SirioTitleBarItemData + +@Composable +fun SirioTable( + title: String, + titleBarItems: List = emptyList(), + headers: List, + rows: List, +) { + Column { + SirioTitleBar(title = title, titleBarItems) + Row { + headers.indices.forEach { index -> + val header = headers[index] + Column(Modifier.weight(1f)) { + SirioTableHeader( + title = header.title, + size = header.size, + alignment = header.alignment, + scroll = header.scroll, + withCheckBox = header.withCheckBox, + checked = header.checked, + onCheckedChange = header.onCheckedChange, + onIconClick = header.onIconClick, + ) + rows.forEach { row -> + if (index > row.cells.size - 1) { + SirioTableCellTextOnly(text = "", size = header.size) + } else { + CellTypeToCell(row.cells[index]) + } + } + } + } + } + } +} + +@Composable +private fun CellTypeToCell(cell: SirioTableCellType) { + when (cell) { + is SirioTableCellType.Avatar -> SirioTableCellAvatar(cell) + is SirioTableCellType.Link -> SirioTableCellLink(cell) + is SirioTableCellType.MultiIcons -> SirioTableCellMultiIcons(cell) + is SirioTableCellType.Number -> SirioTableCellNumber(cell) + is SirioTableCellType.NumberOnly -> SirioTableCellNumberOnly(cell) + is SirioTableCellType.Tag -> SirioTableCellTag(cell) + is SirioTableCellType.Text -> SirioTableCellText(cell) + is SirioTableCellType.TextOnly -> SirioTableCellTextOnly(cell) + else -> {} + } +} + +@Preview +@Composable +private fun SirioTablePreview() { + SirioTheme { + SirioTable( + title = "Title", + titleBarItems = listOf( + SirioTitleBarItemData( + icon = FaIcons.Filter, + text = "Mostra filtri", + contentDescription = null, + action = {}, + ) + ), + headers = listOf( + SirioTableCellType.Header( + title = "id", + size = SirioTableContentSize.LARGE, + alignment = SirioTableContentAlignment.START, + withCheckBox = false, + ), + SirioTableCellType.Header( + title = "Nome", + size = SirioTableContentSize.LARGE, + alignment = SirioTableContentAlignment.START, + withCheckBox = false, + ), + SirioTableCellType.Header( + title = "Cognome", + size = SirioTableContentSize.LARGE, + alignment = SirioTableContentAlignment.START, + withCheckBox = false, + ), + ), + rows = listOf( + SirioTableRowData( + cells = listOf( + SirioTableCellType.TextOnly( + text = "Id 0", + SirioTableContentSize.LARGE, + ), + SirioTableCellType.TextOnly( + text = "Nome 0", + SirioTableContentSize.LARGE, + ), + SirioTableCellType.TextOnly( + text = "Cognome 0", + SirioTableContentSize.LARGE, + ), + ) + ), + SirioTableRowData( + cells = listOf( + SirioTableCellType.TextOnly( + text = "Id 1", + SirioTableContentSize.LARGE, + ), + SirioTableCellType.TextOnly( + text = "Nome 1", + SirioTableContentSize.LARGE, + ), + SirioTableCellType.TextOnly( + text = "Cognome 1", + SirioTableContentSize.LARGE, + ), + ) + ), + SirioTableRowData( + cells = listOf( + SirioTableCellType.TextOnly( + text = "Id 2", + SirioTableContentSize.LARGE, + ), + SirioTableCellType.TextOnly( + text = "Nome 2", + SirioTableContentSize.LARGE, + ), + SirioTableCellType.TextOnly( + text = "Cognome 2", + SirioTableContentSize.LARGE, + ), + ) + ), + ), + ) + } +} \ No newline at end of file diff --git a/design/src/main/java/it/inps/sirio/ui/table/SirioTableCommon.kt b/design/src/main/java/it/inps/sirio/ui/table/SirioTableCommon.kt new file mode 100644 index 0000000..8bd4f87 --- /dev/null +++ b/design/src/main/java/it/inps/sirio/ui/table/SirioTableCommon.kt @@ -0,0 +1,127 @@ +// +// SirioTableCommon.kt +// +// SPDX-FileCopyrightText: 2022 Istituto Nazionale Previdenza Sociale +// +// SPDX-License-Identifier: BSD-3-Clause +// +package it.inps.sirio.ui.table + +import androidx.annotation.Keep +import androidx.compose.runtime.Stable +import com.guru.fontawesomecomposelib.FaIconType +import it.inps.sirio.ui.table.cell.SirioTableCellColors +import it.inps.sirio.ui.table.cell.SirioTableCellTypography +import it.inps.sirio.ui.table.cell.SirioTableComponentColors +import it.inps.sirio.ui.table.drawer.SirioTableDrawerColors +import it.inps.sirio.ui.table.drawer.SirioTableDrawerTypography +import it.inps.sirio.ui.table.vertical.SirioTableVerticalColors +import it.inps.sirio.ui.table.vertical.SirioTableVerticalTypography +import it.inps.sirio.ui.tag.TagType + +sealed class SirioTableCellType { + data class Header( + val title: String, + val size: SirioTableContentSize, + val alignment: SirioTableContentAlignment, + val scroll: Boolean = false, + val withCheckBox: Boolean = false, + val checked: Boolean = false, + val onCheckedChange: (Boolean) -> Unit = {}, + val onIconClick: () -> Unit = {}, + ) : SirioTableCellType() + + data class Avatar( + val icon: FaIconType, + val title: String, + val subtitle: String, + val size: SirioTableContentSize, + val scroll: Boolean = false, + ) : SirioTableCellType() + + data class Link( + val text: String, + val size: SirioTableContentSize, + val scroll: Boolean = false, + val onLinkClick: () -> Unit, + ) : SirioTableCellType() + + data class MultiIcons( + val size: SirioTableContentSize, + val scroll: Boolean = false, + val iconsData: List, + ) : SirioTableCellType() + + data class Number( + val text: String, + val size: SirioTableContentSize, + val checked: Boolean = false, + val scroll: Boolean = false, + val onCheckedChange: (Boolean) -> Unit = {}, + ) : SirioTableCellType() + + data class NumberOnly( + val text: String, + val size: SirioTableContentSize, + val scroll: Boolean = false, + ) : SirioTableCellType() + + data class Tag( + val text: String, + val tagType: TagType, + val size: SirioTableContentSize, + val scroll: Boolean = false, + ) : SirioTableCellType() + + data class Text( + val text: String, + val size: SirioTableContentSize, + val scroll: Boolean = false, + val checked: Boolean = false, + val onCheckedChange: (Boolean) -> Unit = {}, + ) : SirioTableCellType() + + data class TextOnly( + val text: String, + val size: SirioTableContentSize, + val scroll: Boolean = false, + ) : SirioTableCellType() +} + +@Keep +data class SirioTableColors( + val cell: SirioTableCellColors, + val component: SirioTableComponentColors, + val drawer: SirioTableDrawerColors, + val header: SirioTableHeaderColors, + val vertical: SirioTableVerticalColors, +) { + companion object { + @Stable + val Unspecified = SirioTableColors( + cell = SirioTableCellColors.Unspecified, + component = SirioTableComponentColors.Unspecified, + drawer = SirioTableDrawerColors.Unspecified, + header = SirioTableHeaderColors.Unspecified, + vertical = SirioTableVerticalColors.Unspecified, + ) + } +} + +@Keep +data class SirioTableTypography( + val cell: SirioTableCellTypography, + val drawer: SirioTableDrawerTypography, + val header: SirioTableHeaderTypography, + val vertical: SirioTableVerticalTypography, +) { + companion object { + @Stable + val Default = SirioTableTypography( + cell = SirioTableCellTypography.Default, + drawer = SirioTableDrawerTypography.Default, + header = SirioTableHeaderTypography.Default, + vertical = SirioTableVerticalTypography.Default, + ) + } +} diff --git a/design/src/main/java/it/inps/sirio/ui/table/SirioTableHeader.kt b/design/src/main/java/it/inps/sirio/ui/table/SirioTableHeader.kt new file mode 100644 index 0000000..bd18b87 --- /dev/null +++ b/design/src/main/java/it/inps/sirio/ui/table/SirioTableHeader.kt @@ -0,0 +1,233 @@ +// +// SirioTableHeader.kt +// +// SPDX-FileCopyrightText: 2022 Istituto Nazionale Previdenza Sociale +// +// SPDX-License-Identifier: BSD-3-Clause +// +package it.inps.sirio.ui.table + +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier +import androidx.compose.ui.tooling.preview.Preview +import com.guru.fontawesomecomposelib.FaIcons +import it.inps.sirio.theme.SirioTheme +import it.inps.sirio.theme.tableComponentHeightExtraSmall +import it.inps.sirio.theme.tableComponentHeightLarge +import it.inps.sirio.theme.tableComponentHeightMedium +import it.inps.sirio.theme.tableComponentHeightSmall +import it.inps.sirio.theme.tableComponentPaddingHorizontalExtraSmall +import it.inps.sirio.theme.tableComponentPaddingHorizontalLarge +import it.inps.sirio.theme.tableComponentPaddingHorizontalMedium +import it.inps.sirio.theme.tableComponentPaddingHorizontalSmall + +@Composable +fun SirioTableHeader( + title: String, + size: SirioTableContentSize, + alignment: SirioTableContentAlignment = SirioTableContentAlignment.START, + scroll: Boolean = false, + withCheckBox: Boolean = false, + checked: Boolean = false, + onCheckedChange: (Boolean) -> Unit = {}, + onIconClick: () -> Unit, +) { + val (height, horizontalPadding) = remember(size) { + when (size) { + SirioTableContentSize.EXTRASMALL -> tableComponentHeightExtraSmall to tableComponentPaddingHorizontalExtraSmall + SirioTableContentSize.SMALL -> tableComponentHeightSmall to tableComponentPaddingHorizontalSmall + SirioTableContentSize.MEDIUM -> tableComponentHeightMedium to tableComponentPaddingHorizontalMedium + SirioTableContentSize.LARGE -> tableComponentHeightLarge to tableComponentPaddingHorizontalLarge + } + } + SirioTableHeaderCommon( + title = title, + height = height, + horizontalPadding = horizontalPadding, + alignment = alignment, + scroll = scroll, + withCheckBox = withCheckBox, + checked = checked, + iconButton = FaIcons.Sort, + onCheckedChange = onCheckedChange, + onIconClick = onIconClick, + ) +} + +@Preview(heightDp = 1500) +@Composable +private fun SirioTableHeaderPreview() { + Column(Modifier.verticalScroll(rememberScrollState())) { + SirioTheme { + SirioTableHeader( + title = "Header", + size = SirioTableContentSize.LARGE, + withCheckBox = true, + checked = false, + onCheckedChange = {}, + onIconClick = {}, + ) + SirioTableHeader( + title = "Header", + size = SirioTableContentSize.LARGE, + alignment = SirioTableContentAlignment.END, + withCheckBox = true, + checked = false, + onCheckedChange = {}, + onIconClick = {}, + ) + SirioTableHeader( + title = "Header", + size = SirioTableContentSize.LARGE, + alignment = SirioTableContentAlignment.END, + scroll = true, + withCheckBox = true, + checked = false, + onCheckedChange = {}, + onIconClick = {}, + ) + SirioTableHeader( + title = "Header", + size = SirioTableContentSize.MEDIUM, + withCheckBox = true, + checked = false, + onCheckedChange = {}, + onIconClick = {}, + ) + SirioTableHeader( + title = "Header", + size = SirioTableContentSize.MEDIUM, + alignment = SirioTableContentAlignment.END, + withCheckBox = true, + checked = false, + onCheckedChange = {}, + onIconClick = {}, + ) + SirioTableHeader( + title = "Header", + size = SirioTableContentSize.MEDIUM, + alignment = SirioTableContentAlignment.END, + scroll = true, + withCheckBox = true, + checked = false, + onCheckedChange = {}, + onIconClick = {}, + ) + SirioTableHeader( + title = "Header", + size = SirioTableContentSize.SMALL, + withCheckBox = true, + checked = false, + onCheckedChange = {}, + onIconClick = {}, + ) + SirioTableHeader( + title = "Header", + size = SirioTableContentSize.SMALL, + alignment = SirioTableContentAlignment.END, + withCheckBox = true, + checked = false, + onCheckedChange = {}, + onIconClick = {}, + ) + SirioTableHeader( + title = "Header", + size = SirioTableContentSize.SMALL, + alignment = SirioTableContentAlignment.END, + scroll = true, + withCheckBox = true, + checked = false, + onCheckedChange = {}, + onIconClick = {}, + ) + } + SirioTheme(darkTheme = true) { + SirioTableHeader( + title = "Header", + size = SirioTableContentSize.LARGE, + withCheckBox = true, + checked = false, + onCheckedChange = {}, + onIconClick = {}, + ) + SirioTableHeader( + title = "Header", + size = SirioTableContentSize.LARGE, + alignment = SirioTableContentAlignment.END, + withCheckBox = true, + checked = false, + onCheckedChange = {}, + onIconClick = {}, + ) + SirioTableHeader( + title = "Header", + size = SirioTableContentSize.LARGE, + alignment = SirioTableContentAlignment.END, + scroll = true, + withCheckBox = true, + checked = false, + onCheckedChange = {}, + onIconClick = {}, + ) + SirioTableHeader( + title = "Header", + size = SirioTableContentSize.MEDIUM, + withCheckBox = true, + checked = false, + onCheckedChange = {}, + onIconClick = {}, + ) + SirioTableHeader( + title = "Header", + size = SirioTableContentSize.MEDIUM, + alignment = SirioTableContentAlignment.END, + withCheckBox = true, + checked = false, + onCheckedChange = {}, + onIconClick = {}, + ) + SirioTableHeader( + title = "Header", + size = SirioTableContentSize.MEDIUM, + alignment = SirioTableContentAlignment.END, + scroll = true, + withCheckBox = true, + checked = false, + onCheckedChange = {}, + onIconClick = {}, + ) + SirioTableHeader( + title = "Header", + size = SirioTableContentSize.SMALL, + withCheckBox = true, + checked = false, + onCheckedChange = {}, + onIconClick = {}, + ) + SirioTableHeader( + title = "Header", + size = SirioTableContentSize.SMALL, + alignment = SirioTableContentAlignment.END, + withCheckBox = true, + checked = false, + onCheckedChange = {}, + onIconClick = {}, + ) + SirioTableHeader( + title = "Header", + size = SirioTableContentSize.SMALL, + alignment = SirioTableContentAlignment.END, + scroll = true, + withCheckBox = true, + checked = false, + onCheckedChange = {}, + onIconClick = {}, + ) + } + } + +} \ No newline at end of file diff --git a/design/src/main/java/it/inps/sirio/ui/table/SirioTableHeaderCommon.kt b/design/src/main/java/it/inps/sirio/ui/table/SirioTableHeaderCommon.kt new file mode 100644 index 0000000..dee0239 --- /dev/null +++ b/design/src/main/java/it/inps/sirio/ui/table/SirioTableHeaderCommon.kt @@ -0,0 +1,221 @@ +// +// SirioTableHeaderCommon.kt +// +// SPDX-FileCopyrightText: 2022 Istituto Nazionale Previdenza Sociale +// +// SPDX-License-Identifier: BSD-3-Clause +// +package it.inps.sirio.ui.table + +import androidx.annotation.Keep +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.IntrinsicSize +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.material3.IconButton +import androidx.compose.material3.LocalContentColor +import androidx.compose.material3.Surface +import androidx.compose.runtime.Composable +import androidx.compose.runtime.Stable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.guru.fontawesomecomposelib.FaIconType +import com.guru.fontawesomecomposelib.FaIcons +import it.inps.sirio.theme.SirioTheme +import it.inps.sirio.theme.tableComponentHeightLarge +import it.inps.sirio.theme.tableComponentPaddingHorizontalLarge +import it.inps.sirio.theme.tableHeaderIconSize +import it.inps.sirio.theme.tableHeaderSpacingCheckBoxTitle +import it.inps.sirio.theme.tableHeaderSpacingTitleIcon +import it.inps.sirio.ui.checkbox.SirioCheckboxCommon +import it.inps.sirio.ui.table.cell.SirioTableComponentCommon +import it.inps.sirio.ui.text.SirioTextCommon +import it.inps.sirio.utils.SirioIcon + +@Composable +internal fun SirioTableHeaderCommon( + title: String, + height: Int, + horizontalPadding: Int, + alignment: SirioTableContentAlignment, + scroll: Boolean = false, + withCheckBox: Boolean = false, + checked: Boolean = false, + iconButton: FaIconType? = null, + onCheckedChange: (Boolean) -> Unit, + onIconClick: () -> Unit, +) { + SirioTableComponentCommon(scroll = scroll) { + Surface( + modifier = Modifier + .height(height.dp) + .fillMaxWidth(), + color = SirioTheme.colors.table.header.background, + contentColor = SirioTheme.colors.table.header.title, + ) { + Row( + modifier = Modifier + .width(IntrinsicSize.Max) + .padding(start = horizontalPadding.dp), + verticalAlignment = Alignment.CenterVertically, + ) { + if (withCheckBox) { + SirioCheckboxCommon(checked = checked, onCheckedChange = onCheckedChange) + Spacer(modifier = Modifier.width(tableHeaderSpacingCheckBoxTitle.dp)) + } + SirioTextCommon( + text = title, + modifier = Modifier.weight(1f), + color = LocalContentColor.current, + textAlign = if (alignment == SirioTableContentAlignment.START || scroll) TextAlign.Start else TextAlign.End, + overflow = TextOverflow.Ellipsis, + maxLines = 1, + typography = SirioTheme.typography.table.header.title, + ) + iconButton?.let { + Spacer(modifier = Modifier.width(tableHeaderSpacingTitleIcon.dp)) + IconButton(onClick = onIconClick) { + SirioIcon( + faIcon = it, + iconColor = SirioTheme.colors.table.header.icon, + size = tableHeaderIconSize.dp, + ) + } + } ?: Spacer(modifier = Modifier.width(horizontalPadding.dp)) + } + } + } +} + +enum class SirioTableContentSize { + EXTRASMALL, + SMALL, + MEDIUM, + LARGE, +} + +enum class SirioTableContentAlignment { + START, + END, +} + +@Keep +data class SirioTableHeaderColors( + val background: Color, + val title: Color, + val icon: Color, +) { + companion object { + @Stable + val Unspecified = SirioTableHeaderColors( + background = Color.Unspecified, + title = Color.Unspecified, + icon = Color.Unspecified, + ) + } +} + +@Keep +data class SirioTableHeaderTypography( + val title: TextStyle, +) { + companion object { + @Stable + val Default = SirioTableHeaderTypography( + title = TextStyle.Default, + ) + } +} + +@Preview +@Composable +private fun SirioTableHeaderCommonPreview() { + Column { + SirioTheme { + SirioTableHeaderCommon( + title = "Header", + height = tableComponentHeightLarge, + horizontalPadding = tableComponentPaddingHorizontalLarge, + alignment = SirioTableContentAlignment.START, + withCheckBox = true, + iconButton = FaIcons.Sort, + onCheckedChange = {}, + onIconClick = {}, + ) + SirioTableHeaderCommon( + title = "Header", + height = tableComponentHeightLarge, + horizontalPadding = tableComponentPaddingHorizontalLarge, + alignment = SirioTableContentAlignment.END, + withCheckBox = true, + iconButton = FaIcons.Sort, + onCheckedChange = {}, + onIconClick = {}, + ) + SirioTableHeaderCommon( + title = "Header", + height = tableComponentHeightLarge, + horizontalPadding = tableComponentPaddingHorizontalLarge, + alignment = SirioTableContentAlignment.START, + scroll = true, + withCheckBox = true, + iconButton = FaIcons.Sort, + onCheckedChange = {}, + onIconClick = {}, + ) + } + SirioTheme(darkTheme = true) { + SirioTableHeaderCommon( + title = "Header", + height = tableComponentHeightLarge, + horizontalPadding = tableComponentPaddingHorizontalLarge, + alignment = SirioTableContentAlignment.START, + withCheckBox = true, + iconButton = FaIcons.Sort, + onCheckedChange = {}, + onIconClick = {}, + ) + SirioTableHeaderCommon( + title = "Header", + height = tableComponentHeightLarge, + horizontalPadding = tableComponentPaddingHorizontalLarge, + alignment = SirioTableContentAlignment.END, + withCheckBox = true, + iconButton = FaIcons.Sort, + onCheckedChange = {}, + onIconClick = {}, + ) + SirioTableHeaderCommon( + title = "Header", + height = tableComponentHeightLarge, + horizontalPadding = tableComponentPaddingHorizontalLarge, + alignment = SirioTableContentAlignment.START, + scroll = true, + withCheckBox = true, + iconButton = FaIcons.Sort, + onCheckedChange = {}, + onIconClick = {}, + ) + SirioTableHeaderCommon( + title = "Header", + height = tableComponentHeightLarge, + horizontalPadding = tableComponentPaddingHorizontalLarge, + alignment = SirioTableContentAlignment.END, + scroll = true, + withCheckBox = true, + onCheckedChange = {}, + onIconClick = {}, + ) + } + } +} \ No newline at end of file diff --git a/design/src/main/java/it/inps/sirio/ui/table/SirioTableIconData.kt b/design/src/main/java/it/inps/sirio/ui/table/SirioTableIconData.kt new file mode 100644 index 0000000..8f645c8 --- /dev/null +++ b/design/src/main/java/it/inps/sirio/ui/table/SirioTableIconData.kt @@ -0,0 +1,28 @@ +// +// SirioTableIconData.kt +// +// SPDX-FileCopyrightText: 2024 Istituto Nazionale Previdenza Sociale +// +// SPDX-License-Identifier: BSD-3-Clause +// + +package it.inps.sirio.ui.table + +import androidx.annotation.Keep +import com.guru.fontawesomecomposelib.FaIconType + +/** + * The representation of a table cell icon + * + * @param icon The FA icon of the item + * @param text The text used in the sticky bottom bar popup menu + * @param action The onClick callback + * @param contentDescription The content description for the item + */ +@Keep +data class SirioTableIconData( + val icon: FaIconType, + val text: String? = null, + val action: () -> Unit, + val contentDescription: String? = null, +) \ No newline at end of file diff --git a/design/src/main/java/it/inps/sirio/ui/table/SirioTableRowData.kt b/design/src/main/java/it/inps/sirio/ui/table/SirioTableRowData.kt new file mode 100644 index 0000000..57ba09e --- /dev/null +++ b/design/src/main/java/it/inps/sirio/ui/table/SirioTableRowData.kt @@ -0,0 +1,12 @@ +// +// SirioTableRowData.kt +// +// SPDX-FileCopyrightText: 2022 Istituto Nazionale Previdenza Sociale +// +// SPDX-License-Identifier: BSD-3-Clause +// +package it.inps.sirio.ui.table + +data class SirioTableRowData( + val cells: List, +) \ No newline at end of file diff --git a/design/src/main/java/it/inps/sirio/ui/table/cell/SirioTableCellAvatar.kt b/design/src/main/java/it/inps/sirio/ui/table/cell/SirioTableCellAvatar.kt new file mode 100644 index 0000000..b175317 --- /dev/null +++ b/design/src/main/java/it/inps/sirio/ui/table/cell/SirioTableCellAvatar.kt @@ -0,0 +1,126 @@ +// +// SirioTableCellAvatar.kt +// +// SPDX-FileCopyrightText: 2022 Istituto Nazionale Previdenza Sociale +// +// SPDX-License-Identifier: BSD-3-Clause +// +package it.inps.sirio.ui.table.cell + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.width +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.guru.fontawesomecomposelib.FaIconType +import com.guru.fontawesomecomposelib.FaIcons +import it.inps.sirio.theme.SirioTheme +import it.inps.sirio.theme.tableCellAvatarImageTextSpacing +import it.inps.sirio.ui.table.SirioTableCellType +import it.inps.sirio.ui.table.SirioTableContentSize +import it.inps.sirio.ui.text.SirioTextCommon +import it.inps.sirio.utils.SirioIcon + +@Composable +fun SirioTableCellAvatar( + icon: FaIconType, + title: String, + subtitle: String, + size: SirioTableContentSize, + scroll: Boolean = false, +) { + SirioTableCellCommon(size = size, scroll = scroll) { + Row(verticalAlignment = Alignment.CenterVertically) { + SirioIcon(faIcon = icon, iconColor = Color.Unspecified) + Spacer(modifier = Modifier.width(tableCellAvatarImageTextSpacing.dp)) + Column(verticalArrangement = Arrangement.spacedBy((-6).dp)) { + SirioTextCommon( + text = title, + color = SirioTheme.colors.table.cell.avatarTitle, + overflow = TextOverflow.Ellipsis, + maxLines = 1, + typography = SirioTheme.typography.table.cell.avatarTitle, + ) + SirioTextCommon( + text = subtitle, + color = SirioTheme.colors.table.cell.avatarSubtitle, + overflow = TextOverflow.Ellipsis, + maxLines = 1, + typography = SirioTheme.typography.table.cell.avatarSubtitle, + ) + } + } + } +} + +@Composable +internal fun SirioTableCellAvatar(data: SirioTableCellType.Avatar) { + SirioTableCellAvatar( + icon = data.icon, + title = data.title, + subtitle = data.subtitle, + size = data.size, + scroll = data.scroll, + ) +} + +@Preview +@Composable +private fun SirioTableCellAvatarPreview() { + SirioTheme { + Column(Modifier.width(200.dp)) { + val icon = FaIcons.User + val title = "Avatar Name" + val subtitle = "email@mail.com" + SirioTableCellAvatar( + icon = icon, + title = title, + subtitle = subtitle, + size = SirioTableContentSize.LARGE, + scroll = false, + ) + SirioTableCellAvatar( + icon = icon, + title = title, + subtitle = subtitle, + size = SirioTableContentSize.MEDIUM, + scroll = false, + ) + SirioTableCellAvatar( + icon = icon, + title = title, + subtitle = subtitle, + size = SirioTableContentSize.SMALL, + scroll = false, + ) + SirioTableCellAvatar( + icon = icon, + title = title, + subtitle = subtitle, + size = SirioTableContentSize.LARGE, + scroll = true, + ) + SirioTableCellAvatar( + icon = icon, + title = title, + subtitle = subtitle, + size = SirioTableContentSize.MEDIUM, + scroll = true, + ) + SirioTableCellAvatar( + icon = icon, + title = title, + subtitle = subtitle, + size = SirioTableContentSize.SMALL, + scroll = true, + ) + } + } +} \ No newline at end of file diff --git a/design/src/main/java/it/inps/sirio/ui/table/cell/SirioTableCellCommon.kt b/design/src/main/java/it/inps/sirio/ui/table/cell/SirioTableCellCommon.kt new file mode 100644 index 0000000..f186336 --- /dev/null +++ b/design/src/main/java/it/inps/sirio/ui/table/cell/SirioTableCellCommon.kt @@ -0,0 +1,139 @@ +// +// SirioTableCellCommon.kt +// +// SPDX-FileCopyrightText: 2022 Istituto Nazionale Previdenza Sociale +// +// SPDX-License-Identifier: BSD-3-Clause +// +package it.inps.sirio.ui.table.cell + +import androidx.annotation.Keep +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.Surface +import androidx.compose.runtime.Composable +import androidx.compose.runtime.Stable +import androidx.compose.runtime.remember +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import it.inps.sirio.theme.SirioTheme +import it.inps.sirio.theme.tableComponentHeightExtraSmall +import it.inps.sirio.theme.tableComponentHeightLarge +import it.inps.sirio.theme.tableComponentHeightMedium +import it.inps.sirio.theme.tableComponentHeightSmall +import it.inps.sirio.theme.tableComponentPaddingHorizontalExtraSmall +import it.inps.sirio.theme.tableComponentPaddingHorizontalLarge +import it.inps.sirio.theme.tableComponentPaddingHorizontalMedium +import it.inps.sirio.theme.tableComponentPaddingHorizontalSmall +import it.inps.sirio.ui.table.SirioTableContentSize +import it.inps.sirio.ui.text.SirioTextCommon + +@Composable +internal fun SirioTableCellCommon( + size: SirioTableContentSize, + scroll: Boolean = false, + content: @Composable () -> Unit, +) { + val height = remember(size) { + when (size) { + SirioTableContentSize.EXTRASMALL -> tableComponentHeightExtraSmall + SirioTableContentSize.SMALL -> tableComponentHeightSmall + SirioTableContentSize.MEDIUM -> tableComponentHeightMedium + SirioTableContentSize.LARGE -> tableComponentHeightLarge + } + } + val horizontalPadding = remember(size) { + when (size) { + SirioTableContentSize.EXTRASMALL -> tableComponentPaddingHorizontalExtraSmall + SirioTableContentSize.SMALL -> tableComponentPaddingHorizontalSmall + SirioTableContentSize.MEDIUM -> tableComponentPaddingHorizontalMedium + SirioTableContentSize.LARGE -> tableComponentPaddingHorizontalLarge + } + } + SirioTableComponentCommon(scroll = scroll) { + Surface( + modifier = Modifier + .height(height.dp) + .fillMaxWidth(), + color = SirioTheme.colors.table.cell.background, + ) { + Box( + modifier = Modifier.padding(horizontal = horizontalPadding.dp), + contentAlignment = Alignment.CenterStart, + ) { + content() + } + } + } +} + +@Keep +data class SirioTableCellColors( + val avatarSubtitle: Color, + val avatarTitle: Color, + val background: Color, + val icon: Color, + val link: Color, + val number: Color, + val title: Color, +) { + companion object { + @Stable + val Unspecified = SirioTableCellColors( + avatarSubtitle = Color.Unspecified, + avatarTitle = Color.Unspecified, + background = Color.Unspecified, + icon = Color.Unspecified, + link = Color.Unspecified, + number = Color.Unspecified, + title = Color.Unspecified, + ) + } +} + +@Keep +data class SirioTableCellTypography( + val text: TextStyle, + val number: TextStyle, + val link: TextStyle, + val avatarTitle: TextStyle, + val avatarSubtitle: TextStyle, +) { + companion object { + @Stable + val Default = SirioTableCellTypography( + text = TextStyle.Default, + number = TextStyle.Default, + link = TextStyle.Default, + avatarTitle = TextStyle.Default, + avatarSubtitle = TextStyle.Default, + ) + } +} + +@Preview +@Composable +private fun SirioTableCellCommonPreview() { + SirioTheme { + Column { + SirioTableCellCommon( + size = SirioTableContentSize.LARGE, + ) { + SirioTextCommon(text = "Test", Modifier.weight(1f)) + } + SirioTableCellCommon( + size = SirioTableContentSize.LARGE, + scroll = true + ) { + SirioTextCommon(text = "Test") + } + } + } +} \ No newline at end of file diff --git a/design/src/main/java/it/inps/sirio/ui/table/cell/SirioTableCellLink.kt b/design/src/main/java/it/inps/sirio/ui/table/cell/SirioTableCellLink.kt new file mode 100644 index 0000000..2997294 --- /dev/null +++ b/design/src/main/java/it/inps/sirio/ui/table/cell/SirioTableCellLink.kt @@ -0,0 +1,95 @@ +// +// SirioTableCellLink.kt +// +// SPDX-FileCopyrightText: 2022 Istituto Nazionale Previdenza Sociale +// +// SPDX-License-Identifier: BSD-3-Clause +// +package it.inps.sirio.ui.table.cell + +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.width +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import it.inps.sirio.theme.SirioTheme +import it.inps.sirio.ui.table.SirioTableCellType +import it.inps.sirio.ui.table.SirioTableContentSize +import it.inps.sirio.ui.text.SirioTextCommon + +@Composable +fun SirioTableCellLink( + text: String, + size: SirioTableContentSize, + scroll: Boolean = false, + onLinkClick: () -> Unit, +) { + SirioTableCellCommon(size = size, scroll = scroll) { + SirioTextCommon( + text = text, + modifier = Modifier.clickable(onClick = onLinkClick), + color = SirioTheme.colors.table.cell.link, + overflow = TextOverflow.Ellipsis, + maxLines = 1, + typography = SirioTheme.typography.table.cell.link, + ) + } +} + +@Composable +internal fun SirioTableCellLink(data: SirioTableCellType.Link) { + SirioTableCellLink( + text = data.text, + size = data.size, + scroll = data.scroll, + onLinkClick = data.onLinkClick, + ) +} + +@Preview +@Composable +private fun SirioTableCellLinkPreview() { + SirioTheme { + Column(Modifier.width(200.dp)) { + SirioTableCellLink( + text = "Link", + size = SirioTableContentSize.LARGE, + scroll = false, + onLinkClick = {}, + ) + SirioTableCellLink( + text = "Link", + size = SirioTableContentSize.MEDIUM, + scroll = false, + onLinkClick = {}, + ) + SirioTableCellLink( + text = "Link", + size = SirioTableContentSize.SMALL, + scroll = false, + onLinkClick = {}, + ) + SirioTableCellLink( + text = "Link", + size = SirioTableContentSize.LARGE, + scroll = true, + onLinkClick = {}, + ) + SirioTableCellLink( + text = "Link", + size = SirioTableContentSize.MEDIUM, + scroll = true, + onLinkClick = {}, + ) + SirioTableCellLink( + text = "Link", + size = SirioTableContentSize.SMALL, + scroll = true, + onLinkClick = {}, + ) + } + } +} \ No newline at end of file diff --git a/design/src/main/java/it/inps/sirio/ui/table/cell/SirioTableCellMultiIcons.kt b/design/src/main/java/it/inps/sirio/ui/table/cell/SirioTableCellMultiIcons.kt new file mode 100644 index 0000000..1f3352f --- /dev/null +++ b/design/src/main/java/it/inps/sirio/ui/table/cell/SirioTableCellMultiIcons.kt @@ -0,0 +1,98 @@ +// +// SirioTableCellMultiIcons.kt +// +// SPDX-FileCopyrightText: 2022 Istituto Nazionale Previdenza Sociale +// +// SPDX-License-Identifier: BSD-3-Clause +// +package it.inps.sirio.ui.table.cell + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.tooling.preview.Preview +import com.guru.fontawesomecomposelib.FaIcons +import it.inps.sirio.theme.SirioTheme +import it.inps.sirio.ui.button.ButtonSize +import it.inps.sirio.ui.button.ButtonStyle +import it.inps.sirio.ui.button.SirioButton +import it.inps.sirio.ui.table.SirioTableCellType +import it.inps.sirio.ui.table.SirioTableContentSize +import it.inps.sirio.ui.table.SirioTableIconData + +@Composable +fun SirioTableCellMultiIcons( + size: SirioTableContentSize, + scroll: Boolean = false, + icons: List, +) { + SirioTableCellCommon(size = size, scroll = scroll) { + Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.End) { + icons.forEach { + SirioButton( + size = ButtonSize.Small, + style = ButtonStyle.Ghost, + icon = it.icon, + iconContentDescription = it.contentDescription, + onClick = it.action, + ) + } + } + } +} + +@Composable +internal fun SirioTableCellMultiIcons(data: SirioTableCellType.MultiIcons) { + SirioTableCellMultiIcons( + size = data.size, + scroll = data.scroll, + icons = data.iconsData, + ) +} + +@Preview +@Composable +private fun SirioTableCellMultiIconsPreview() { + SirioTheme { + Column { + val icons = listOf( + SirioTableIconData(FaIcons.FilePdf, action = {}), + SirioTableIconData(FaIcons.Download, action = {}), + SirioTableIconData(FaIcons.Trash, action = {}) + ) + SirioTableCellMultiIcons( + size = SirioTableContentSize.LARGE, + scroll = false, + icons = icons, + ) + SirioTableCellMultiIcons( + size = SirioTableContentSize.MEDIUM, + scroll = false, + icons = icons, + ) + SirioTableCellMultiIcons( + size = SirioTableContentSize.SMALL, + scroll = false, + icons = icons, + ) + SirioTableCellMultiIcons( + size = SirioTableContentSize.LARGE, + scroll = true, + icons = icons, + ) + SirioTableCellMultiIcons( + size = SirioTableContentSize.MEDIUM, + scroll = true, + icons = icons, + ) + SirioTableCellMultiIcons( + size = SirioTableContentSize.SMALL, + scroll = true, + icons = icons, + ) + } + } +} \ No newline at end of file diff --git a/design/src/main/java/it/inps/sirio/ui/table/cell/SirioTableCellNumber.kt b/design/src/main/java/it/inps/sirio/ui/table/cell/SirioTableCellNumber.kt new file mode 100644 index 0000000..adfb265 --- /dev/null +++ b/design/src/main/java/it/inps/sirio/ui/table/cell/SirioTableCellNumber.kt @@ -0,0 +1,119 @@ +// +// SirioTableCellNumber.kt +// +// SPDX-FileCopyrightText: 2022 Istituto Nazionale Previdenza Sociale +// +// SPDX-License-Identifier: BSD-3-Clause +// +package it.inps.sirio.ui.table.cell + +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.selection.toggleable +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.semantics.Role +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.tooling.preview.Preview +import it.inps.sirio.theme.SirioTheme +import it.inps.sirio.ui.checkbox.SirioCheckboxCommon +import it.inps.sirio.ui.table.SirioTableCellType +import it.inps.sirio.ui.table.SirioTableContentSize +import it.inps.sirio.ui.text.SirioTextCommon + +@Composable +fun SirioTableCellNumber( + text: String, + size: SirioTableContentSize, + checked: Boolean = false, + scroll: Boolean = false, + onCheckedChange: (Boolean) -> Unit, +) { + SirioTableCellCommon(size = size, scroll = scroll) { + Row( + Modifier.toggleable( + value = checked, + role = Role.Checkbox, + onValueChange = onCheckedChange + ), + verticalAlignment = Alignment.CenterVertically, + ) { + SirioCheckboxCommon( + checked = checked + ) {} + SirioTextCommon( + text = text, + modifier = Modifier.weight(1f), + color = SirioTheme.colors.table.cell.number, + textAlign = TextAlign.End, + overflow = TextOverflow.Ellipsis, + maxLines = 1, + typography = SirioTheme.typography.table.cell.number, + ) + } + } +} + +@Composable +internal fun SirioTableCellNumber(data: SirioTableCellType.Number) { + SirioTableCellNumber( + text = data.text, + size = data.size, + checked = data.checked, + scroll = data.scroll, + onCheckedChange = data.onCheckedChange + ) +} + +@Preview +@Composable +private fun SirioTableCellNumberPreview() { + SirioTheme { + Column { + SirioTableCellNumber( + text = "00", + size = SirioTableContentSize.LARGE, + checked = true, + scroll = false, + onCheckedChange = {} + ) + SirioTableCellNumber( + text = "00", + size = SirioTableContentSize.MEDIUM, + checked = true, + scroll = false, + onCheckedChange = {} + ) + SirioTableCellNumber( + text = "00", + size = SirioTableContentSize.SMALL, + checked = true, + scroll = false, + onCheckedChange = {} + ) + SirioTableCellNumber( + text = "00", + size = SirioTableContentSize.LARGE, + checked = true, + scroll = true, + onCheckedChange = {} + ) + SirioTableCellNumber( + text = "00", + size = SirioTableContentSize.MEDIUM, + checked = true, + scroll = true, + onCheckedChange = {} + ) + SirioTableCellNumber( + text = "00", + size = SirioTableContentSize.SMALL, + checked = true, + scroll = true, + onCheckedChange = {} + ) + } + } +} \ No newline at end of file diff --git a/design/src/main/java/it/inps/sirio/ui/table/cell/SirioTableCellNumberOnly.kt b/design/src/main/java/it/inps/sirio/ui/table/cell/SirioTableCellNumberOnly.kt new file mode 100644 index 0000000..d0d8228 --- /dev/null +++ b/design/src/main/java/it/inps/sirio/ui/table/cell/SirioTableCellNumberOnly.kt @@ -0,0 +1,90 @@ +// +// SirioTableCellNumberOnly.kt +// +// SPDX-FileCopyrightText: 2022 Istituto Nazionale Previdenza Sociale +// +// SPDX-License-Identifier: BSD-3-Clause +// +package it.inps.sirio.ui.table.cell + +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.width +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import it.inps.sirio.theme.SirioTheme +import it.inps.sirio.ui.table.SirioTableCellType +import it.inps.sirio.ui.table.SirioTableContentSize +import it.inps.sirio.ui.text.SirioTextCommon + +@Composable +fun SirioTableCellNumberOnly( + text: String, + size: SirioTableContentSize, + scroll: Boolean = false, +) { + SirioTableCellCommon(size = size, scroll = scroll) { + SirioTextCommon( + text = text, + modifier = Modifier.fillMaxWidth(), + color = SirioTheme.colors.table.cell.number, + textAlign = TextAlign.End, + overflow = TextOverflow.Ellipsis, + maxLines = 1, + typography = SirioTheme.typography.table.cell.number, + ) + } +} + +@Composable +internal fun SirioTableCellNumberOnly(data: SirioTableCellType.NumberOnly) { + SirioTableCellNumberOnly( + text = data.text, + size = data.size, + scroll = data.scroll, + ) +} + +@Preview +@Composable +private fun SirioTableCellNumberOnlyPreview() { + SirioTheme { + Column(Modifier.width(200.dp)) { + val text = "00" + SirioTableCellNumberOnly( + text = text, + size = SirioTableContentSize.LARGE, + scroll = false, + ) + SirioTableCellNumberOnly( + text = text, + size = SirioTableContentSize.MEDIUM, + scroll = false, + ) + SirioTableCellNumberOnly( + text = text, + size = SirioTableContentSize.SMALL, + scroll = false, + ) + SirioTableCellNumberOnly( + text = text, + size = SirioTableContentSize.LARGE, + scroll = true, + ) + SirioTableCellNumberOnly( + text = text, + size = SirioTableContentSize.MEDIUM, + scroll = true, + ) + SirioTableCellNumberOnly( + text = text, + size = SirioTableContentSize.SMALL, + scroll = true, + ) + } + } +} \ No newline at end of file diff --git a/design/src/main/java/it/inps/sirio/ui/table/cell/SirioTableCellTag.kt b/design/src/main/java/it/inps/sirio/ui/table/cell/SirioTableCellTag.kt new file mode 100644 index 0000000..de38e5f --- /dev/null +++ b/design/src/main/java/it/inps/sirio/ui/table/cell/SirioTableCellTag.kt @@ -0,0 +1,88 @@ +// +// SirioTableCellTag.kt +// +// SPDX-FileCopyrightText: 2022 Istituto Nazionale Previdenza Sociale +// +// SPDX-License-Identifier: BSD-3-Clause +// +package it.inps.sirio.ui.table.cell + +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.width +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import it.inps.sirio.theme.SirioTheme +import it.inps.sirio.ui.table.SirioTableCellType +import it.inps.sirio.ui.table.SirioTableContentSize +import it.inps.sirio.ui.tag.SirioTag +import it.inps.sirio.ui.tag.TagType + +@Composable +fun SirioTableCellTag( + text: String, + tagType: TagType, + size: SirioTableContentSize, + scroll: Boolean = false, +) { + SirioTableCellCommon(size = size, scroll = scroll) { + SirioTag(text = text, tagType = tagType) + } +} + +@Composable +internal fun SirioTableCellTag(data: SirioTableCellType.Tag) { + SirioTableCellTag( + text = data.text, + tagType = data.tagType, + size = data.size, + scroll = data.scroll, + ) +} + +@Preview +@Composable +private fun SirioTableCellTagPreview() { + SirioTheme { + Column(Modifier.width(200.dp)) { + val text = "Label Tag" + SirioTableCellTag( + text = text, + tagType = TagType.GRAY, + size = SirioTableContentSize.LARGE, + scroll = false, + ) + SirioTableCellTag( + text = text, + tagType = TagType.GRAY, + size = SirioTableContentSize.MEDIUM, + scroll = false, + ) + SirioTableCellTag( + text = text, + tagType = TagType.GRAY, + size = SirioTableContentSize.SMALL, + scroll = false, + ) + SirioTableCellTag( + text = text, + tagType = TagType.GRAY, + size = SirioTableContentSize.LARGE, + scroll = true, + ) + SirioTableCellTag( + text = text, + tagType = TagType.GRAY, + size = SirioTableContentSize.MEDIUM, + scroll = true, + ) + SirioTableCellTag( + text = text, + tagType = TagType.GRAY, + size = SirioTableContentSize.SMALL, + scroll = true, + ) + } + } +} \ No newline at end of file diff --git a/design/src/main/java/it/inps/sirio/ui/table/cell/SirioTableCellText.kt b/design/src/main/java/it/inps/sirio/ui/table/cell/SirioTableCellText.kt new file mode 100644 index 0000000..a3b6d08 --- /dev/null +++ b/design/src/main/java/it/inps/sirio/ui/table/cell/SirioTableCellText.kt @@ -0,0 +1,98 @@ +// +// SirioTableCellText.kt +// +// SPDX-FileCopyrightText: 2022 Istituto Nazionale Previdenza Sociale +// +// SPDX-License-Identifier: BSD-3-Clause +// +package it.inps.sirio.ui.table.cell + +import androidx.compose.foundation.layout.Column +import androidx.compose.runtime.Composable +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.tooling.preview.Preview +import it.inps.sirio.theme.SirioTheme +import it.inps.sirio.ui.checkbox.SirioCheckboxCommon +import it.inps.sirio.ui.table.SirioTableCellType +import it.inps.sirio.ui.table.SirioTableContentSize + +@Composable +fun SirioTableCellText( + text: String, + size: SirioTableContentSize, + scroll: Boolean = false, + checked: Boolean = false, + onCheckedChange: (Boolean) -> Unit, +) { + SirioTableCellCommon(size = size, scroll = scroll) { + SirioCheckboxCommon( + checked = checked, + text = text, + overflow = TextOverflow.Ellipsis, + maxLines = 1, + onCheckedChange = onCheckedChange + ) + } +} + +@Composable +internal fun SirioTableCellText(data: SirioTableCellType.Text) { + SirioTableCellText( + text = data.text, + size = data.size, + scroll = data.scroll, + checked = data.checked, + onCheckedChange = data.onCheckedChange, + ) +} + +@Preview +@Composable +private fun SirioTableCellTextPreview() { + SirioTheme { + Column { + SirioTableCellText( + text = "Title", + size = SirioTableContentSize.LARGE, + scroll = false, + checked = true, + onCheckedChange = {} + ) + SirioTableCellText( + text = "Title", + size = SirioTableContentSize.MEDIUM, + scroll = false, + checked = true, + onCheckedChange = {} + ) + SirioTableCellText( + text = "Title", + size = SirioTableContentSize.SMALL, + scroll = false, + checked = true, + onCheckedChange = {} + ) + SirioTableCellText( + text = "Title", + size = SirioTableContentSize.LARGE, + scroll = true, + checked = true, + onCheckedChange = {} + ) + SirioTableCellText( + text = "Title", + size = SirioTableContentSize.MEDIUM, + scroll = true, + checked = true, + onCheckedChange = {} + ) + SirioTableCellText( + text = "Title", + size = SirioTableContentSize.SMALL, + scroll = true, + checked = true, + onCheckedChange = {} + ) + } + } +} \ No newline at end of file diff --git a/design/src/main/java/it/inps/sirio/ui/table/cell/SirioTableCellTextOnly.kt b/design/src/main/java/it/inps/sirio/ui/table/cell/SirioTableCellTextOnly.kt new file mode 100644 index 0000000..6016b59 --- /dev/null +++ b/design/src/main/java/it/inps/sirio/ui/table/cell/SirioTableCellTextOnly.kt @@ -0,0 +1,82 @@ +// +// SirioTableCellTextOnly.kt +// +// SPDX-FileCopyrightText: 2022 Istituto Nazionale Previdenza Sociale +// +// SPDX-License-Identifier: BSD-3-Clause +// +package it.inps.sirio.ui.table.cell + +import androidx.compose.foundation.layout.Column +import androidx.compose.runtime.Composable +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.tooling.preview.Preview +import it.inps.sirio.theme.SirioTheme +import it.inps.sirio.ui.table.SirioTableCellType +import it.inps.sirio.ui.table.SirioTableContentSize +import it.inps.sirio.ui.text.SirioTextCommon + +@Composable +fun SirioTableCellTextOnly( + text: String, + size: SirioTableContentSize, + scroll: Boolean = false, +) { + SirioTableCellCommon(size = size, scroll = scroll) { + SirioTextCommon( + text = text, + color = SirioTheme.colors.table.cell.title, + overflow = TextOverflow.Ellipsis, + maxLines = 1, + typography = SirioTheme.typography.table.cell.text, + ) + } +} + +@Composable +internal fun SirioTableCellTextOnly(data: SirioTableCellType.TextOnly) { + SirioTableCellTextOnly( + text = data.text, + size = data.size, + scroll = data.scroll, + ) +} + +@Preview +@Composable +private fun SirioTableCellTextOnlyPreview() { + SirioTheme { + Column { + SirioTableCellTextOnly( + text = "Lorem ipsum", + size = SirioTableContentSize.LARGE, + scroll = false, + ) + SirioTableCellTextOnly( + text = "Lorem ipsum", + size = SirioTableContentSize.MEDIUM, + scroll = false, + ) + SirioTableCellTextOnly( + text = "Lorem ipsum", + size = SirioTableContentSize.SMALL, + scroll = false, + ) + SirioTableCellTextOnly( + text = "Lorem ipsum", + size = SirioTableContentSize.LARGE, + scroll = true, + ) + SirioTableCellTextOnly( + text = "Lorem ipsum", + size = SirioTableContentSize.MEDIUM, + scroll = true, + ) + SirioTableCellTextOnly( + text = "Lorem ipsum", + size = SirioTableContentSize.SMALL, + scroll = true, + ) + } + } +} \ No newline at end of file diff --git a/design/src/main/java/it/inps/sirio/ui/table/cell/SirioTableComponentCommon.kt b/design/src/main/java/it/inps/sirio/ui/table/cell/SirioTableComponentCommon.kt new file mode 100644 index 0000000..a22c790 --- /dev/null +++ b/design/src/main/java/it/inps/sirio/ui/table/cell/SirioTableComponentCommon.kt @@ -0,0 +1,80 @@ +// +// SirioTableComponentCommon.kt +// +// SPDX-FileCopyrightText: 2022 Istituto Nazionale Previdenza Sociale +// +// SPDX-License-Identifier: BSD-3-Clause +// +package it.inps.sirio.ui.table.cell + +import androidx.annotation.Keep +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.runtime.Composable +import androidx.compose.runtime.Stable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import it.inps.sirio.theme.SirioTheme +import it.inps.sirio.theme.tableComponentBorderWidth +import it.inps.sirio.theme.tableComponentScrollIndicatorWidth +import it.inps.sirio.ui.text.SirioTextCommon +import it.inps.sirio.utils.Border +import it.inps.sirio.utils.border + +@Composable +internal fun SirioTableComponentCommon( + scroll: Boolean = false, + content: @Composable () -> Unit, +) { + val tableBorder = Border( + strokeWidth = tableComponentBorderWidth.dp, + color = SirioTheme.colors.table.component.border + ) + val scrollBorder = Border( + strokeWidth = tableComponentScrollIndicatorWidth.dp, + color = SirioTheme.colors.table.component.scrollIndicator + ) + val endBorder = if (scroll) scrollBorder else tableBorder + Box( + Modifier + .border(bottom = tableBorder) + .border(end = endBorder), + contentAlignment = Alignment.CenterStart, + ) { + content() + } +} + +@Keep +data class SirioTableComponentColors( + val border: Color, + val scrollIndicator: Color, +) { + companion object { + @Stable + val Unspecified = SirioTableComponentColors( + border = Color.Unspecified, + scrollIndicator = Color.Unspecified, + ) + } +} + +@Preview +@Composable +private fun SirioTableComponentCommonPreview() { + SirioTheme { + Column { + SirioTableComponentCommon { + SirioTextCommon(text = "Test") + } + SirioTableComponentCommon( + scroll = true + ) { + SirioTextCommon(text = "Test") + } + } + } +} \ No newline at end of file diff --git a/design/src/main/java/it/inps/sirio/ui/table/drawer/SirioTableDrawer.kt b/design/src/main/java/it/inps/sirio/ui/table/drawer/SirioTableDrawer.kt new file mode 100644 index 0000000..2400d1b --- /dev/null +++ b/design/src/main/java/it/inps/sirio/ui/table/drawer/SirioTableDrawer.kt @@ -0,0 +1,154 @@ +// +// SirioTableDrawer.kt +// +// SPDX-FileCopyrightText: 2022 Istituto Nazionale Previdenza Sociale +// +// SPDX-License-Identifier: BSD-3-Clause +// +package it.inps.sirio.ui.table.drawer + +import androidx.annotation.Keep +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items +import androidx.compose.runtime.Composable +import androidx.compose.runtime.Stable +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.guru.fontawesomecomposelib.FaIcons +import it.inps.sirio.theme.SirioTheme +import it.inps.sirio.theme.tableDrawerPaddingHorizontal +import it.inps.sirio.theme.tableDrawerPaddingTitle +import it.inps.sirio.theme.tableDrawerPaddingTop +import it.inps.sirio.ui.table.SirioTableIconData + +@Composable +fun SirioTableDrawer( + title: String, + closeContentDescription: String? = null, + data: List, + icons: List = emptyList(), + onClose: () -> Unit, +) { + Column( + modifier = Modifier + .background(SirioTheme.colors.table.drawer.background) + ) { + Column( + modifier = Modifier + .weight(1f) + .padding(horizontal = tableDrawerPaddingHorizontal.dp) + .padding(top = tableDrawerPaddingTop.dp) + ) { + SirioTableDrawerHeader( + title = title, + closeContentDescription = closeContentDescription, + onClose = onClose, + ) + Spacer(modifier = Modifier.height(tableDrawerPaddingTitle.dp)) + LazyColumn(modifier = Modifier.fillMaxHeight()) { + items(data) { + SirioTableDrawerItem(data = it) + } + } + } + if (icons.isNotEmpty()) { + SirioTableDrawerStickyBottomBar(icons) + } + } +} + +@Keep +data class SirioTableDrawerColors( + val actionsText: Color, + val background: Color, + val border: Color, + val iconsBackground: Color, + val title: Color, + val itemTitle: Color, + val itemText: Color, + val itemNumber: Color, + val itemLink: Color, +) { + companion object { + @Stable + val Unspecified = SirioTableDrawerColors( + actionsText = Color.Unspecified, + background = Color.Unspecified, + border = Color.Unspecified, + iconsBackground = Color.Unspecified, + title = Color.Unspecified, + itemTitle = Color.Unspecified, + itemText = Color.Unspecified, + itemNumber = Color.Unspecified, + itemLink = Color.Unspecified, + ) + } +} + +@Keep +data class SirioTableDrawerTypography( + val actionsText: TextStyle, + val title: TextStyle, + val itemTitle: TextStyle, + val itemText: TextStyle, + val itemNumber: TextStyle, + val itemLink: TextStyle, +) { + companion object { + @Stable + val Default = SirioTableDrawerTypography( + actionsText = TextStyle.Default, + title = TextStyle.Default, + itemTitle = TextStyle.Default, + itemText = TextStyle.Default, + itemNumber = TextStyle.Default, + itemLink = TextStyle.Default, + ) + } +} + +@Preview +@Composable +private fun SirioTableDrawerPreview() { + SirioTheme { + SirioTableDrawer( + title = "Titolo 1", + onClose = {}, + data = listOf( + SirioTableDrawerItemData( + title = "Titolo colonna di dettaglio", + text = "Suspendisse purus lectus, accumsan vitae malesuada lobortis, maximus vel enim. Proin nulla augue, ultricies quis mattis at, fringilla id sem.", + type = SirioTableDrawerItemType.TEXT, + onClick = {} + ), + SirioTableDrawerItemData( + title = "Titolo colonna di dettaglio", + text = "11/03/2023", + type = SirioTableDrawerItemType.NUMBER, + onClick = {} + ), + SirioTableDrawerItemData( + title = "Titolo colonna di dettaglio", + text = "Lorem Ipsum dolor sit amet", + type = SirioTableDrawerItemType.LINK, + onClick = {} + ) + ), + icons = listOf( + SirioTableIconData(FaIcons.Print, action = {}), + SirioTableIconData(FaIcons.Download, action = {}), + SirioTableIconData(FaIcons.Trash, action = {}), + SirioTableIconData(FaIcons.Trash, action = {}), + ) + ) + } +} \ No newline at end of file diff --git a/design/src/main/java/it/inps/sirio/ui/table/drawer/SirioTableDrawerHeader.kt b/design/src/main/java/it/inps/sirio/ui/table/drawer/SirioTableDrawerHeader.kt new file mode 100644 index 0000000..e105024 --- /dev/null +++ b/design/src/main/java/it/inps/sirio/ui/table/drawer/SirioTableDrawerHeader.kt @@ -0,0 +1,61 @@ +// +// SirioTableDrawerHeader.kt +// +// SPDX-FileCopyrightText: 2022 Istituto Nazionale Previdenza Sociale +// +// SPDX-License-Identifier: BSD-3-Clause +// +package it.inps.sirio.ui.table.drawer + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.guru.fontawesomecomposelib.FaIcons +import it.inps.sirio.theme.SirioTheme +import it.inps.sirio.theme.tableDrawerPaddingTitle +import it.inps.sirio.ui.button.ButtonSize +import it.inps.sirio.ui.button.ButtonStyle +import it.inps.sirio.ui.button.SirioButton +import it.inps.sirio.ui.text.SirioText + +@Composable +fun SirioTableDrawerHeader( + title: String, + closeContentDescription: String?, + onClose: () -> Unit, +) { + Column( + Modifier + .fillMaxWidth() + .background(SirioTheme.colors.table.drawer.background)) { + SirioButton( + modifier = Modifier.align(Alignment.End), + size = ButtonSize.Large, + style = ButtonStyle.Ghost, + icon = FaIcons.Times, + iconContentDescription = closeContentDescription, + onClick = onClose, + ) + Spacer(modifier = Modifier.height(tableDrawerPaddingTitle.dp)) + SirioText( + text = title, + color = SirioTheme.colors.table.drawer.title, + typography = SirioTheme.typography.table.drawer.title, + ) + } +} + +@Preview +@Composable +private fun SirioTableDrawerHeaderPreview() { + SirioTheme { + SirioTableDrawerHeader(title = "Titolo", closeContentDescription = null, onClose = {}) + } +} \ No newline at end of file diff --git a/design/src/main/java/it/inps/sirio/ui/table/drawer/SirioTableDrawerItem.kt b/design/src/main/java/it/inps/sirio/ui/table/drawer/SirioTableDrawerItem.kt new file mode 100644 index 0000000..ee8d191 --- /dev/null +++ b/design/src/main/java/it/inps/sirio/ui/table/drawer/SirioTableDrawerItem.kt @@ -0,0 +1,96 @@ +// +// SirioTableDrawerItem.kt +// +// SPDX-FileCopyrightText: 2022 Istituto Nazionale Previdenza Sociale +// +// SPDX-License-Identifier: BSD-3-Clause +// +package it.inps.sirio.ui.table.drawer + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import it.inps.sirio.theme.SirioTheme +import it.inps.sirio.theme.tableDrawerItemBorderWidth +import it.inps.sirio.theme.tableDrawerItemPaddingInternal +import it.inps.sirio.theme.tableDrawerItemPaddingVertical +import it.inps.sirio.ui.text.SirioText +import it.inps.sirio.utils.Border +import it.inps.sirio.utils.border + +@Composable +internal fun SirioTableDrawerItem(data: SirioTableDrawerItemData) { + val drawerTypography = SirioTheme.typography.table.drawer + val drawerColor = SirioTheme.colors.table.drawer + val (typography, color) = remember(data.type) { + when (data.type) { + SirioTableDrawerItemType.TEXT -> drawerTypography.itemText to drawerColor.itemText + SirioTableDrawerItemType.NUMBER -> drawerTypography.itemNumber to drawerColor.itemNumber + SirioTableDrawerItemType.LINK -> drawerTypography.itemLink to drawerColor.itemLink + } + } + Column( + modifier = Modifier + .fillMaxWidth() + .border(bottom = Border(tableDrawerItemBorderWidth.dp, drawerColor.border)) + .padding(vertical = tableDrawerItemPaddingVertical.dp) + ) { + SirioText( + text = data.title, + typography = drawerTypography.itemTitle, + color = drawerColor.itemTitle, + ) + Spacer(modifier = Modifier.height(tableDrawerItemPaddingInternal.dp)) + SirioText( + text = data.text, + typography = typography, + color = color, + ) + } +} + +enum class SirioTableDrawerItemType { + TEXT, NUMBER, LINK, +} + +@Preview +@Composable +private fun SirioTableDrawerItemPreview() { + SirioTheme { + Column(Modifier.background(Color.White)) { + SirioTableDrawerItem( + SirioTableDrawerItemData( + title = "Titolo colonna di dettaglio", + text = "Suspendisse purus lectus, accumsan vitae malesuada lobortis, maximus vel enim. Proin nulla augue, ultricies quis mattis at, fringilla id sem.", + type = SirioTableDrawerItemType.TEXT, + onClick = {} + ) + ) + SirioTableDrawerItem( + SirioTableDrawerItemData( + title = "Titolo colonna di dettaglio", + text = "11/03/2023", + type = SirioTableDrawerItemType.NUMBER, + onClick = {} + ) + ) + SirioTableDrawerItem( + SirioTableDrawerItemData( + title = "Titolo colonna di dettaglio", + text = "Lorem Ipsum dolor sit amet", + type = SirioTableDrawerItemType.LINK, + onClick = {} + ) + ) + } + } +} \ No newline at end of file diff --git a/design/src/main/java/it/inps/sirio/ui/table/drawer/SirioTableDrawerItemData.kt b/design/src/main/java/it/inps/sirio/ui/table/drawer/SirioTableDrawerItemData.kt new file mode 100644 index 0000000..a9dfcc0 --- /dev/null +++ b/design/src/main/java/it/inps/sirio/ui/table/drawer/SirioTableDrawerItemData.kt @@ -0,0 +1,15 @@ +// +// SirioTableDrawerItemData.kt +// +// SPDX-FileCopyrightText: 2022 Istituto Nazionale Previdenza Sociale +// +// SPDX-License-Identifier: BSD-3-Clause +// +package it.inps.sirio.ui.table.drawer + +data class SirioTableDrawerItemData( + val title: String, + val text: String, + val type: SirioTableDrawerItemType, + val onClick: () -> Unit, +) \ No newline at end of file diff --git a/design/src/main/java/it/inps/sirio/ui/table/drawer/SirioTableDrawerStickyBottomBar.kt b/design/src/main/java/it/inps/sirio/ui/table/drawer/SirioTableDrawerStickyBottomBar.kt new file mode 100644 index 0000000..eadea63 --- /dev/null +++ b/design/src/main/java/it/inps/sirio/ui/table/drawer/SirioTableDrawerStickyBottomBar.kt @@ -0,0 +1,144 @@ +// +// SirioTableDrawerStickyBottomBar.kt +// +// SPDX-FileCopyrightText: 2022 Istituto Nazionale Previdenza Sociale +// +// SPDX-License-Identifier: BSD-3-Clause +// +package it.inps.sirio.ui.table.drawer + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.wrapContentSize +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.DpOffset +import androidx.compose.ui.unit.dp +import com.guru.fontawesomecomposelib.FaIcons +import it.inps.sirio.theme.SirioTheme +import it.inps.sirio.theme.tableDrawerIconsPaddingHorizontal +import it.inps.sirio.theme.tableDrawerIconsPaddingVertical +import it.inps.sirio.ui.button.ButtonSize +import it.inps.sirio.ui.button.ButtonStyle +import it.inps.sirio.ui.button.SirioButton +import it.inps.sirio.ui.dropdown.SirioDropdownOptionItem +import it.inps.sirio.ui.dropdown.SirioPopup +import it.inps.sirio.ui.dropdown.SirioPopupState +import it.inps.sirio.ui.table.SirioTableIconData +import it.inps.sirio.ui.text.SirioText + +@Composable +fun SirioTableDrawerStickyBottomBar(icons: List) { + Row( + modifier = Modifier + .fillMaxWidth() + .background(SirioTheme.colors.table.drawer.iconsBackground) + .padding( + vertical = tableDrawerIconsPaddingVertical.dp, + horizontal = tableDrawerIconsPaddingHorizontal.dp + ), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.End, + ) { + if (icons.size < 4) { + icons.forEach { + SirioButton( + size = ButtonSize.Large, + style = ButtonStyle.Primary, + icon = it.icon, + iconContentDescription = it.contentDescription, + onClick = it.action, + ) + } + } else { + SirioText( + text = "Azioni", + color = SirioTheme.colors.table.drawer.actionsText, + typography = SirioTheme.typography.table.drawer.actionsText, + ) + Spacer(modifier = Modifier.weight(1f)) + Box(modifier = Modifier.wrapContentSize(Alignment.TopEnd)) { +// SirioDropdown( +// expanded = dropdownOpen, +// onDismissRequest = { dropdownOpen = false }, +// offset = DpOffset(0.dp, (-30).dp) +// ) { +// icons.forEach { icon -> +// icon.text?.let { +// SirioDropdownOptionItem( +// text = it, +// enabled = true, +// selected = false, +// onCLick = { +// dropdownOpen = false +// icon.action() +// } +// ) +// } +// } +// } + + val sirioPopupState: SirioPopupState = remember { SirioPopupState(false) } + sirioPopupState.isTop = true + sirioPopupState.horizontalAlignment = Alignment.End + SirioPopup( + sirioPopupState = sirioPopupState, + onDismissRequest = { sirioPopupState.isVisible = false }, + offset = DpOffset(0.dp, 8.dp), + ) { + icons.forEach { icon -> + icon.text?.let { + SirioDropdownOptionItem( + text = it, + enabled = true, + selected = false, + onCLick = { + icon.action() + sirioPopupState.isVisible = false + } + ) + } + } + } + SirioButton( + size = ButtonSize.Large, + style = ButtonStyle.Primary, + icon = FaIcons.EllipsisH, + onClick = { + sirioPopupState.isVisible = true + }, + ) + } + } + } +} + +@Preview +@Composable +private fun SirioTableDrawerStickyBottomBarPreview() { + val icons = listOf( + SirioTableIconData(FaIcons.Print, action = {}), + SirioTableIconData(FaIcons.Download, action = {}), + SirioTableIconData(FaIcons.Trash, action = {}), + SirioTableIconData(FaIcons.Trash, action = {}), + ) + SirioTheme { + Box( + Modifier + .fillMaxWidth() + .height(400.dp), + contentAlignment = Alignment.BottomCenter, + ) { + SirioTableDrawerStickyBottomBar(icons = icons) + } + } +} \ No newline at end of file diff --git a/design/src/main/java/it/inps/sirio/ui/table/vertical/SirioTableVertical.kt b/design/src/main/java/it/inps/sirio/ui/table/vertical/SirioTableVertical.kt new file mode 100644 index 0000000..4354a54 --- /dev/null +++ b/design/src/main/java/it/inps/sirio/ui/table/vertical/SirioTableVertical.kt @@ -0,0 +1,109 @@ +// +// SirioTableVertical.kt +// +// SPDX-FileCopyrightText: 2022 Istituto Nazionale Previdenza Sociale +// +// SPDX-License-Identifier: BSD-3-Clause +// +package it.inps.sirio.ui.table.vertical + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items +import androidx.compose.runtime.Composable +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.guru.fontawesomecomposelib.FaIcons +import it.inps.sirio.theme.SirioTheme +import it.inps.sirio.theme.tableVerticalPaddingCells +import it.inps.sirio.theme.tableVerticalPaddingHorizontal +import it.inps.sirio.ui.table.SirioTableIconData + +@Composable +fun SirioTableVertical(cells: List) { + LazyColumn( + contentPadding = PaddingValues(horizontal = tableVerticalPaddingHorizontal.dp), + verticalArrangement = Arrangement.spacedBy(tableVerticalPaddingCells.dp) + ) { + items(cells) { cellData -> + SirioTableVerticalCell(cellData = cellData) + } + } +} + +@Preview +@Composable +private fun SirioTableVerticalPreview() { + SirioTheme { + val icons = listOf( + SirioTableIconData(FaIcons.FilePdf, action = {}), + SirioTableIconData(FaIcons.Download, action = {}), + SirioTableIconData(FaIcons.Trash, action = {}) + ) + SirioTableVertical( + cells = listOf( + SirioTableVerticalCellData( + items = listOf( + SirioTableVerticalCellItemData( + "Header", + "Link", + SirioTableVerticalCellItemType.LINK + ), + SirioTableVerticalCellItemData( + "Header", + "Lorem ipsum", + SirioTableVerticalCellItemType.TEXT + ), + SirioTableVerticalCellItemData( + "Header", + "00", + SirioTableVerticalCellItemType.NUMBER + ), + SirioTableVerticalCellItemData( + "Header", + "Lorem ipsum", + SirioTableVerticalCellItemType.TEXT + ), + SirioTableVerticalCellItemData( + "Header", + "Label Tag", + SirioTableVerticalCellItemType.TAG + ), + ), + icons = icons, + ), + SirioTableVerticalCellData( + items = listOf( + SirioTableVerticalCellItemData( + "Header", + "Link", + SirioTableVerticalCellItemType.LINK + ), + SirioTableVerticalCellItemData( + "Header", + "Lorem ipsum", + SirioTableVerticalCellItemType.TEXT + ), + SirioTableVerticalCellItemData( + "Header", + "00", + SirioTableVerticalCellItemType.NUMBER + ), + SirioTableVerticalCellItemData( + "Header", + "Lorem ipsum", + SirioTableVerticalCellItemType.TEXT + ), + SirioTableVerticalCellItemData( + "Header", + "Label Tag", + SirioTableVerticalCellItemType.TAG + ), + ), + icons = icons, + ), + ), + ) + } +} \ No newline at end of file diff --git a/design/src/main/java/it/inps/sirio/ui/table/vertical/SirioTableVerticalCell.kt b/design/src/main/java/it/inps/sirio/ui/table/vertical/SirioTableVerticalCell.kt new file mode 100644 index 0000000..13092f2 --- /dev/null +++ b/design/src/main/java/it/inps/sirio/ui/table/vertical/SirioTableVerticalCell.kt @@ -0,0 +1,97 @@ +// +// SirioTableVerticalCell.kt +// +// SPDX-FileCopyrightText: 2022 Istituto Nazionale Previdenza Sociale +// +// SPDX-License-Identifier: BSD-3-Clause +// +package it.inps.sirio.ui.table.vertical + +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.guru.fontawesomecomposelib.FaIcons +import it.inps.sirio.theme.SirioTheme +import it.inps.sirio.theme.tableVerticalItemBorderWidth +import it.inps.sirio.ui.button.ButtonSize +import it.inps.sirio.ui.button.ButtonStyle +import it.inps.sirio.ui.button.SirioButton +import it.inps.sirio.ui.table.SirioTableIconData + +@Composable +fun SirioTableVerticalCell(cellData: SirioTableVerticalCellData) { + Column( + Modifier + .background(SirioTheme.colors.table.vertical.background) + .border(tableVerticalItemBorderWidth.dp, SirioTheme.colors.table.vertical.border) + ) { + cellData.items.forEach { item -> + SirioTableVerticalCellItem(data = item) + } + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.End, + ) { + cellData.icons.forEach { + SirioButton( + size = ButtonSize.Small, + style = ButtonStyle.Ghost, + icon = it.icon, + iconContentDescription = it.contentDescription, + onClick = it.action, + ) + } + } + } +} + +@Preview +@Composable +private fun SirioTableVerticalPreview() { + SirioTheme { + val icons = listOf( + SirioTableIconData(FaIcons.FilePdf, action = {}), + SirioTableIconData(FaIcons.Download, action = {}), + SirioTableIconData(FaIcons.Trash, action = {}) + ) + SirioTableVerticalCell( + SirioTableVerticalCellData( + items = listOf( + SirioTableVerticalCellItemData( + "Header", + "Link", + SirioTableVerticalCellItemType.LINK + ), + SirioTableVerticalCellItemData( + "Header", + "Lorem ipsum", + SirioTableVerticalCellItemType.TEXT + ), + SirioTableVerticalCellItemData( + "Header", + "00", + SirioTableVerticalCellItemType.NUMBER + ), + SirioTableVerticalCellItemData( + "Header", + "Lorem ipsum", + SirioTableVerticalCellItemType.TEXT + ), + SirioTableVerticalCellItemData( + "Header", + "Label Tag", + SirioTableVerticalCellItemType.TAG + ), + ), + icons = icons, + ), + ) + } +} \ No newline at end of file diff --git a/design/src/main/java/it/inps/sirio/ui/table/vertical/SirioTableVerticalCellData.kt b/design/src/main/java/it/inps/sirio/ui/table/vertical/SirioTableVerticalCellData.kt new file mode 100644 index 0000000..b5cb639 --- /dev/null +++ b/design/src/main/java/it/inps/sirio/ui/table/vertical/SirioTableVerticalCellData.kt @@ -0,0 +1,15 @@ +// +// SirioTableVerticalCellData.kt +// +// SPDX-FileCopyrightText: 2022 Istituto Nazionale Previdenza Sociale +// +// SPDX-License-Identifier: BSD-3-Clause +// +package it.inps.sirio.ui.table.vertical + +import it.inps.sirio.ui.table.SirioTableIconData + +data class SirioTableVerticalCellData( + val items: List, + val icons: List = emptyList(), +) \ No newline at end of file diff --git a/design/src/main/java/it/inps/sirio/ui/table/vertical/SirioTableVerticalCellItem.kt b/design/src/main/java/it/inps/sirio/ui/table/vertical/SirioTableVerticalCellItem.kt new file mode 100644 index 0000000..1ede8e0 --- /dev/null +++ b/design/src/main/java/it/inps/sirio/ui/table/vertical/SirioTableVerticalCellItem.kt @@ -0,0 +1,146 @@ +// +// SirioTableDrawerItem.kt +// +// SPDX-FileCopyrightText: 2022 Istituto Nazionale Previdenza Sociale +// +// SPDX-License-Identifier: BSD-3-Clause +// +package it.inps.sirio.ui.table.vertical + +import androidx.annotation.Keep +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.runtime.Composable +import androidx.compose.runtime.Stable +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import it.inps.sirio.theme.SirioTheme +import it.inps.sirio.theme.tableVerticalItemPadding +import it.inps.sirio.theme.tableVerticalItemTagPadding +import it.inps.sirio.ui.tag.SirioTag +import it.inps.sirio.ui.tag.TagType +import it.inps.sirio.ui.text.SirioText + +@Composable +internal fun SirioTableVerticalCellItem(data: SirioTableVerticalCellItemData) { + val verticalTypography = SirioTheme.typography.table.vertical + val verticalColor = SirioTheme.colors.table.vertical + val (typography, color) = remember(data.type) { + when (data.type) { + SirioTableVerticalCellItemType.TEXT -> verticalTypography.itemText to verticalColor.itemText + SirioTableVerticalCellItemType.NUMBER -> verticalTypography.itemNumber to verticalColor.itemNumber + SirioTableVerticalCellItemType.LINK -> verticalTypography.itemLink to verticalColor.itemLink + SirioTableVerticalCellItemType.TAG -> null to null + } + } + Column( + modifier = Modifier + .fillMaxWidth() + .padding(tableVerticalItemPadding.dp) + ) { + SirioText( + text = data.title, + typography = verticalTypography.itemTitle, + color = verticalColor.itemTitle, + ) + if (typography != null && color != null) { + SirioText( + text = data.text, + typography = typography, + color = color, + ) + } else { + Spacer(modifier = Modifier.height(tableVerticalItemTagPadding.dp)) + SirioTag(text = data.text, tagType = TagType.GRAY) + } + } +} + +enum class SirioTableVerticalCellItemType { + TEXT, NUMBER, LINK, TAG, +} + +@Keep +data class SirioTableVerticalColors( + val background: Color, + val border: Color, + val itemTitle: Color, + val itemText: Color, + val itemNumber: Color, + val itemLink: Color, +) { + companion object { + @Stable + val Unspecified = SirioTableVerticalColors( + background = Color.Unspecified, + border = Color.Unspecified, + itemTitle = Color.Unspecified, + itemText = Color.Unspecified, + itemNumber = Color.Unspecified, + itemLink = Color.Unspecified, + ) + } +} + +@Keep +data class SirioTableVerticalTypography( + val itemTitle: TextStyle, + val itemText: TextStyle, + val itemNumber: TextStyle, + val itemLink: TextStyle, +) { + companion object { + @Stable + val Default = SirioTableVerticalTypography( + itemTitle = TextStyle.Default, + itemText = TextStyle.Default, + itemNumber = TextStyle.Default, + itemLink = TextStyle.Default, + ) + } +} + +@Preview +@Composable +private fun SirioTableVerticalCellItemPreview() { + SirioTheme { + Column(Modifier.background(Color.White)) { + SirioTableVerticalCellItem( + SirioTableVerticalCellItemData( + title = "Header", + text = "Lorem Ipsum", + type = SirioTableVerticalCellItemType.TEXT, + ) + ) + SirioTableVerticalCellItem( + SirioTableVerticalCellItemData( + title = "Header", + text = "00", + type = SirioTableVerticalCellItemType.NUMBER, + ) + ) + SirioTableVerticalCellItem( + SirioTableVerticalCellItemData( + title = "Header", + text = "Link", + type = SirioTableVerticalCellItemType.LINK, + ) + ) + SirioTableVerticalCellItem( + SirioTableVerticalCellItemData( + title = "Header", + text = "Label Tag", + type = SirioTableVerticalCellItemType.TAG, + ) + ) + } + } +} \ No newline at end of file diff --git a/design/src/main/java/it/inps/sirio/ui/table/vertical/SirioTableVerticalCellItemData.kt b/design/src/main/java/it/inps/sirio/ui/table/vertical/SirioTableVerticalCellItemData.kt new file mode 100644 index 0000000..f9649d2 --- /dev/null +++ b/design/src/main/java/it/inps/sirio/ui/table/vertical/SirioTableVerticalCellItemData.kt @@ -0,0 +1,14 @@ +// +// SirioTableVerticalCellItemData.kt +// +// SPDX-FileCopyrightText: 2022 Istituto Nazionale Previdenza Sociale +// +// SPDX-License-Identifier: BSD-3-Clause +// +package it.inps.sirio.ui.table.vertical + +data class SirioTableVerticalCellItemData( + val title: String, + val text: String, + val type: SirioTableVerticalCellItemType, +) \ No newline at end of file diff --git a/design/src/main/java/it/inps/sirio/ui/tabs/SirioTabCommon.kt b/design/src/main/java/it/inps/sirio/ui/tabs/SirioTabCommon.kt index b45915a..64ed029 100644 --- a/design/src/main/java/it/inps/sirio/ui/tabs/SirioTabCommon.kt +++ b/design/src/main/java/it/inps/sirio/ui/tabs/SirioTabCommon.kt @@ -15,17 +15,11 @@ import androidx.compose.foundation.interaction.collectIsFocusedAsState import androidx.compose.foundation.interaction.collectIsHoveredAsState import androidx.compose.foundation.interaction.collectIsPressedAsState import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.IntrinsicSize import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.requiredWidth -import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.wrapContentWidth import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll @@ -46,7 +40,6 @@ import it.inps.sirio.theme.SirioTheme import it.inps.sirio.theme.tabHeight import it.inps.sirio.theme.tabHorizontalPadding import it.inps.sirio.theme.tabIconSize -import it.inps.sirio.theme.tabIndicatorHeight import it.inps.sirio.theme.tabWithIconHorizontalSpacing import it.inps.sirio.ui.text.SirioTextCommon import it.inps.sirio.utils.SirioIcon @@ -75,7 +68,11 @@ internal fun SirioTabCommon( val isFocused by interactionSource.collectIsFocusedAsState() val isHovered by interactionSource.collectIsHoveredAsState() - val tabsParams = getTabsParams(enabled, isFocused, isPressed, isHovered, selected) + val labelColor = + SirioTheme.colors.tabs.text.get(enabled.not(), isFocused, isPressed || selected, isHovered) + val iconColor = + SirioTheme.colors.tabs.icon.get(enabled.not(), isFocused, isPressed || selected, isHovered) + val backgroundColor = when { selected -> SirioTheme.colors.tabs.backgroundSelected !enabled && selection == TabSelectionIndicatorPosition.BOTTOM -> SirioTheme.colors.tabs.backgroundBottomSelectionDisabled @@ -85,99 +82,38 @@ internal fun SirioTabCommon( else -> SirioTheme.colors.tabs.backgroundSelected } - Box( + Tab( + selected = selected, + onClick = onSelect, modifier = Modifier .height(tabHeight) - .width(IntrinsicSize.Max), - contentAlignment = if (selection == TabSelectionIndicatorPosition.TOP) Alignment.TopCenter else Alignment.BottomCenter + .wrapContentWidth() + .background(backgroundColor), + enabled = enabled, + interactionSource = interactionSource, ) { - Tab( - selected = selected, - onClick = onSelect, - modifier = Modifier - .height(tabHeight) - .wrapContentWidth() - .background(backgroundColor), - enabled = enabled, - interactionSource = interactionSource, + Row( + modifier = Modifier.padding(horizontal = tabHorizontalPadding.dp), + horizontalArrangement = Arrangement + .spacedBy(tabWithIconHorizontalSpacing.dp, Alignment.CenterHorizontally), + verticalAlignment = Alignment.CenterVertically, ) { - Row( - modifier = Modifier.padding(horizontal = tabHorizontalPadding.dp), - horizontalArrangement = Arrangement.Center, - verticalAlignment = Alignment.CenterVertically, - ) { - icon?.let { - SirioIcon( - faIcon = icon, - iconColor = tabsParams.iconColor, - size = tabIconSize - ) - Spacer(Modifier.requiredWidth(tabWithIconHorizontalSpacing.dp)) - } - SirioTextCommon( - text = label, - color = tabsParams.labelColor, - typography = if (selected) SirioTheme.typography.tabTextSelected else SirioTheme.typography.tabTextDefault + icon?.let { + SirioIcon( + faIcon = icon, + iconColor = iconColor, + size = tabIconSize ) } + SirioTextCommon( + text = label, + color = labelColor, + typography = if (selected) SirioTheme.typography.tabTextSelected else SirioTheme.typography.tabTextDefault + ) } - Box( - modifier = Modifier - .fillMaxWidth() - .height(tabIndicatorHeight) - .background(color = tabsParams.selectionColor) - ) } } -/** - * Tab colors based on current state - */ -@Composable -private fun getTabsParams( - enabled: Boolean, - isFocused: Boolean, - isPressed: Boolean, - isHovered: Boolean, - isSelected: Boolean, -): TabsParams = when { - !enabled -> TabsParams( - labelColor = SirioTheme.colors.tabs.text.disabled, - iconColor = SirioTheme.colors.tabs.icon.disabled, - selectionColor = SirioTheme.colors.tabs.selection.disabled, - ) - - isFocused -> TabsParams( - labelColor = SirioTheme.colors.tabs.text.focused, - iconColor = SirioTheme.colors.tabs.icon.focused, - selectionColor = SirioTheme.colors.tabs.selection.focused, - ) - - isPressed || isSelected -> TabsParams( - labelColor = SirioTheme.colors.tabs.text.pressed, - iconColor = SirioTheme.colors.tabs.icon.pressed, - selectionColor = SirioTheme.colors.tabs.selection.pressed, - ) - - isHovered -> TabsParams( - labelColor = SirioTheme.colors.tabs.text.hovered, - iconColor = SirioTheme.colors.tabs.icon.hovered, - selectionColor = SirioTheme.colors.tabs.selection.hovered, - ) - - else -> TabsParams( - labelColor = SirioTheme.colors.tabs.text.default, - iconColor = SirioTheme.colors.tabs.icon.default, - selectionColor = SirioTheme.colors.tabs.selection.default, - ) -} - -data class TabsParams( - val labelColor: Color, - val iconColor: Color, - val selectionColor: Color, -) - @Keep data class SirioTabsColors( val backgroundBottomSelection: Color, diff --git a/design/src/main/java/it/inps/sirio/ui/tabs/SirioTabGroupCommon.kt b/design/src/main/java/it/inps/sirio/ui/tabs/SirioTabGroupCommon.kt index 93d15bb..fab0c98 100644 --- a/design/src/main/java/it/inps/sirio/ui/tabs/SirioTabGroupCommon.kt +++ b/design/src/main/java/it/inps/sirio/ui/tabs/SirioTabGroupCommon.kt @@ -8,24 +8,43 @@ package it.inps.sirio.ui.tabs +import androidx.compose.animation.core.FastOutSlowInEasing +import androidx.compose.animation.core.animateDpAsState +import androidx.compose.animation.core.tween import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.offset import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.wrapContentHeight +import androidx.compose.foundation.layout.wrapContentSize import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.shape.CornerSize +import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.verticalScroll import androidx.compose.material3.ScrollableTabRow +import androidx.compose.material3.TabPosition +import androidx.compose.material3.TabRow import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.composed +import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color +import androidx.compose.ui.platform.debugInspectorInfo import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.IntOffset import androidx.compose.ui.unit.dp import com.guru.fontawesomecomposelib.FaIcons import it.inps.sirio.theme.SirioTheme import it.inps.sirio.theme.tabEdgePadding +import it.inps.sirio.theme.tabIndicatorHeight /** * Sirio tab group implementation @@ -40,6 +59,7 @@ internal fun SirioTabGroupCommon( items: List, selectedIndex: Int, selection: TabSelectionIndicatorPosition, + modifier: Modifier = Modifier, onTabSelected: (Int) -> Unit, ) { require(items.isNotEmpty()) { "TabGroup cannot be empty" } @@ -47,12 +67,25 @@ internal fun SirioTabGroupCommon( ScrollableTabRow( selectedTabIndex = selectedIndex, - modifier = Modifier + modifier = modifier .fillMaxWidth() .wrapContentHeight(), edgePadding = tabEdgePadding, containerColor = if (selection == TabSelectionIndicatorPosition.TOP) Color.Transparent else Color.White, - indicator = { }, + indicator = @Composable { tabPositions -> + if (selection == TabSelectionIndicatorPosition.BOTTOM) { + Box( + Modifier + .wrapContentSize(Alignment.BottomStart) + .fillMaxWidth() + .height(tabIndicatorHeight) + .background(color = SirioTheme.colors.tabs.selection.default) + ) + } + SirioTabIndicator( + Modifier.sirioTabIndicatorOffset(selection, tabPositions[selectedIndex]) + ) + }, divider = {} ) { items.forEachIndexed { index, item -> @@ -68,6 +101,54 @@ internal fun SirioTabGroupCommon( } } +@Composable +internal fun SirioTabIndicator( + modifier: Modifier = Modifier, +) { + Box( + modifier + .fillMaxWidth() + .height(tabIndicatorHeight) + .clip(RoundedCornerShape(corner = CornerSize(4.dp))) + .background(color = SirioTheme.colors.tabs.selection.pressed) + ) +} + +/** + * [Modifier] that takes up all the available width inside the [TabRow], and then animates + * the offset of the indicator it is applied to, depending on the [currentTabPosition]. + * + * @param currentTabPosition [TabPosition] of the currently selected tab. This is used to + * calculate the offset of the indicator this modifier is applied to, as well as its width. + */ +internal fun Modifier.sirioTabIndicatorOffset( + selection: TabSelectionIndicatorPosition, + currentTabPosition: TabPosition, +): Modifier = composed( + inspectorInfo = debugInspectorInfo { + name = "tabIndicatorOffset" + value = currentTabPosition + } +) { + val currentTabWidth by animateDpAsState( + targetValue = currentTabPosition.width, + animationSpec = tween(durationMillis = 250, easing = FastOutSlowInEasing), + label = "tabWidth", + ) + val indicatorOffset by animateDpAsState( + targetValue = currentTabPosition.left, + animationSpec = tween(durationMillis = 250, easing = FastOutSlowInEasing), + label = "indicatorOffset", + ) + val align = + if (selection == TabSelectionIndicatorPosition.BOTTOM) Alignment.BottomStart + else Alignment.TopStart + fillMaxWidth() + .wrapContentSize(align) + .offset { IntOffset(indicatorOffset.roundToPx(), 0) } + .width(currentTabWidth) +} + @Preview(showSystemUi = true) @Composable private fun TabsCommonPreview() { diff --git a/design/src/main/java/it/inps/sirio/ui/tabs/TabItemData.kt b/design/src/main/java/it/inps/sirio/ui/tabs/TabItemData.kt index e51e8f8..5304fee 100644 --- a/design/src/main/java/it/inps/sirio/ui/tabs/TabItemData.kt +++ b/design/src/main/java/it/inps/sirio/ui/tabs/TabItemData.kt @@ -21,5 +21,5 @@ import com.guru.fontawesomecomposelib.FaIconType data class TabItemData( val label: String, val icon: FaIconType? = null, - val enabled: Boolean = false, -) \ No newline at end of file + val enabled: Boolean = true, +) diff --git a/design/src/main/java/it/inps/sirio/ui/textarea/SirioTextAreaCommon.kt b/design/src/main/java/it/inps/sirio/ui/textarea/SirioTextAreaCommon.kt index 4c18007..6c1a07e 100644 --- a/design/src/main/java/it/inps/sirio/ui/textarea/SirioTextAreaCommon.kt +++ b/design/src/main/java/it/inps/sirio/ui/textarea/SirioTextAreaCommon.kt @@ -109,7 +109,14 @@ internal fun SirioTextAreaCommon( val isFocused by interactionSource.collectIsFocusedAsState() val isHovered by interactionSource.collectIsHoveredAsState() - val textAreaParams = getTextAreaParams(enabled, type, isFocused, isPressed, isHovered) + val textAreaParams = getTextAreaParams( + enabled = enabled, + type = type, + isFocused = isFocused, + isPressed = isPressed, + isHovered = isHovered, + isValued = text.isNotEmpty() + ) Column { label?.let { @@ -271,6 +278,7 @@ private fun getTextAreaParams( isFocused: Boolean, isPressed: Boolean, isHovered: Boolean, + isValued: Boolean, ): TextAreaParams = when { !enabled -> TextAreaParams( backgroundColor = SirioTheme.colors.textArea.background.disabled, @@ -320,16 +328,16 @@ private fun getTextAreaParams( dropdownBorderColor = SirioTheme.colors.textArea.dropdown.focused, ) - isPressed -> TextAreaParams( - backgroundColor = SirioTheme.colors.textArea.background.pressed, - infoIconColor = SirioTheme.colors.textArea.label.pressed, - labelColor = SirioTheme.colors.textArea.label.pressed, - helperTextColor = SirioTheme.colors.textArea.helperText.pressed, - placeholderTextColor = SirioTheme.colors.textArea.placeholder.pressed, - textColor = SirioTheme.colors.textArea.text.pressed, - iconColor = SirioTheme.colors.textArea.icon.pressed, - borderColor = SirioTheme.colors.textArea.border.pressed, - dropdownBorderColor = SirioTheme.colors.textArea.dropdown.pressed, + isValued -> TextAreaParams( + backgroundColor = SirioTheme.colors.textArea.background.valued, + infoIconColor = SirioTheme.colors.textArea.label.valued, + labelColor = SirioTheme.colors.textArea.label.valued, + helperTextColor = SirioTheme.colors.textArea.helperText.valued, + placeholderTextColor = SirioTheme.colors.textArea.placeholder.valued, + textColor = SirioTheme.colors.textArea.text.valued, + iconColor = SirioTheme.colors.textArea.icon.valued, + borderColor = SirioTheme.colors.textArea.border.valued, + dropdownBorderColor = SirioTheme.colors.textArea.dropdown.valued, ) isHovered -> TextAreaParams( diff --git a/design/src/main/java/it/inps/sirio/ui/textfield/SirioTextFieldCommon.kt b/design/src/main/java/it/inps/sirio/ui/textfield/SirioTextFieldCommon.kt index 7a1c0aa..4cbd527 100644 --- a/design/src/main/java/it/inps/sirio/ui/textfield/SirioTextFieldCommon.kt +++ b/design/src/main/java/it/inps/sirio/ui/textfield/SirioTextFieldCommon.kt @@ -210,6 +210,7 @@ internal fun SirioTextFieldCommon( value = text, onValueChange = onValueChange, modifier = Modifier + .height(48.dp) .fillMaxWidth() .onFocusChanged { onDropdownStateChange?.invoke(it.hasFocus && optionValues.isNotEmpty()) @@ -257,7 +258,10 @@ internal fun SirioTextFieldCommon( } }, colors = colors, - contentPadding = OutlinedTextFieldDefaults.contentPadding(), + contentPadding = OutlinedTextFieldDefaults.contentPadding( + top = 0.dp, + bottom = 0.dp + ), container = { OutlinedTextFieldDefaults.ContainerBox( enabled = enabled, @@ -322,7 +326,13 @@ private fun SirioTextFieldOptionItem( val isFocused by interactionSource.collectIsFocusedAsState() val isHovered by interactionSource.collectIsHoveredAsState() - val optionItemParams = getOptionItemParams(enabled, isFocused, isPressed, isHovered) + val optionItemParams = getOptionItemParams( + enabled = enabled, + isFocused = isFocused, + isPressed = isPressed, + isHovered = isHovered, + isValued = value.isNotEmpty() + ) Box( modifier = Modifier @@ -524,6 +534,7 @@ private fun getOptionItemParams( isFocused: Boolean, isPressed: Boolean, isHovered: Boolean, + isValued: Boolean, ): OptionItemParams = when { !enabled -> OptionItemParams( optionBackgroundColor = SirioTheme.colors.textField.optionBackground.disabled, @@ -535,9 +546,9 @@ private fun getOptionItemParams( optionTextColor = SirioTheme.colors.textField.optionText.focused, ) - isPressed -> OptionItemParams( - optionBackgroundColor = SirioTheme.colors.textField.optionBackground.pressed, - optionTextColor = SirioTheme.colors.textField.optionText.pressed, + isValued -> OptionItemParams( + optionBackgroundColor = SirioTheme.colors.textField.optionBackground.valued, + optionTextColor = SirioTheme.colors.textField.optionText.valued, ) isHovered -> OptionItemParams( @@ -700,7 +711,7 @@ private fun TextFieldInRowPreview() { SirioTextFieldCommon( text = "", onValueChange = {}, - label = "XX", + label = "RC", modifier = Modifier.weight(1f), ) Text( @@ -712,7 +723,7 @@ private fun TextFieldInRowPreview() { SirioTextFieldCommon( text = "", onValueChange = {}, - label = "YYYY", + label = "ANNO", modifier = Modifier.weight(2f), ) } diff --git a/design/src/main/java/it/inps/sirio/ui/titlebar/SirioTitleBar.kt b/design/src/main/java/it/inps/sirio/ui/titlebar/SirioTitleBar.kt new file mode 100644 index 0000000..52c2ee1 --- /dev/null +++ b/design/src/main/java/it/inps/sirio/ui/titlebar/SirioTitleBar.kt @@ -0,0 +1,24 @@ +// +// SirioTitleBar.kt +// +// SPDX-FileCopyrightText: 2022 Istituto Nazionale Previdenza Sociale +// +// SPDX-License-Identifier: BSD-3-Clause +// +package it.inps.sirio.ui.titlebar + +import androidx.compose.runtime.Composable + +/** + * Sirio component for displaying a title bar with a title and optional items. + * + * @param title The title to be displayed in the title bar. + * @param items A list of [SirioTitleBarItemData] objects representing the items to be displayed in the title bar. + */ +@Composable +fun SirioTitleBar( + title: String, + items: List = emptyList(), +) { + SirioTitleBarCommon(title = title, items = items) +} \ No newline at end of file diff --git a/design/src/main/java/it/inps/sirio/ui/titlebar/SirioTitleBarCommon.kt b/design/src/main/java/it/inps/sirio/ui/titlebar/SirioTitleBarCommon.kt new file mode 100644 index 0000000..75c6c9e --- /dev/null +++ b/design/src/main/java/it/inps/sirio/ui/titlebar/SirioTitleBarCommon.kt @@ -0,0 +1,145 @@ +package it.inps.sirio.ui.titlebar + +import androidx.annotation.Keep +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.material3.LocalContentColor +import androidx.compose.material3.Surface +import androidx.compose.runtime.Composable +import androidx.compose.runtime.Stable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.semantics.Role +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.guru.fontawesomecomposelib.FaIcons +import it.inps.sirio.theme.SirioTheme +import it.inps.sirio.theme.titleBarHeight +import it.inps.sirio.theme.titleBarIconSize +import it.inps.sirio.theme.titleBarItemPadding +import it.inps.sirio.theme.titleBarItemSpacing +import it.inps.sirio.theme.titleBarPaddingHorizontal +import it.inps.sirio.ui.text.SirioText +import it.inps.sirio.ui.text.SirioTextCommon +import it.inps.sirio.utils.SirioIcon + +/** + * Sirio component for displaying a title bar with a title and optional items. + * + * @param title The title to be displayed in the title bar. + * @param items A list of [SirioTitleBarItemData] objects representing the items to be displayed in the title bar. + */ +@Composable +internal fun SirioTitleBarCommon( + title: String, + items: List = emptyList(), +) { + Surface( + color = SirioTheme.colors.titleBar.container, + contentColor = SirioTheme.colors.titleBar.content, + ) { + Row( + modifier = Modifier + .height(titleBarHeight.dp) + .padding(start = titleBarPaddingHorizontal.dp), + verticalAlignment = Alignment.CenterVertically, + ) { + SirioTextCommon( + text = title, + typography = SirioTheme.typography.titleBar.title, + ) + Spacer(modifier = Modifier.weight(1f)) + items.forEach { + Row( + modifier = Modifier.clickable(role = Role.Button, onClick = it.action), + verticalAlignment = Alignment.CenterVertically, + ) { + SirioIcon( + faIcon = it.icon, + iconColor = LocalContentColor.current, + size = titleBarIconSize.dp, + contentDescription = it.contentDescription, + ) + if (it.text.isNotBlank()) { + Spacer(modifier = Modifier.width(titleBarItemPadding.dp)) + SirioText( + text = it.text, + color = SirioTheme.colors.titleBar.content, + typography = SirioTheme.typography.titleBar.iconText, + ) + } + } + Spacer(modifier = Modifier.width(titleBarItemSpacing.dp)) + } + } + } +} + +@Keep +data class SirioTitleBarColors( + val container: Color, + val content: Color, +) { + companion object { + @Stable + val Unspecified = SirioTitleBarColors( + container = Color.Unspecified, + content = Color.Unspecified, + ) + } +} + +@Keep +data class SirioTitleBarTypography( + val title: TextStyle, + val iconText: TextStyle, +) { + companion object { + @Stable + val Default = SirioTitleBarTypography( + title = TextStyle.Default, + iconText = TextStyle.Default, + ) + } +} + +@Preview +@Composable +private fun SirioTitleBarCommonPreview() { + Column { + val title = "Titolo" + val items = listOf( + SirioTitleBarItemData( + icon = FaIcons.Filter, + text = "Mostra filtri", + contentDescription = null, + action = {}, + ), + SirioTitleBarItemData( + icon = FaIcons.EllipsisH, + text = "Mostra altro", + contentDescription = null, + action = {}, + ) + ) + SirioTheme { + SirioTitleBarCommon( + title = title, + items = items, + ) + } + SirioTheme(darkTheme = true) { + SirioTitleBarCommon( + title = title, + items = items, + ) + } + } +} \ No newline at end of file diff --git a/design/src/main/java/it/inps/sirio/ui/titlebar/SirioTitleBarItemData.kt b/design/src/main/java/it/inps/sirio/ui/titlebar/SirioTitleBarItemData.kt new file mode 100644 index 0000000..3996342 --- /dev/null +++ b/design/src/main/java/it/inps/sirio/ui/titlebar/SirioTitleBarItemData.kt @@ -0,0 +1,27 @@ +// +// SirioTitleBarItemData.kt +// +// SPDX-FileCopyrightText: 2022 Istituto Nazionale Previdenza Sociale +// +// SPDX-License-Identifier: BSD-3-Clause +// + +package it.inps.sirio.ui.titlebar + +import androidx.annotation.Keep +import com.guru.fontawesomecomposelib.FaIconType + +/** + * A representation of a title bar item + * @param icon The FA icon of the item + * @param text The text of the item + * @param contentDescription The content description for the item + * @param action The click action callback + */ +@Keep +data class SirioTitleBarItemData( + val icon: FaIconType, + val text: String, + val contentDescription: String? = null, + val action: () -> Unit, +) diff --git a/design/src/main/java/it/inps/sirio/ui/toggle/Toggle.kt b/design/src/main/java/it/inps/sirio/ui/toggle/SirioToggle.kt similarity index 94% rename from design/src/main/java/it/inps/sirio/ui/toggle/Toggle.kt rename to design/src/main/java/it/inps/sirio/ui/toggle/SirioToggle.kt index 342453d..6d50d5e 100644 --- a/design/src/main/java/it/inps/sirio/ui/toggle/Toggle.kt +++ b/design/src/main/java/it/inps/sirio/ui/toggle/SirioToggle.kt @@ -1,5 +1,5 @@ // -// Toggle.kt +// SirioToggle.kt // // SPDX-FileCopyrightText: 2024 Istituto Nazionale Previdenza Sociale // @@ -22,15 +22,15 @@ import it.inps.sirio.theme.SirioTheme * @param onToggleChange The callback when the toggle state change */ @Composable -fun Toggle( +fun SirioToggle( label: String? = null, isOn: Boolean, enabled: Boolean = true, onToggleChange: (on: Boolean) -> Unit ) { SirioToggleCommon( - text = label, isOn = isOn, + text = label, enabled = enabled, onToggleChange = onToggleChange, ) @@ -41,7 +41,7 @@ fun Toggle( private fun TogglePreview() { SirioTheme { Column { - Toggle( + SirioToggle( label = "Title", isOn = true, enabled = true, diff --git a/design/src/main/java/it/inps/sirio/ui/toggle/SirioToggleCommon.kt b/design/src/main/java/it/inps/sirio/ui/toggle/SirioToggleCommon.kt index 18ff4de..e36ba25 100644 --- a/design/src/main/java/it/inps/sirio/ui/toggle/SirioToggleCommon.kt +++ b/design/src/main/java/it/inps/sirio/ui/toggle/SirioToggleCommon.kt @@ -20,7 +20,9 @@ import androidx.compose.foundation.interaction.collectIsPressedAsState import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.offset import androidx.compose.foundation.layout.padding @@ -29,6 +31,7 @@ import androidx.compose.foundation.layout.width import androidx.compose.foundation.selection.toggleable import androidx.compose.foundation.shape.CircleShape import androidx.compose.material3.Surface +import androidx.compose.material3.minimumInteractiveComponentSize import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.Stable @@ -53,7 +56,7 @@ import it.inps.sirio.theme.toggleFocusExtraBorderWidth import it.inps.sirio.theme.toggleHeight import it.inps.sirio.theme.toggleIndicatorHorizontalOffset import it.inps.sirio.theme.toggleIndicatorSize -import it.inps.sirio.theme.toggleSafeAreaPadding +import it.inps.sirio.theme.togglePaddingText import it.inps.sirio.theme.toggleWidth import it.inps.sirio.ui.text.SirioTextCommon import androidx.compose.animation.core.Animatable as AnimatableF @@ -62,14 +65,16 @@ import androidx.compose.animation.core.Animatable as AnimatableF * Sirio toggle implementation * * @param text The string on the toggle right + * @param modifier the Modifier to be applied to this toggle * @param isOn Whether the toggle is selected * @param enabled Whether the toggle is enabled * @param onToggleChange The callback when the toggle state change */ @Composable internal fun SirioToggleCommon( - text: String? = null, isOn: Boolean, + modifier: Modifier = Modifier, + text: String? = null, enabled: Boolean = true, onToggleChange: (Boolean) -> Unit, ) { @@ -78,7 +83,7 @@ internal fun SirioToggleCommon( val isFocused by interactionSource.collectIsFocusedAsState() val isHovered by interactionSource.collectIsHoveredAsState() - Row(verticalAlignment = Alignment.CenterVertically) { + Row(verticalAlignment = Alignment.CenterVertically, modifier = modifier) { val backgroundColor = SirioTheme.colors.toggle.background.get(enabled.not(), isFocused, isPressed, isHovered) val onColor = @@ -94,20 +99,20 @@ internal fun SirioToggleCommon( val offset: Float = with(LocalDensity.current) { toggleIndicatorHorizontalOffset.dp.toPx() } - val modifier = Modifier - .padding(toggleSafeAreaPadding) - .height(height = toggleHeight) - .width(width = toggleWidth) + val sizeModifier = Modifier + .height(height = toggleHeight.dp) + .width(width = toggleWidth.dp) + .minimumInteractiveComponentSize() Box( modifier = if (isFocused) { - modifier + sizeModifier .border( - toggleFocusExtraBorderWidth, + toggleFocusExtraBorderWidth.dp, color = SirioTheme.colors.toggle.borderFocusExtra, shape = CircleShape, ) - .padding(toggleFocusExtraBorderPadding) - } else modifier, + .padding(toggleFocusExtraBorderPadding.dp) + } else sizeModifier, ) { Surface( modifier = Modifier @@ -122,7 +127,7 @@ internal fun SirioToggleCommon( ), shape = CircleShape, color = backgroundColor, - border = BorderStroke(width = toggleBorderWidth, color = borderColor) + border = BorderStroke(width = toggleBorderWidth.dp, color = borderColor) ) { val currentX = if (isOn) offset else -offset val animatedColor = remember { Animatable(stateColor) } @@ -135,13 +140,14 @@ internal fun SirioToggleCommon( Modifier .align(Alignment.CenterStart) .offset { IntOffset(xPos.value.toInt(), 0) } - .requiredSize(toggleIndicatorSize) + .requiredSize(toggleIndicatorSize.dp) .clip(CircleShape) .background(animatedColor.value) ) } } text?.let { + Spacer(modifier = Modifier.width(togglePaddingText.dp)) SirioTextCommon( text = it, color = stateColor, @@ -186,10 +192,14 @@ data class SirioToggleTypography( private fun ToggleCommonPreview() { SirioTheme { Column { - SirioToggleCommon(text = "Title", isOn = false, onToggleChange = {}) - SirioToggleCommon(text = "Title", isOn = true, onToggleChange = {}) - SirioToggleCommon(text = "Title", isOn = false, enabled = false, onToggleChange = {}) - SirioToggleCommon(text = "Title", isOn = true, enabled = false, onToggleChange = {}) + SirioToggleCommon( + isOn = false, + modifier = Modifier.fillMaxWidth(), + text = "Title", + onToggleChange = {}) + SirioToggleCommon(isOn = true, text = "Title", onToggleChange = {}) + SirioToggleCommon(isOn = false, text = "Title", enabled = false, onToggleChange = {}) + SirioToggleCommon(isOn = true, text = "Title", enabled = false, onToggleChange = {}) } } } diff --git a/design/src/main/java/it/inps/sirio/utils/ModifierExt.kt b/design/src/main/java/it/inps/sirio/utils/ModifierExt.kt new file mode 100644 index 0000000..f476934 --- /dev/null +++ b/design/src/main/java/it/inps/sirio/utils/ModifierExt.kt @@ -0,0 +1,21 @@ +package it.inps.sirio.utils + +import androidx.compose.ui.Modifier + +/** + * Used to apply modifiers conditionally. + */ +fun Modifier.ifElse( + condition: () -> Boolean, + ifTrueModifier: Modifier, + ifFalseModifier: Modifier = Modifier, +): Modifier = then(if (condition()) ifTrueModifier else ifFalseModifier) + +/** + * Used to apply modifiers conditionally. + */ +fun Modifier.ifElse( + condition: Boolean, + ifTrueModifier: Modifier, + ifFalseModifier: Modifier = Modifier, +): Modifier = ifElse({ condition }, ifTrueModifier, ifFalseModifier) \ No newline at end of file diff --git a/design/src/main/java/it/inps/sirio/utils/SirioIcon.kt b/design/src/main/java/it/inps/sirio/utils/SirioIcon.kt index 9e74a44..c7b8621 100644 --- a/design/src/main/java/it/inps/sirio/utils/SirioIcon.kt +++ b/design/src/main/java/it/inps/sirio/utils/SirioIcon.kt @@ -1,6 +1,7 @@ package it.inps.sirio.utils import androidx.annotation.DrawableRes +import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.requiredSize import androidx.compose.foundation.layout.size @@ -10,6 +11,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.painterResource +import androidx.compose.ui.semantics.Role import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import com.guru.fontawesomecomposelib.FaIconType @@ -30,9 +32,21 @@ fun SirioIcon( iconColor: Color, size: Dp = 24.dp, contentDescription: String? = null, + onclick: (() -> Unit)? = null, ) { require(faIcon != null || iconResId != null) { "At least one of faIcon or iconResId must be non-null" } - Box(Modifier.requiredSize(size), contentAlignment = Alignment.Center) { + Box( + Modifier + .requiredSize(size) + .ifElse( + condition = onclick != null, + ifTrueModifier = Modifier.clickable( + enabled = onclick != null, + role = Role.Image, + onClick = { onclick?.invoke() }) + ), + contentAlignment = Alignment.Center + ) { faIcon?.let { SirioFaIcon( faIcon = it, @@ -49,4 +63,20 @@ fun SirioIcon( ) } } -} \ No newline at end of file +} + +/** + * Creates a custom icon using a [SirioIconData] object. + * + * @param iconData The [SirioIconData] object containing the icon parameters. + */ +@Composable +fun SirioIcon(iconData: SirioIconData) { + SirioIcon( + faIcon = iconData.faIcon, + iconResId = iconData.iconResId, + iconColor = iconData.iconColor, + size = iconData.size, + contentDescription = iconData.contentDescription + ) +} diff --git a/design/src/main/java/it/inps/sirio/utils/SirioIconData.kt b/design/src/main/java/it/inps/sirio/utils/SirioIconData.kt new file mode 100644 index 0000000..23a8ebd --- /dev/null +++ b/design/src/main/java/it/inps/sirio/utils/SirioIconData.kt @@ -0,0 +1,68 @@ +// +// SirioIconData.kt +// +// SPDX-FileCopyrightText: 2022 Istituto Nazionale Previdenza Sociale +// +// SPDX-License-Identifier: BSD-3-Clause +// +package it.inps.sirio.utils + +import androidx.annotation.DrawableRes +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp +import com.guru.fontawesomecomposelib.FaIconType + +/** + * Data class representing an icon that can be displayed using either a FontAwesome icon + * or a drawable resource. + * + * @property faIcon The FontAwesome icon type to display. + * @property iconResId The resource ID of the drawable to display. + * @property iconColor The color of the icon. + * @property size The size of the icon. + * @property contentDescription The content description for accessibility. + * + *@constructor Creates a new [SirioIconData] instance. + * + * This class provides two convenience constructors: + * + * * `SirioIconData(faIcon: FaIconType, iconColor: Color, size: Dp = 24.dp, contentDescription: String? = null)` + * for creating an icon from a FontAwesome icon type. + * + * * `SirioIconData(@DrawableRes iconResId: Int, iconColor: Color, size: Dp = 24.dp, contentDescription: String? = null)` + * for creating an icon from adrawable resource ID. + */ +data class SirioIconData internal constructor( + val faIcon: FaIconType?, + @DrawableRes val iconResId: Int?, + val iconColor: Color, + val size: Dp, + val contentDescription: String?, +) { + constructor( + faIcon: FaIconType, + iconColor: Color, + size: Dp = 24.dp, + contentDescription: String? = null, + ) : this( + faIcon = faIcon, + iconResId = null, + iconColor = iconColor, + size = size, + contentDescription = contentDescription + ) + + constructor( + @DrawableRes iconResId: Int, + iconColor: Color, + size: Dp = 24.dp, + contentDescription: String? = null, + ) : this( + faIcon = null, + iconResId = iconResId, + iconColor = iconColor, + size = size, + contentDescription = contentDescription + ) +} \ No newline at end of file diff --git a/design/src/main/res/values/strings.xml b/design/src/main/res/values/strings.xml index d41f001..fd70edb 100644 --- a/design/src/main/res/values/strings.xml +++ b/design/src/main/res/values/strings.xml @@ -1,3 +1,6 @@ Sirio - \ No newline at end of file + Passaggio %1$d di %2$d + Indietro + Avanti + diff --git a/gradle.properties b/gradle.properties index 0b1ecdd..f401b47 100644 --- a/gradle.properties +++ b/gradle.properties @@ -24,7 +24,7 @@ android.nonTransitiveRClass=true android.nonFinalResIds=false # Library properties -LIBRARY_VERSION=8.0.0 +LIBRARY_VERSION=8.1.0 LIBRARY_GROUP=it.inps.sirio LIBRARY_ARTIFACT=library # Github required information diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index af047c6..1805df3 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -6,23 +6,24 @@ sdkTarget = "33" # @keep sdkMin = "21" -gradleAndroid = "8.4.0" +gradleAndroid = "8.5.2" androidxCore = "1.13.1" -androidxAppcompat = "1.6.1" -androidxRuntimeKtx = "2.7.0" -androidxActivityCompose = "1.9.0" +androidxAppcompat = "1.7.0" +androidxRuntimeKtx = "2.8.4" +androidxActivityCompose = "1.9.1" androidxConstraintlayoutCompose = "1.0.1" -kotlin = "1.9.23" -material = "1.11.0" +kotlin = "2.0.0" +material = "1.12.0" accompanist = "0.34.0" -composeBom = "2024.05.00" -composeCompiler = "1.5.13" -composeNavigation = "2.7.7" +composeBom = "2024.06.00" +composeNavigation = "2.8.0-beta06" -coil = "2.6.0" +kotlinxSerializationJson = "1.7.1" + +coil = "2.7.0" fontawesome-compose = "1.1.0" [libraries] @@ -44,6 +45,8 @@ compose-navigation = { group = "androidx.navigation", name = "navigation-compose material = { group = "com.google.android.material", name = "material", version.ref = "material" } accompanist-flowlayout = { group = "com.google.accompanist", name = "accompanist-flowlayout", version.ref = "accompanist" } +jetbrains-kotlinx-serialization-json = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-json", version.ref = "kotlinxSerializationJson" } + coil-compose = { group = "io.coil-kt", name = "coil-compose", version.ref = "coil" } coil-svg = { group = "io.coil-kt", name = "coil-svg", version.ref = "coil" } @@ -91,3 +94,5 @@ fontawesome-compose = [ android-application = { id = "com.android.application", version.ref = "gradleAndroid" } android-library = { id = "com.android.library", version.ref = "gradleAndroid" } kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } +kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" } +compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index ff6da66..61224df 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ #Wed Jan 12 12:44:20 CET 2022 distributionBase=GRADLE_USER_HOME -distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip distributionPath=wrapper/dists zipStorePath=wrapper/dists zipStoreBase=GRADLE_USER_HOME diff --git a/sample/build.gradle.kts b/sample/build.gradle.kts index c62c11b..89e9f7e 100644 --- a/sample/build.gradle.kts +++ b/sample/build.gradle.kts @@ -1,6 +1,8 @@ plugins { alias(libs.plugins.android.application) alias(libs.plugins.kotlin.android) + alias(libs.plugins.kotlin.serialization) + alias(libs.plugins.compose.compiler) } android { @@ -11,8 +13,8 @@ android { applicationId = "it.inps.design.sample" minSdk = libs.versions.sdkMin.get().toInt() targetSdk = libs.versions.sdkTarget.get().toInt() - versionCode = 8 - versionName = "8.0.0" + versionCode = 9 + versionName = "8.1.0" vectorDrawables { useSupportLibrary = true @@ -35,9 +37,6 @@ android { buildFeatures { compose = true } - composeOptions { - kotlinCompilerExtensionVersion = libs.versions.composeCompiler.get() - } packaging { resources.excludes.add("/META-INF/{AL2.0,LGPL2.1}") } @@ -50,4 +49,5 @@ dependencies { implementation(libs.bundles.appcompat) implementation(libs.bundles.material) implementation(libs.bundles.compose) + implementation(libs.jetbrains.kotlinx.serialization.json) } diff --git a/sample/src/main/AndroidManifest.xml b/sample/src/main/AndroidManifest.xml index 1ca4d01..ff7831a 100644 --- a/sample/src/main/AndroidManifest.xml +++ b/sample/src/main/AndroidManifest.xml @@ -10,6 +10,9 @@ android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.Sirio"> + + @@ -30,7 +34,9 @@ + + @@ -39,13 +45,14 @@ + + - diff --git a/sample/src/main/java/it/inps/design/MainActivity.kt b/sample/src/main/java/it/inps/design/MainActivity.kt index 002a357..fb898a2 100644 --- a/sample/src/main/java/it/inps/design/MainActivity.kt +++ b/sample/src/main/java/it/inps/design/MainActivity.kt @@ -32,6 +32,7 @@ import androidx.compose.ui.tooling.preview.Devices import androidx.compose.ui.tooling.preview.Preview import it.inps.design.accordion.AccordionActivity import it.inps.design.appnavigation.AppNavigationActivity +import it.inps.design.avviso.AvvisoActivity import it.inps.design.button.ButtonActivity import it.inps.design.card.CardActivity import it.inps.design.carousel.CarouselActivity @@ -40,18 +41,23 @@ import it.inps.design.chip.ChipActivity import it.inps.design.dialog.DialogActivity import it.inps.design.fab.FabActivity import it.inps.design.fileupload.FileUploadActivity +import it.inps.design.filter.FilterActivity import it.inps.design.hero.HeroActivity +import it.inps.design.menuspalla.MenuSpallaActivity import it.inps.design.notification.NotificationActivity import it.inps.design.pagination.PaginationActivity import it.inps.design.progressbar.ProgressBarActivity import it.inps.design.radiobutton.RadioButtonActivity import it.inps.design.searchbar.SearchBarActivity import it.inps.design.slider.SliderActivity +import it.inps.design.stepprogressbar.StepProgressBarActivity import it.inps.design.tabbar.TabBarActivity +import it.inps.design.table.TableActivity import it.inps.design.tabs.TabActivity import it.inps.design.tag.TagActivity import it.inps.design.textarea.TextAreaActivity import it.inps.design.textfield.TextFieldActivity +import it.inps.design.titlebar.TitleBarActivity import it.inps.design.toggle.ToggleActivity import it.inps.design.ui.DemoMenuItem import it.inps.sirio.theme.SirioTheme @@ -94,6 +100,10 @@ fun DemoContent() { context.startActivity(Intent(context, AppNavigationActivity::class.java)) } HorizontalDivider() + DemoMenuItem("Avviso") { + context.startActivity(Intent(context, AvvisoActivity::class.java)) + } + HorizontalDivider() DemoMenuItem("Buttons") { context.startActivity(Intent(context, ButtonActivity::class.java)) } @@ -126,10 +136,18 @@ fun DemoContent() { context.startActivity(Intent(context, FileUploadActivity::class.java)) } HorizontalDivider() + DemoMenuItem("Filtri") { + context.startActivity(Intent(context, FilterActivity::class.java)) + } + HorizontalDivider() DemoMenuItem("Hero") { context.startActivity(Intent(context, HeroActivity::class.java)) } HorizontalDivider() + DemoMenuItem("Menu spalla") { + context.startActivity(Intent(context, MenuSpallaActivity::class.java)) + } + HorizontalDivider() DemoMenuItem("Notification") { context.startActivity(Intent(context, NotificationActivity::class.java)) } @@ -162,6 +180,10 @@ fun DemoContent() { context.startActivity(Intent(context, SliderActivity::class.java)) } HorizontalDivider() + DemoMenuItem("Step progress bar") { + context.startActivity(Intent(context, StepProgressBarActivity::class.java)) + } + HorizontalDivider() DemoMenuItem("Tab") { context.startActivity(Intent(context, TabActivity::class.java)) } @@ -170,6 +192,10 @@ fun DemoContent() { context.startActivity(Intent(context, TabBarActivity::class.java)) } HorizontalDivider() + DemoMenuItem("Table") { + context.startActivity(Intent(context, TableActivity::class.java)) + } + HorizontalDivider() DemoMenuItem("Tag") { context.startActivity(Intent(context, TagActivity::class.java)) } @@ -182,6 +208,10 @@ fun DemoContent() { context.startActivity(Intent(context, TextFieldActivity::class.java)) } HorizontalDivider() + DemoMenuItem("TitleBar") { + context.startActivity(Intent(context, TitleBarActivity::class.java)) + } + HorizontalDivider() DemoMenuItem("Toggle") { context.startActivity(Intent(context, ToggleActivity::class.java)) } diff --git a/sample/src/main/java/it/inps/design/avviso/AvvisoActivity.kt b/sample/src/main/java/it/inps/design/avviso/AvvisoActivity.kt new file mode 100644 index 0000000..6755ec2 --- /dev/null +++ b/sample/src/main/java/it/inps/design/avviso/AvvisoActivity.kt @@ -0,0 +1,87 @@ +@file:OptIn(ExperimentalMaterial3Api::class) + +package it.inps.design.avviso + +import android.os.Bundle +import androidx.activity.ComponentActivity +import androidx.activity.compose.setContent +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Text +import androidx.compose.material3.TopAppBar +import androidx.compose.material3.TopAppBarDefaults +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import it.inps.sirio.theme.SirioTheme +import it.inps.sirio.ui.avviso.SirioAvviso + +class AvvisoActivity : ComponentActivity() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContent { + SirioTheme { + AvvisoDemoContent() + } + } + } +} + + +@Composable +fun AvvisoDemoContent() { + Scaffold( + topBar = { + TopAppBar( + title = { Text("Avviso") }, + colors = TopAppBarDefaults.topAppBarColors(containerColor = SirioTheme.colors.brand), + ) + }, + ) { + Column( + modifier = Modifier + .fillMaxSize() + .verticalScroll(rememberScrollState()) + .padding(it), + verticalArrangement = Arrangement.spacedBy(20.dp), + ) { + val title = "Titolo avviso" + val text = + "Ac iaculis posuere turpis diam mi non viverra tempus eget. Nunc volutpat nunc erat risus eleifend convallis viverra bibendum. Mattis ante mauris sit montes. Scelerisque dui arcu tempus proin massa massa ultricies nunc duis." + val buttonText = "Text" + val onButtonClick = {} + SirioTheme { + SirioAvviso( + title = title, + text = text, + buttonText = buttonText, + onButtonClick = onButtonClick, + ) + } + SirioTheme(darkTheme = true) { + SirioAvviso( + title = title, + text = text, + buttonText = buttonText, + onButtonClick = onButtonClick, + ) + } + } + } +} + + +@Preview(showBackground = true) +@Composable +private fun AvvisoActivityPreview() { + SirioTheme { + AvvisoDemoContent() + } +} \ No newline at end of file diff --git a/sample/src/main/java/it/inps/design/button/ButtonActivity.kt b/sample/src/main/java/it/inps/design/button/ButtonActivity.kt index 543ca1c..2d7faf0 100644 --- a/sample/src/main/java/it/inps/design/button/ButtonActivity.kt +++ b/sample/src/main/java/it/inps/design/button/ButtonActivity.kt @@ -252,20 +252,23 @@ private fun ButtonDemoContent(text: String, style: ButtonStyle, size: ButtonSize enabled = true, style = style, size = size, - onClick = {}) + onClick = {}, + ) SirioButton( text = text, icon = FaIcons.ArrowRight, enabled = true, style = style, size = size, - onClick = {}) + onClick = {}, + ) SirioButton( icon = FaIcons.ArrowRight, enabled = true, style = style, size = size, - onClick = {}) + onClick = {}, + ) } Spacer(modifier = Modifier.width(8.dp)) Column( diff --git a/sample/src/main/java/it/inps/design/carousel/CarouselActivity.kt b/sample/src/main/java/it/inps/design/carousel/CarouselActivity.kt index bbb020d..dc9dd79 100644 --- a/sample/src/main/java/it/inps/design/carousel/CarouselActivity.kt +++ b/sample/src/main/java/it/inps/design/carousel/CarouselActivity.kt @@ -84,6 +84,20 @@ fun CarouselDemoContent() { text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt.", button = "Text" ), + CarouselSampleData( + icon = FaIcons.Book, + date = "13 Nov 2021", + title = "Titolo della card 3", + text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt.", + button = "Text" + ), + CarouselSampleData( + icon = FaIcons.Book, + date = "13 Nov 2021", + title = "Titolo della card 4", + text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt.", + button = "Text" + ), ) Scaffold( topBar = { @@ -142,4 +156,4 @@ private fun CarouselActivityPreview() { SirioTheme { CarouselDemoContent() } -} \ No newline at end of file +} diff --git a/sample/src/main/java/it/inps/design/chip/ChipActivity.kt b/sample/src/main/java/it/inps/design/chip/ChipActivity.kt index 6f0d3e7..3728a68 100644 --- a/sample/src/main/java/it/inps/design/chip/ChipActivity.kt +++ b/sample/src/main/java/it/inps/design/chip/ChipActivity.kt @@ -48,10 +48,10 @@ import androidx.navigation.compose.rememberNavController import com.guru.fontawesomecomposelib.FaIcons import it.inps.design.ui.DemoMenuItem import it.inps.sirio.theme.SirioTheme -import it.inps.sirio.ui.chip.ChipLabel -import it.inps.sirio.ui.chip.ChipLabelClose -import it.inps.sirio.ui.chip.ChipLabelIcon -import it.inps.sirio.ui.chip.ChipLabelIconClose +import it.inps.sirio.ui.chip.SirioChipLabel +import it.inps.sirio.ui.chip.SirioChipLabelClose +import it.inps.sirio.ui.chip.SirioChipLabelIcon +import it.inps.sirio.ui.chip.SirioChipLabelIconClose class ChipActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { @@ -95,18 +95,18 @@ private fun ChipDemoView() { var isActive4 by remember { mutableStateOf(false) } val label = "Chips" Text(text = "Big Chips Label + Icon + Close") - ChipLabelIconClose(label = label, icon = FaIcons.User, enabled = true) {} + SirioChipLabelIconClose(label = label, icon = FaIcons.User, enabled = true) {} Text(text = "Big Chips Label + Close") - ChipLabelClose(label = label, enabled = true) {} + SirioChipLabelClose(label = label, enabled = true) {} Text(text = "Big Chips Label + Icon") - ChipLabelIcon( + SirioChipLabelIcon( label = label, icon = FaIcons.Check, enabled = true, isActive = isActive3, onStateChange = { isActive3 = it }) Text(text = "Big Chips Only Label") - ChipLabel( + SirioChipLabel( label = label, enabled = true, active = isActive4, @@ -183,8 +183,8 @@ fun ChipLabelIconCloseDemoContent() { .padding(0.dp, 4.dp), verticalArrangement = Arrangement.spacedBy(8.dp) ) { - ChipLabelIconClose(label = title, icon = FaIcons.User, enabled = true) {} - ChipLabelIconClose(label = title, icon = FaIcons.User, enabled = false) {} + SirioChipLabelIconClose(label = title, icon = FaIcons.User, enabled = true) {} + SirioChipLabelIconClose(label = title, icon = FaIcons.User, enabled = false) {} } } @@ -199,8 +199,8 @@ fun ChipLabelCloseDemoContent() { .padding(0.dp, 4.dp), verticalArrangement = Arrangement.spacedBy(8.dp) ) { - ChipLabelClose(label = title, enabled = true) {} - ChipLabelClose(label = title, enabled = false) {} + SirioChipLabelClose(label = title, enabled = true) {} + SirioChipLabelClose(label = title, enabled = false) {} } } @@ -218,19 +218,19 @@ fun ChipLabelIconDemoContent() { var isActive1 by remember { mutableStateOf(true) } var isActive2 by remember { mutableStateOf(true) } var isActive3 by remember { mutableStateOf(false) } - ChipLabelIcon( + SirioChipLabelIcon( label = title, icon = FaIcons.User, enabled = true, isActive = isActive1, onStateChange = { isActive1 = it }) - ChipLabelIcon( + SirioChipLabelIcon( label = title, icon = FaIcons.User, enabled = false, isActive = isActive2, onStateChange = { isActive2 = it }) - ChipLabelIcon( + SirioChipLabelIcon( label = title, icon = FaIcons.User, enabled = true, @@ -253,17 +253,17 @@ fun ChipLabelDemoContent() { var isActive1 by remember { mutableStateOf(true) } var isActive2 by remember { mutableStateOf(true) } var isActive3 by remember { mutableStateOf(false) } - ChipLabel( + SirioChipLabel( label = title, enabled = true, active = isActive1, onStateChange = { isActive1 = it }) - ChipLabel( + SirioChipLabel( label = title, enabled = false, active = isActive2, onStateChange = { isActive2 = it }) - ChipLabel( + SirioChipLabel( label = title, enabled = true, active = isActive3, diff --git a/sample/src/main/java/it/inps/design/filter/FilterActivity.kt b/sample/src/main/java/it/inps/design/filter/FilterActivity.kt new file mode 100644 index 0000000..cc04282 --- /dev/null +++ b/sample/src/main/java/it/inps/design/filter/FilterActivity.kt @@ -0,0 +1,311 @@ +// +// FilterActivity.kt +// +// SPDX-FileCopyrightText: 2022 Istituto Nazionale Previdenza Sociale +// +// SPDX-License-Identifier: BSD-3-Clause +// +@file:OptIn(ExperimentalMaterial3Api::class) + +package it.inps.design.filter + +import android.os.Bundle +import androidx.activity.ComponentActivity +import androidx.activity.compose.setContent +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.HorizontalDivider +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Text +import androidx.compose.material3.TopAppBar +import androidx.compose.material3.TopAppBarDefaults +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableIntStateOf +import androidx.compose.runtime.mutableStateListOf +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import androidx.navigation.NavController +import androidx.navigation.compose.NavHost +import androidx.navigation.compose.composable +import androidx.navigation.compose.rememberNavController +import it.inps.design.ui.DemoMenuItem +import it.inps.sirio.styleDictionary.StyleDictionaryColor +import it.inps.sirio.theme.SirioTheme +import it.inps.sirio.ui.filter.SirioFilterCheckbox +import it.inps.sirio.ui.filter.SirioFilterChips +import it.inps.sirio.ui.filter.SirioFilterChipsWrap +import it.inps.sirio.ui.filter.SirioFilterFooter +import it.inps.sirio.ui.filter.SirioFilterHeader +import it.inps.sirio.ui.filter.SirioFilterInput +import it.inps.sirio.ui.filter.SirioFilterRadio +import it.inps.sirio.ui.filter.SirioFilterSelected +import it.inps.sirio.ui.filter.SirioFilterTabs +import it.inps.sirio.ui.filter.SirioFilterTitle +import it.inps.sirio.ui.filter.SirioFilterToggle +import it.inps.sirio.ui.tabs.TabItemData + +private const val SELECTED = "Selected" +private const val DRAWER = "Drawer" +private const val TABS = "Tabs" + +class FilterActivity : ComponentActivity() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContent { + SirioTheme { + FilterDemoView() + } + } + } +} + +@Composable +private fun FilterDemoView() { + Scaffold( + Modifier.fillMaxSize(), + topBar = { + TopAppBar( + title = { Text(text = "Filtri") }, + colors = TopAppBarDefaults.topAppBarColors(containerColor = SirioTheme.colors.brand) + ) + } + ) { + val navController = rememberNavController() + NavHost( + navController = navController, + startDestination = "/", + modifier = Modifier.padding(it), + ) { + composable("/") { + FilterMenuDemo(navController = navController) + } + composable(SELECTED) { + FilterSelectedDemo() + } + composable(DRAWER) { + FilterDrawerDemo() + } + composable(TABS) { + FilterTabsDemo() + } + } + } +} + +@Composable +fun FilterMenuDemo(navController: NavController) { + Column( + modifier = Modifier.verticalScroll(rememberScrollState()), + ) { + DemoMenuItem(SELECTED) { + navController.navigate(SELECTED) + } + HorizontalDivider() + DemoMenuItem(DRAWER) { + navController.navigate(DRAWER) + } + HorizontalDivider() + DemoMenuItem(TABS) { + navController.navigate(TABS) + } + } +} + +@Composable +private fun FilterSelectedDemo() { + Column( + Modifier.verticalScroll(rememberScrollState()), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.spacedBy(20.dp) + ) { + Spacer(modifier = Modifier.height(20.dp)) + Text(text = "Selected") + val state = remember { + mutableStateListOf( + elements = arrayOf( + "Valore A", + "Valore B", + "Valore C", + "Valore D", + "Valore E" + ) + ) + } + SirioFilterSelected( + values = state, + onDeleteValue = { state.remove(it) } + ) + } +} + +@Composable +private fun FilterDrawerDemo() { + Column( + Modifier + .fillMaxSize() + .background(StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight50) + .verticalScroll(rememberScrollState()) + .padding(vertical = 20.dp, horizontal = 0.dp), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.spacedBy(31.dp) + ) { + var radio by remember { mutableStateOf(false) } + var checkbox by remember { mutableStateOf(false) } + var toggle by remember { mutableStateOf(false) } + val chips = remember { mutableStateListOf(elements = arrayOf()) } + val chipsWrap = remember { mutableStateListOf(elements = arrayOf()) } + var input by remember { mutableStateOf("") } + SirioFilterHeader(title = "Filtri", onClose = {}) + SirioFilterRadio(selected = radio, text = "Title", onClick = { radio = !radio }) + SirioFilterCheckbox(checked = checkbox, text = "Title", onCheckedChange = { checkbox = it }) + SirioFilterToggle(isOn = toggle, text = "Title", onToggleChange = { toggle = it }) + SirioFilterTitle(text = "Section Title #") + SirioFilterChips( + texts = listOf( + "Valore 1", + "Valore 2", + "Valore 3", + "Valore 4", + "Valore 5", + "Valore 6" + ), + selectedTexts = chips, + onSelectedChanges = { + chips.clear() + chips.addAll(it) + } + ) + SirioFilterChipsWrap( + texts = listOf( + "Valore 1", + "Valore 2", + "Valore 3", + "Valore 4", + "Valore 5", + "Valore 6" + ), + selectedTexts = chipsWrap, + onSelectedChanges = { + chipsWrap.clear() + chipsWrap.addAll(it) + }, + ) + SirioFilterInput( + label = "Label", + text = input, + placeholder = "Text", + onValueChange = { input = it }, + ) + SirioFilterFooter( + neutralText = "Elimina filtri", + positiveText = "Applica filtri", + onNeutral = {}, + onPositive = {} + ) + } +} + +@Composable +private fun FilterTabsDemo() { + Column( + Modifier + .fillMaxSize() + .background(StyleDictionaryColor.colorAliasBackgroundColorPrimaryLight50) + .verticalScroll(rememberScrollState()) + .padding(vertical = 20.dp, horizontal = 0.dp), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.spacedBy(31.dp) + ) { + var selectedTabIndex by remember { mutableIntStateOf(0) } + SirioFilterTabs( + items = listOf( + TabItemData("Label tab 0"), + TabItemData("Label tab 1"), + TabItemData("Label tab 2"), + TabItemData("Label tab 3"), + TabItemData("Label tab 4"), + ), + selectedIndex = selectedTabIndex, + withScroll = true, + onTabSelected = { selectedTabIndex = it } + ) + SirioFilterTabs( + items = listOf( + TabItemData("Label tab 0"), + TabItemData("Label tab 1"), + TabItemData("Label tab 2"), + TabItemData("Label tab 3"), + TabItemData("Label tab 4"), + ), + selectedIndex = selectedTabIndex, + onTabSelected = { selectedTabIndex = it } + ) + FilterTabDemoContent(selectedTabIndex) + SirioFilterFooter( + neutralText = "Elimina", + positiveText = "Applica", + onNeutral = {}, + onPositive = {} + ) + } +} + +@Composable +private fun FilterTabDemoContent(i: Int) { + Column(verticalArrangement = Arrangement.spacedBy(31.dp)) { + val radio = remember { + mutableStateListOf(elements = arrayOf(false, false, false, false, false)) + } + val checkbox = remember { + mutableStateListOf(elements = arrayOf(false, false, false, false, false)) + } + val toggle = remember { + mutableStateListOf(elements = arrayOf(false, false, false, false, false)) + } + val input = remember { + mutableStateListOf(elements = arrayOf("", "", "", "", "")) + } + SirioFilterInput( + label = "Label $i", + text = input[i], + placeholder = "Text $i", + onValueChange = { input[i] = it }, + ) + SirioFilterCheckbox( + checked = checkbox[i], + text = "Title $i", + onCheckedChange = { checkbox[i] = it }) + SirioFilterRadio(selected = radio[i], text = "Title $i", onClick = { radio[i] = !radio[i] }) + SirioFilterToggle(isOn = toggle[i], text = "Title $i", onToggleChange = { toggle[i] = it }) + } +} + +@Preview +@Composable +private fun FilterActivityPreview() { + SirioTheme { + FilterDemoView() + } +} + +@Preview +@Composable +private fun FilterTabsDemoPreview() { + SirioTheme { + FilterTabsDemo() + } +} \ No newline at end of file diff --git a/sample/src/main/java/it/inps/design/menuspalla/MenuSpallaActivity.kt b/sample/src/main/java/it/inps/design/menuspalla/MenuSpallaActivity.kt new file mode 100644 index 0000000..9d67a06 --- /dev/null +++ b/sample/src/main/java/it/inps/design/menuspalla/MenuSpallaActivity.kt @@ -0,0 +1,522 @@ +// +// MenuSpallaActivity.kt +// +// SPDX-FileCopyrightText: 2022 Istituto Nazionale Previdenza Sociale +// +// SPDX-License-Identifier: BSD-3-Clause +// +@file:OptIn(ExperimentalMaterial3Api::class) + +package it.inps.design.menuspalla + +import android.os.Bundle +import android.util.Log +import androidx.activity.ComponentActivity +import androidx.activity.compose.setContent +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.HorizontalDivider +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Text +import androidx.compose.material3.TopAppBar +import androidx.compose.material3.TopAppBarDefaults +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import androidx.navigation.NavController +import androidx.navigation.compose.NavHost +import androidx.navigation.compose.composable +import androidx.navigation.compose.rememberNavController +import com.guru.fontawesomecomposelib.FaIcons +import it.inps.design.ui.DemoMenuItem +import it.inps.sirio.theme.SirioTheme +import it.inps.sirio.ui.menuspalla.SirioMenuSpalla +import it.inps.sirio.ui.menuspalla.SirioMenuSpallaDrawerItem +import it.inps.sirio.ui.menuspalla.SirioMenuSpallaDrawerItemInfo +import it.inps.sirio.ui.menuspalla.SirioMenuSpallaItem +import it.inps.sirio.ui.menuspalla.SirioMenuSpallaItemData +import it.inps.sirio.ui.menuspalla.SirioMenuSpallaItemLevel +import it.inps.sirio.ui.menuspalla.SirioMenuSpallaItemTitleSection +import it.inps.sirio.ui.menuspalla.SirioMenuSpallaSectionItemData + +private const val INTESTAZIONE = "Intestazione" +private const val FIRST_LEVEL = "Base components - Primo livello" +private const val SECOND_LEVEL = "Base components - Secondo livello" +private const val THIRD_LEVEL = "Base components - Terzo livello" +private const val DRAWER = "Base components - Mobile Drawer" +private const val DEMO = "Demo" + +class MenuSpallaActivity : ComponentActivity() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContent { + SirioTheme { + MenuSpallaDemoView() + } + } + } +} + +@Composable +private fun MenuSpallaDemoView() { + Scaffold( + Modifier.fillMaxSize(), + topBar = { + TopAppBar( + title = { Text(text = "Menu spalla") }, + colors = TopAppBarDefaults.topAppBarColors(containerColor = SirioTheme.colors.brand) + ) + } + ) { + val navController = rememberNavController() + NavHost( + navController = navController, + startDestination = "/", + modifier = Modifier.padding(it), + ) { + composable("/") { + MenuSpallaMenuDemo(navController = navController) + } + composable(INTESTAZIONE) { + MenuSpallaIntestazioneDemo() + } + composable(FIRST_LEVEL) { + MenuSpallaFirstLevelDemo() + } + composable(SECOND_LEVEL) { + MenuSpallaSecondLevelDemo() + } + composable(THIRD_LEVEL) { + MenuSpallaThirdLevelDemo() + } + composable(DRAWER) { + MenuSpallaDrawerDemo() + } + composable(DEMO) { + MenuSpallaDemo() + } + } + } +} + +@Composable +fun MenuSpallaMenuDemo(navController: NavController) { + Box(Modifier.fillMaxSize(), contentAlignment = Alignment.BottomCenter) { + Column( + modifier = Modifier + .align(Alignment.TopCenter) + .verticalScroll(rememberScrollState()), + ) { + DemoMenuItem(INTESTAZIONE) { + navController.navigate(INTESTAZIONE) + } + HorizontalDivider() + DemoMenuItem(FIRST_LEVEL) { + navController.navigate(FIRST_LEVEL) + } + HorizontalDivider() + DemoMenuItem(SECOND_LEVEL) { + navController.navigate(SECOND_LEVEL) + } + HorizontalDivider() + DemoMenuItem(THIRD_LEVEL) { + navController.navigate(THIRD_LEVEL) + } + HorizontalDivider() + DemoMenuItem(DRAWER) { + navController.navigate(DRAWER) + } + HorizontalDivider() + DemoMenuItem(DEMO) { + navController.navigate(DEMO) + } + } + } +} + +@Composable +private fun MenuSpallaIntestazioneDemo() { + Column( + Modifier.verticalScroll(rememberScrollState()), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.spacedBy(20.dp) + ) { + Spacer(modifier = Modifier.height(20.dp)) + Text(text = "Intestazione") + SirioMenuSpallaItemTitleSection(title = "Label menu") + } +} + +@Composable +private fun MenuSpallaFirstLevelDemo() { + Column( + Modifier.verticalScroll(rememberScrollState()), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.spacedBy(20.dp) + ) { + Spacer(modifier = Modifier.height(20.dp)) + Text(text = "Item / Primario + Chip") + SirioMenuSpallaItem( + title = "Label", + level = SirioMenuSpallaItemLevel.FIRST, + tagText = "3", + selected = false, + enabled = true, + hasSubItems = false, + onClick = {}, + ) + SirioMenuSpallaItem( + title = "Label", + level = SirioMenuSpallaItemLevel.FIRST, + tagText = "3", + selected = false, + enabled = false, + hasSubItems = false, + onClick = {}, + ) + SirioMenuSpallaItem( + title = "Label", + level = SirioMenuSpallaItemLevel.FIRST, + tagText = "3", + selected = true, + enabled = true, + hasSubItems = false, + onClick = {}, + ) + Text(text = "Item / Primario / Sub-item") + SirioMenuSpallaItem( + title = "Label", + level = SirioMenuSpallaItemLevel.FIRST, + tagText = "3", + selected = false, + enabled = true, + hasSubItems = true, + onClick = {}, + ) + SirioMenuSpallaItem( + title = "Label", + level = SirioMenuSpallaItemLevel.FIRST, + tagText = "3", + selected = false, + enabled = false, + hasSubItems = true, + onClick = {}, + ) + SirioMenuSpallaItem( + title = "Label", + level = SirioMenuSpallaItemLevel.FIRST, + tagText = "3", + selected = true, + enabled = true, + hasSubItems = true, + onClick = {}, + ) + Text(text = "Item / Primario") + SirioMenuSpallaItem( + title = "Label", + level = SirioMenuSpallaItemLevel.FIRST, + tagText = null, + selected = false, + enabled = true, + hasSubItems = false, + onClick = {}, + ) + SirioMenuSpallaItem( + title = "Label", + level = SirioMenuSpallaItemLevel.FIRST, + selected = false, + enabled = false, + hasSubItems = false, + onClick = {}, + ) + SirioMenuSpallaItem( + title = "Label", + level = SirioMenuSpallaItemLevel.FIRST, + tagText = "", + selected = true, + enabled = true, + hasSubItems = false, + onClick = {}, + ) + } +} + +@Composable +private fun MenuSpallaSecondLevelDemo() { + Column( + Modifier.verticalScroll(rememberScrollState()), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.spacedBy(20.dp) + ) { + Spacer(modifier = Modifier.height(20.dp)) + Text(text = "Item / Secondario / Sub-item") + SirioMenuSpallaItem( + title = "Label", + level = SirioMenuSpallaItemLevel.SECOND, + tagText = "3", + selected = false, + enabled = true, + hasSubItems = true, + onClick = {}, + ) + SirioMenuSpallaItem( + title = "Label", + level = SirioMenuSpallaItemLevel.SECOND, + tagText = "3", + selected = false, + enabled = false, + hasSubItems = true, + onClick = {}, + ) + SirioMenuSpallaItem( + title = "Label", + level = SirioMenuSpallaItemLevel.SECOND, + tagText = "3", + selected = true, + enabled = true, + hasSubItems = true, + onClick = {}, + ) + Text(text = "Item / Secondario / Sub-item") + SirioMenuSpallaItem( + title = "Label", + level = SirioMenuSpallaItemLevel.SECOND, + tagText = "3", + selected = false, + enabled = true, + hasSubItems = false, + onClick = {}, + ) + SirioMenuSpallaItem( + title = "Label", + level = SirioMenuSpallaItemLevel.SECOND, + tagText = "3", + selected = false, + enabled = false, + hasSubItems = false, + onClick = {}, + ) + SirioMenuSpallaItem( + title = "Label", + level = SirioMenuSpallaItemLevel.SECOND, + tagText = "3", + selected = true, + enabled = true, + hasSubItems = false, + onClick = {}, + ) + } +} + +@Composable +private fun MenuSpallaThirdLevelDemo() { + Column( + Modifier.verticalScroll(rememberScrollState()), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.spacedBy(20.dp) + ) { + Spacer(modifier = Modifier.height(20.dp)) + Text(text = "Item / Terziario") + SirioMenuSpallaItem( + title = "Label", + level = SirioMenuSpallaItemLevel.THIRD, + tagText = "3", + selected = false, + enabled = true, + hasSubItems = true, + onClick = {}, + ) + SirioMenuSpallaItem( + title = "Label", + level = SirioMenuSpallaItemLevel.THIRD, + tagText = "3", + selected = false, + enabled = false, + hasSubItems = true, + onClick = {}, + ) + SirioMenuSpallaItem( + title = "Label", + level = SirioMenuSpallaItemLevel.THIRD, + tagText = "3", + selected = true, + enabled = true, + hasSubItems = true, + onClick = {}, + ) + } +} + +@Composable +private fun MenuSpallaDrawerDemo() { + Column( + Modifier.verticalScroll(rememberScrollState()), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.spacedBy(20.dp) + ) { + Spacer(modifier = Modifier.height(20.dp)) + Text(text = "Mobile / item") + val title = "Action Label" + val subtitle = "Placeholder Label" + SirioMenuSpallaDrawerItem( + title = title, + subtitle = subtitle, + open = false, + onStateChange = {} + ) + SirioMenuSpallaDrawerItem( + title = title, + subtitle = subtitle, + open = true, + onStateChange = {} + ) + SirioMenuSpallaDrawerItemInfo( + title = "Mario Rossi", + subtitle = "Profilo Cittadino", + icon = FaIcons.User, + ) + } +} + +@Composable +private fun MenuSpallaDemo() { + Column( + modifier = Modifier.fillMaxSize(), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.Bottom + ) { + var title by remember { mutableStateOf("Apri menu") } + val sections = listOf( + SirioMenuSpallaSectionItemData( + title = "Titolo sezione", + items = listOf( + SirioMenuSpallaItemData( + title = "Label tag", + tag = "3", + onClick = { + Log.d( + "SirioMenuSpallaPreview", + "SirioMenuSpallaPreview: label tag" + ) + }, + ), + SirioMenuSpallaItemData( + title = "Label 1", + tag = "1", + children = listOf( + SirioMenuSpallaItemData( + title = "Label 1.1", + tag = "1.1", + onClick = { + Log.d( + "SirioMenuSpallaPreview", + "SirioMenuSpallaPreview: label 1.1" + ) + } + ), + SirioMenuSpallaItemData( + title = "Label 1.2", + tag = "1.2", + children = listOf( + SirioMenuSpallaItemData( + title = "Label 1.2.1", + tag = "1.2.1", + onClick = { + Log.d( + "SirioMenuSpallaPreview", + "SirioMenuSpallaPreview: label 1.2.1" + ) + } + ), + SirioMenuSpallaItemData( + title = "Label 1.2.2", + tag = "1.2.2", + onClick = { + Log.d( + "SirioMenuSpallaPreview", + "SirioMenuSpallaPreview: label 1.2.2" + ) + } + ) + ), + onClick = { + Log.d( + "SirioMenuSpallaPreview", + "SirioMenuSpallaPreview: label 1.2" + ) + } + ) + ), + onClick = { + Log.d( + "SirioMenuSpallaPreview", + "SirioMenuSpallaPreview: label 1" + ) + }, + ), + SirioMenuSpallaItemData( + title = "Label 2", + tag = "2", + children = listOf( + SirioMenuSpallaItemData( + title = "Label 2.1", + tag = "2.1", + onClick = { + Log.d( + "SirioMenuSpallaPreview", + "SirioMenuSpallaPreview: label 2.1" + ) + } + ) + ), + onClick = { + Log.d( + "SirioMenuSpallaPreview", + "SirioMenuSpallaPreview: label 2" + ) + }, + ), + SirioMenuSpallaItemData( + title = "Label 3", + onClick = { + Log.d( + "SirioMenuSpallaPreview", + "SirioMenuSpallaPreview: label 3" + ) + }, + ), + ), + ) + ) + SirioMenuSpalla( + title = title, + subtitle = "Titolo sezione", + sections = sections, + onStateChange = { open -> + title = if (open) "Chiudi menu" else "Apri menu" + } + ) + } +} + +@Preview +@Composable +private fun MenuSpallaActivityPreview() { + SirioTheme { + MenuSpallaDemoView() + } +} \ No newline at end of file diff --git a/sample/src/main/java/it/inps/design/stepprogressbar/StepProgressBarActivity.kt b/sample/src/main/java/it/inps/design/stepprogressbar/StepProgressBarActivity.kt new file mode 100644 index 0000000..67547c5 --- /dev/null +++ b/sample/src/main/java/it/inps/design/stepprogressbar/StepProgressBarActivity.kt @@ -0,0 +1,149 @@ +// +// StepProgressBarActivity.kt +// +// SPDX-FileCopyrightText: 2022 Istituto Nazionale Previdenza Sociale +// +// SPDX-License-Identifier: BSD-3-Clause +// +@file:OptIn(ExperimentalMaterial3Api::class) + +package it.inps.design.stepprogressbar + +import android.os.Bundle +import androidx.activity.ComponentActivity +import androidx.activity.compose.setContent +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.ColumnScope +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.HorizontalDivider +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Text +import androidx.compose.material3.TopAppBar +import androidx.compose.material3.TopAppBarDefaults +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableIntStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.sp +import androidx.navigation.NavController +import androidx.navigation.compose.NavHost +import androidx.navigation.compose.composable +import androidx.navigation.compose.rememberNavController +import it.inps.design.ui.DemoMenuItem +import it.inps.sirio.theme.SirioTheme +import it.inps.sirio.ui.stepprogressbar.SirioStepControls +import it.inps.sirio.ui.stepprogressbar.SirioStepSelection + +private const val DEMO = "Demo" + +class StepProgressBarActivity : ComponentActivity() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContent { + SirioTheme { + StepProgressBarDemoView() + } + } + } +} + +@Composable +private fun StepProgressBarDemoView() { + Scaffold( + Modifier.fillMaxSize(), + topBar = { + TopAppBar( + title = { Text(text = "Step progress bar") }, + colors = TopAppBarDefaults.topAppBarColors(containerColor = SirioTheme.colors.brand) + ) + } + ) { + val navController = rememberNavController() + NavHost( + navController = navController, + startDestination = "/", + modifier = Modifier.padding(it), + ) { + composable("/") { + StepProgressBarMenuDemo(navController = navController) + } + composable(DEMO) { + StepProgressBarDemo() + } + } + } +} + +@Composable +private fun StepProgressBarMenuDemo(navController: NavController) { + Box(Modifier.fillMaxSize(), contentAlignment = Alignment.BottomCenter) { + Column( + modifier = Modifier + .align(Alignment.TopCenter) + .verticalScroll(rememberScrollState()), + ) { + DemoMenuItem(DEMO) { + navController.navigate(DEMO) + } + HorizontalDivider() + } + } +} + +@Composable +private fun StepProgressBarDemo() { + Column( + modifier = Modifier.fillMaxSize(), + ) { + var index by remember { mutableIntStateOf(1) } + val totalSteps = 6 + SirioStepSelection(progress = index, total = totalSteps, currentStep = "Step $index") + StepDemo(index) + SirioStepControls( + previousEnabled = index > 1, + nextEnabled = index < totalSteps, + onPrevious = { --index }, + onNext = { ++index }) + } +} + +@Composable +private fun ColumnScope.StepDemo(index: Int) { + Box( + modifier = Modifier + .fillMaxWidth() + .weight(1f) + .background(Color.White), + contentAlignment = Alignment.Center + ) { + Text(text = "$index", fontSize = 30.sp) + } +} + +@Preview +@Composable +private fun StepProgressBarActivityPreview() { + SirioTheme { + StepProgressBarDemoView() + } +} + +@Preview +@Composable +private fun StepProgressBarDemoPreview() { + SirioTheme { + StepProgressBarDemo() + } +} \ No newline at end of file diff --git a/sample/src/main/java/it/inps/design/tabbar/Navigation.kt b/sample/src/main/java/it/inps/design/tabbar/Navigation.kt index 6c74a6d..8bd06b2 100644 --- a/sample/src/main/java/it/inps/design/tabbar/Navigation.kt +++ b/sample/src/main/java/it/inps/design/tabbar/Navigation.kt @@ -15,20 +15,17 @@ import androidx.navigation.compose.composable @Composable fun NavigationGraph(navController: NavHostController) { - NavHost(navController, startDestination = HOME_TAB.route) { - composable(HOME_TAB.route) { + NavHost(navController, startDestination = Home) { + composable { HomeScreen() } - composable(NEWS_TAB.route) { + composable { NewsScreen() } - composable(MAP_TAB.route) { + composable { MapScreen() } - composable(CONTACTS_TAB.route) { - ContactsScreen() - } - composable(SERVICES_TAB.route) { + composable { ServicesScreen() } } @@ -54,4 +51,4 @@ fun NavigationGraph(navController: NavHostController) { // ServicesScreen() // } // } -//} \ No newline at end of file +//} diff --git a/sample/src/main/java/it/inps/design/tabbar/TabBarActivity.kt b/sample/src/main/java/it/inps/design/tabbar/TabBarActivity.kt index 125bede..8820a10 100644 --- a/sample/src/main/java/it/inps/design/tabbar/TabBarActivity.kt +++ b/sample/src/main/java/it/inps/design/tabbar/TabBarActivity.kt @@ -22,22 +22,31 @@ import androidx.compose.material3.Text import androidx.compose.material3.TopAppBar import androidx.compose.material3.TopAppBarDefaults import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableIntStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.Devices import androidx.compose.ui.tooling.preview.Preview import androidx.navigation.compose.rememberNavController import com.guru.fontawesomecomposelib.FaIcons import it.inps.sirio.theme.SirioTheme -import it.inps.sirio.ui.tabbar.TabBar -import it.inps.sirio.ui.tabbar.TabBarItemData +import it.inps.sirio.ui.tabbar.SirioTabBar +import it.inps.sirio.ui.tabbar.SirioTabBarItemData +import kotlinx.serialization.Serializable -val HOME_TAB = TabBarItemData(label = "Home", icon = FaIcons.Home, route = "Home") -val NEWS_TAB = TabBarItemData(label = "News", icon = FaIcons.Bell, route = "Notizie", badge = true) -val MAP_TAB = TabBarItemData(label = "Mappa", icon = FaIcons.Globe, route = "Mappa") -val CONTACTS_TAB = - TabBarItemData(label = "Contattaci", icon = FaIcons.CommentAlt, route = "Contatti") -val SERVICES_TAB = - TabBarItemData(label = "Servizi", icon = FaIcons.GripHorizontal, route = "Servizi") +@Serializable +object Home + +@Serializable +object Notizie + +@Serializable +object Mappa + +@Serializable +object Servizi class TabBarActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { @@ -53,9 +62,53 @@ class TabBarActivity : ComponentActivity() { } @Composable -fun TabBarDemoContent() { - val listItems = listOf(HOME_TAB, NEWS_TAB, MAP_TAB, CONTACTS_TAB, SERVICES_TAB) +fun TabBarDemoContent(logout: () -> Unit = {}) { val navController = rememberNavController() + var selectedIndex: Int by remember { mutableIntStateOf(0) } + val listItems = listOf( + SirioTabBarItemData( + label = "Home", + icon = FaIcons.Home, + action = { + navController.navigate(Home) + selectedIndex = 0 + } + ), + SirioTabBarItemData( + label = "News", + icon = FaIcons.Bell, + action = { + navController.navigate(Notizie) + selectedIndex = 1 + }, + badge = true + ), + SirioTabBarItemData( + label = "Mappa", + icon = FaIcons.Globe, + action = { + navController.navigate(Mappa) + selectedIndex = 2 + } + ), + SirioTabBarItemData( + label = "Servizi", + icon = FaIcons.GripHorizontal, + action = { + navController.navigate(Servizi) + selectedIndex = 3 + } + ), + SirioTabBarItemData( + label = "Logout", + icon = FaIcons.SignOutAlt, + action = { + logout() + navController.navigate(Home) + selectedIndex = 0 + } + ), + ) Scaffold( topBar = { TopAppBar( @@ -64,7 +117,7 @@ fun TabBarDemoContent() { ) }, bottomBar = { - TabBar(items = listItems, navController = navController) + SirioTabBar(items = listItems, selectedIndex = selectedIndex) } ) { Box(modifier = Modifier.padding(it)) { diff --git a/sample/src/main/java/it/inps/design/table/TableActivity.kt b/sample/src/main/java/it/inps/design/table/TableActivity.kt new file mode 100644 index 0000000..de1d23f --- /dev/null +++ b/sample/src/main/java/it/inps/design/table/TableActivity.kt @@ -0,0 +1,979 @@ +@file:OptIn(ExperimentalMaterial3Api::class) + +package it.inps.design.table + +import android.os.Bundle +import androidx.activity.ComponentActivity +import androidx.activity.compose.setContent +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.HorizontalDivider +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Text +import androidx.compose.material3.TopAppBar +import androidx.compose.material3.TopAppBarDefaults +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import androidx.navigation.NavController +import androidx.navigation.compose.NavHost +import androidx.navigation.compose.composable +import androidx.navigation.compose.rememberNavController +import com.guru.fontawesomecomposelib.FaIcons +import it.inps.design.ui.DemoMenuItem +import it.inps.sirio.theme.SirioTheme +import it.inps.sirio.ui.table.SirioTable +import it.inps.sirio.ui.table.SirioTableCellType +import it.inps.sirio.ui.table.SirioTableContentAlignment +import it.inps.sirio.ui.table.SirioTableContentSize +import it.inps.sirio.ui.table.SirioTableIconData +import it.inps.sirio.ui.table.SirioTableRowData +import it.inps.sirio.ui.table.drawer.SirioTableDrawer +import it.inps.sirio.ui.table.drawer.SirioTableDrawerItemData +import it.inps.sirio.ui.table.drawer.SirioTableDrawerItemType +import it.inps.sirio.ui.table.vertical.SirioTableVertical +import it.inps.sirio.ui.table.vertical.SirioTableVerticalCellData +import it.inps.sirio.ui.table.vertical.SirioTableVerticalCellItemData +import it.inps.sirio.ui.table.vertical.SirioTableVerticalCellItemType +import it.inps.sirio.ui.tag.TagType + +private const val XSMALL = "Table - xsmall" +private const val SMALL = "Table - small" +private const val MEDIUM = "Table - medium" +private const val LARGE = "Table - large" +private const val VERTICAL = "Table - vertical" +private const val DRAWERBARCOLLAPSED = "Drawer + bottom bar collapsed" +private const val DRAWERBAREXPANDED = "Drawer + bottom bar expanded" +private const val TABLE = "Table" +private const val TABLE1 = "Table 1" +private const val TABLE2 = "Table 2" +private const val TABLE3 = "Table 3" + + +class TableActivity : ComponentActivity() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContent { + SirioTheme { + TableDemoView() + } + } + } +} + +@Composable +private fun TableDemoView() { + Scaffold( + Modifier.fillMaxSize(), + topBar = { + TopAppBar( + title = { Text(text = "Menu spalla") }, + colors = TopAppBarDefaults.topAppBarColors(containerColor = SirioTheme.colors.brand) + ) + } + ) { + val navController = rememberNavController() + NavHost( + navController = navController, + startDestination = "/", + modifier = Modifier.padding(it), + ) { + composable("/") { + TableMenuDemo(navController = navController) + } + composable(XSMALL) { + TableSizeDemo(SirioTableContentSize.EXTRASMALL) + } + composable(SMALL) { + TableSizeDemo(SirioTableContentSize.SMALL) + } + composable(MEDIUM) { + TableSizeDemo(SirioTableContentSize.MEDIUM) + } + composable(LARGE) { + TableSizeDemo(SirioTableContentSize.LARGE) + } + composable(VERTICAL) { + TableVerticalDemo() + } + composable(DRAWERBARCOLLAPSED) { + TableDrawerBarCollapsedDemo() + } + composable(DRAWERBAREXPANDED) { + TableDrawerBarExpandedDemo() + } + composable(TABLE) { + TableSubMenuDemo(navController) + } + composable(TABLE1) { + Table1Demo() + } + composable(TABLE2) { + Table2Demo() + } + composable(TABLE3) { + Table3Demo() + } + } + } +} + +@Composable +private fun TableSizeDemo(size: SirioTableContentSize) { + Column( + modifier = Modifier.background(SirioTheme.colors.table.vertical.background), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.spacedBy(20.dp) + ) { + Spacer(modifier = Modifier.height(20.dp)) + Text(text = MEDIUM) + SirioTable( + title = "Title", + headers = listOf( + SirioTableCellType.Header( + title = "Header", + size = size, + alignment = SirioTableContentAlignment.START, + withCheckBox = true, + ), + SirioTableCellType.Header( + title = "Header", + size = size, + alignment = SirioTableContentAlignment.START, + withCheckBox = true, + ), + ), + rows = listOf( + SirioTableRowData( + cells = listOf( + SirioTableCellType.Text( + text = "Text 0", + size = size + ), + SirioTableCellType.Text( + text = "Text 1", + size = size + ), + ) + ), + SirioTableRowData( + cells = listOf( + SirioTableCellType.Number( + text = "0", + size = size + ), + SirioTableCellType.Number( + text = "1", + size = size + ), + ) + ), + SirioTableRowData( + cells = listOf( + SirioTableCellType.TextOnly( + text = "Text Only 0", + size = size + ), + SirioTableCellType.TextOnly( + text = "Text Only 1", + size = size + ), + ) + ), + SirioTableRowData( + cells = listOf( + SirioTableCellType.Link( + text = "Link 0", + size = size, + onLinkClick = {}, + ), + SirioTableCellType.Link( + text = "Link 1", + size = size, + onLinkClick = {}, + ), + ) + ), + SirioTableRowData( + cells = listOf( + SirioTableCellType.Avatar( + icon = FaIcons.AddressBook, + title = "Avatar 0", + subtitle = "Subtitle", + size = size, + ), + SirioTableCellType.Avatar( + icon = FaIcons.AddressBook, + title = "Avatar 1", + subtitle = "Subtitle", + size = size, + ), + ) + ), + SirioTableRowData( + cells = listOf( + SirioTableCellType.NumberOnly( + text = "0", + size = size + ), + SirioTableCellType.NumberOnly( + text = "1", + size = size + ), + ) + ), + SirioTableRowData( + cells = listOf( + SirioTableCellType.Tag( + text = "Tag 0", + tagType = TagType.GRAY, + size = size + ), + SirioTableCellType.Tag( + text = "Tag 1", + tagType = TagType.GRAY, + size = size + ), + ) + ), + SirioTableRowData( + cells = listOf( + SirioTableCellType.MultiIcons( + size = size, + iconsData = listOf( + SirioTableIconData( + icon = FaIcons.FilePdf, + text = "Stampa", + action = {}, + contentDescription = null, + ), + SirioTableIconData( + icon = FaIcons.Download, + text = "Stampa", + action = {}, + contentDescription = null, + ), + ) + ), + SirioTableCellType.MultiIcons( + size = size, + iconsData = listOf( + SirioTableIconData( + icon = FaIcons.FilePdf, + action = {}, + contentDescription = null, + ), + SirioTableIconData( + icon = FaIcons.Download, + action = {}, + contentDescription = null, + ), + ) + ), + ) + ), + ) + ) + } +} + +@Composable +private fun TableVerticalDemo() { + Column( + modifier = Modifier.background(SirioTheme.colors.table.vertical.background), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.spacedBy(20.dp) + ) { + Spacer(modifier = Modifier.height(20.dp)) + Text(text = VERTICAL) + SirioTableVertical( + cells = listOf( + SirioTableVerticalCellData( + items = listOf( + SirioTableVerticalCellItemData( + title = "Header", + text = "Link", + type = SirioTableVerticalCellItemType.LINK, + ), + SirioTableVerticalCellItemData( + title = "Header", + text = "23/11/2023", + type = SirioTableVerticalCellItemType.NUMBER, + ), + SirioTableVerticalCellItemData( + title = "Header", + text = "00", + type = SirioTableVerticalCellItemType.NUMBER, + ), + SirioTableVerticalCellItemData( + title = "Header", + text = "Lorem ipsum", + type = SirioTableVerticalCellItemType.TEXT, + ), + SirioTableVerticalCellItemData( + title = "Header", + text = "Label tag", + type = SirioTableVerticalCellItemType.TAG, + ) + ), + icons = listOf( + SirioTableIconData( + icon = FaIcons.FilePdf, + action = {}, + contentDescription = null + ), + SirioTableIconData( + icon = FaIcons.Download, + action = {}, + contentDescription = null + ), + SirioTableIconData( + icon = FaIcons.Trash, + action = {}, + contentDescription = null + ), + ), + ), + SirioTableVerticalCellData( + items = listOf( + SirioTableVerticalCellItemData( + title = "Header", + text = "Link", + type = SirioTableVerticalCellItemType.LINK, + ), + SirioTableVerticalCellItemData( + title = "Header", + text = "23/11/2023", + type = SirioTableVerticalCellItemType.NUMBER, + ), + SirioTableVerticalCellItemData( + title = "Header", + text = "00", + type = SirioTableVerticalCellItemType.NUMBER, + ), + SirioTableVerticalCellItemData( + title = "Header", + text = "Lorem ipsum", + type = SirioTableVerticalCellItemType.TEXT, + ), + SirioTableVerticalCellItemData( + title = "Header", + text = "Label tag", + type = SirioTableVerticalCellItemType.TAG, + ) + ), + icons = listOf( + SirioTableIconData( + icon = FaIcons.FilePdf, + action = {}, + contentDescription = null + ), + SirioTableIconData( + icon = FaIcons.Download, + action = {}, + contentDescription = null + ), + SirioTableIconData( + icon = FaIcons.Trash, + action = {}, + contentDescription = null + ), + ), + ) + ) + ) + } +} + +@Composable +private fun TableDrawerBarCollapsedDemo() { + Column( + modifier = Modifier, + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.spacedBy(20.dp) + ) { + Spacer(modifier = Modifier.height(20.dp)) + Text(text = DRAWERBARCOLLAPSED) + SirioTableDrawer( + title = "Titolo", + data = listOf( + SirioTableDrawerItemData( + title = "Titolo", + text = "Sottotitolo", + type = SirioTableDrawerItemType.TEXT, + onClick = {}, + ), + SirioTableDrawerItemData( + title = "Titolo", + text = "00", + type = SirioTableDrawerItemType.NUMBER, + onClick = {}, + ), + SirioTableDrawerItemData( + title = "Titolo", + text = "11/03/2023", + type = SirioTableDrawerItemType.NUMBER, + onClick = {}, + ), + SirioTableDrawerItemData( + title = "Titolo", + text = "Lorem Ipsum dolor sit amet", + type = SirioTableDrawerItemType.LINK, + onClick = {}, + ), + ), + icons = listOf( + SirioTableIconData( + icon = FaIcons.Print, + text = "Stampa", + action = {}, + contentDescription = null + ), + SirioTableIconData( + icon = FaIcons.Trash, + text = "Cancella", + action = {}, + contentDescription = null + ), + SirioTableIconData( + icon = FaIcons.Download, + text = "Scarica", + action = {}, + contentDescription = null + ), + SirioTableIconData( + icon = FaIcons.Times, + text = "Chiudi", + action = { }, + contentDescription = null + ), + ), + onClose = {} + ) + } +} + +@Composable +private fun TableDrawerBarExpandedDemo() { + Column( + modifier = Modifier, + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.spacedBy(20.dp) + ) { + Spacer(modifier = Modifier.height(20.dp)) + Text(text = DRAWERBAREXPANDED) + SirioTableDrawer( + title = "Titolo", + data = listOf( + SirioTableDrawerItemData( + title = "Titolo", + text = "Sottotitolo", + type = SirioTableDrawerItemType.TEXT, + onClick = {}, + ), + SirioTableDrawerItemData( + title = "Titolo", + text = "00", + type = SirioTableDrawerItemType.NUMBER, + onClick = {}, + ), + SirioTableDrawerItemData( + title = "Titolo", + text = "11/03/2023", + type = SirioTableDrawerItemType.NUMBER, + onClick = {}, + ), + SirioTableDrawerItemData( + title = "Titolo", + text = "Lorem Ipsum dolor sit amet", + type = SirioTableDrawerItemType.LINK, + onClick = {}, + ), + ), + icons = listOf( + SirioTableIconData( + icon = FaIcons.Print, + text = "Stampa", + action = {}, + contentDescription = null + ), + SirioTableIconData( + icon = FaIcons.Trash, + text = "Cancella", + action = {}, + contentDescription = null + ), + SirioTableIconData( + icon = FaIcons.Download, + text = "Scarica", + action = {}, + contentDescription = null + ), + ), + onClose = {} + ) + } +} + +@Composable +private fun Table1Demo() { + Column( + modifier = Modifier.background(SirioTheme.colors.table.vertical.background), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.spacedBy(20.dp) + ) { + val size: SirioTableContentSize = SirioTableContentSize.LARGE + Spacer(modifier = Modifier.height(20.dp)) + Text(text = TABLE1) + SirioTable( + title = "Title", + headers = listOf( + SirioTableCellType.Header( + title = "Title 0", + size = size, + alignment = SirioTableContentAlignment.START, + ), + SirioTableCellType.Header( + title = "Title 1", + size = size, + alignment = SirioTableContentAlignment.START, + ), + SirioTableCellType.Header( + title = "Title 2", + size = size, + alignment = SirioTableContentAlignment.START, + ), + ), + rows = listOf( + SirioTableRowData( + cells = listOf( + SirioTableCellType.Text( + text = "Text 0", + size = size + ), + SirioTableCellType.NumberOnly( + text = "0", + size = size + ), + SirioTableCellType.TextOnly( + text = "Text 0", + size = size + ), + ) + ), + SirioTableRowData( + cells = listOf( + SirioTableCellType.Text( + text = "Text 1", + size = size + ), + SirioTableCellType.NumberOnly( + text = "1", + size = size + ), + SirioTableCellType.TextOnly( + text = "Text 1", + size = size + ), + ) + ), + SirioTableRowData( + cells = listOf( + SirioTableCellType.Text( + text = "Text 2", + size = size + ), + SirioTableCellType.NumberOnly( + text = "2", + size = size + ), + SirioTableCellType.TextOnly( + text = "Text 2", + size = size + ), + ) + ), + ) + ) + } +} + +@Composable +private fun Table2Demo() { + Column( + modifier = Modifier.background(SirioTheme.colors.table.vertical.background), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.spacedBy(20.dp) + ) { + val size: SirioTableContentSize = SirioTableContentSize.LARGE + Spacer(modifier = Modifier.height(20.dp)) + Text(text = TABLE2) + SirioTable( + title = "Title", + headers = listOf( + SirioTableCellType.Header( + title = "Title 0", + size = size, + alignment = SirioTableContentAlignment.START, + withCheckBox = true, + ), + SirioTableCellType.Header( + title = "Title 1", + size = size, + alignment = SirioTableContentAlignment.START, + withCheckBox = true, + ), + SirioTableCellType.Header( + title = "Title 2", + size = size, + alignment = SirioTableContentAlignment.START, + withCheckBox = true, + ), + ), + rows = listOf( + SirioTableRowData( + cells = listOf( + SirioTableCellType.Link( + text = "Link 0", + size = size, + onLinkClick = {}, + ), + SirioTableCellType.Avatar( + icon = FaIcons.AddressBook, + title = "Avatar 0", + subtitle = "Subtitle", + size = size, + ), + SirioTableCellType.Tag( + text = "Tag 0", + size = size, + tagType = TagType.GRAY, + ), + ) + ), + SirioTableRowData( + cells = listOf( + SirioTableCellType.Link( + text = "Link 1", + size = size, + onLinkClick = {}, + ), + SirioTableCellType.Avatar( + icon = FaIcons.AddressBook, + title = "Avatar 1", + subtitle = "Subtitle", + size = size, + ), + SirioTableCellType.Tag( + text = "Tag 1", + size = size, + tagType = TagType.GRAY, + ), + ) + ), + SirioTableRowData( + cells = listOf( + SirioTableCellType.Link( + text = "Link 2", + size = size, + onLinkClick = {}, + ), + SirioTableCellType.Avatar( + icon = FaIcons.AddressBook, + title = "Avatar 2", + subtitle = "Subtitle", + size = size, + ), + SirioTableCellType.Tag( + text = "Tag 2", + size = size, + tagType = TagType.GRAY, + ), + ) + ), + ) + ) + } +} + +@Composable +private fun Table3Demo() { + Column( + modifier = Modifier.background(SirioTheme.colors.table.vertical.background), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.spacedBy(20.dp) + ) { + val size: SirioTableContentSize = SirioTableContentSize.LARGE + Spacer(modifier = Modifier.height(20.dp)) + Text(text = TABLE1) + SirioTable( + title = "Title", + headers = listOf( + SirioTableCellType.Header( + title = "Title 0", + size = size, + alignment = SirioTableContentAlignment.START, + ), + SirioTableCellType.Header( + title = "Title 1", + size = size, + alignment = SirioTableContentAlignment.START, + withCheckBox = true, + ), + SirioTableCellType.Header( + title = "Title 2", + size = size, + alignment = SirioTableContentAlignment.START, + ), + ), + rows = listOf( + SirioTableRowData( + cells = listOf( + SirioTableCellType.TextOnly( + text = "Text 0", + size = size + ), + SirioTableCellType.Number( + text = "0", + size = size, + ), + SirioTableCellType.MultiIcons( + size = size, + iconsData = listOf( + SirioTableIconData( + icon = FaIcons.FilePdf, + action = {}, + contentDescription = null + ), + SirioTableIconData( + icon = FaIcons.Download, + action = {}, + contentDescription = null + ) + ) + ), + ) + ), + SirioTableRowData( + cells = listOf( + SirioTableCellType.TextOnly( + text = "Text 1", + size = size + ), + SirioTableCellType.Number( + text = "1", + size = size, + ), + SirioTableCellType.MultiIcons( + size = size, + iconsData = listOf( + SirioTableIconData( + icon = FaIcons.FilePdf, + action = {}, + contentDescription = null + ), + SirioTableIconData( + icon = FaIcons.Download, + action = {}, + contentDescription = null + ) + ) + ), + ) + ), + SirioTableRowData( + cells = listOf( + SirioTableCellType.TextOnly( + text = "Text 2", + size = size + ), + SirioTableCellType.Number( + text = "2", + size = size, + ), + SirioTableCellType.MultiIcons( + size = size, + iconsData = listOf( + SirioTableIconData( + icon = FaIcons.FilePdf, + action = {}, + contentDescription = null + ), + SirioTableIconData( + icon = FaIcons.Download, + action = {}, + contentDescription = null + ) + ) + ), + ) + ), + ) + ) + } +} + +@Composable +fun TableMenuDemo(navController: NavController) { + Box(Modifier.fillMaxSize(), contentAlignment = Alignment.BottomCenter) { + Column( + modifier = Modifier + .align(Alignment.TopCenter) + .verticalScroll(rememberScrollState()), + ) { + DemoMenuItem(XSMALL) { + navController.navigate(XSMALL) + } + HorizontalDivider() + DemoMenuItem(SMALL) { + navController.navigate(SMALL) + } + HorizontalDivider() + DemoMenuItem(MEDIUM) { + navController.navigate(MEDIUM) + } + HorizontalDivider() + DemoMenuItem(LARGE) { + navController.navigate(LARGE) + } + HorizontalDivider() + DemoMenuItem(VERTICAL) { + navController.navigate(VERTICAL) + } + HorizontalDivider() + DemoMenuItem(DRAWERBARCOLLAPSED) { + navController.navigate(DRAWERBARCOLLAPSED) + } + HorizontalDivider() + DemoMenuItem(DRAWERBAREXPANDED) { + navController.navigate(DRAWERBAREXPANDED) + } + HorizontalDivider() + DemoMenuItem(TABLE) { + navController.navigate(TABLE) + } + } + } +} + +@Composable +fun TableSubMenuDemo(navController: NavController) { + Box(Modifier.fillMaxSize(), contentAlignment = Alignment.BottomCenter) { + Column( + modifier = Modifier + .align(Alignment.TopCenter) + .verticalScroll(rememberScrollState()), + ) { + DemoMenuItem(TABLE1) { + navController.navigate(TABLE1) + } + HorizontalDivider() + DemoMenuItem(TABLE2) { + navController.navigate(TABLE2) + } + HorizontalDivider() + DemoMenuItem(TABLE3) { + navController.navigate(TABLE3) + } + } + } +} + +@Preview +@Composable +private fun TableActivityPreview() { + SirioTheme { + TableDemoView() + } +} + +@Preview +@Composable +private fun TableSmallDemoPreview() { + SirioTheme { + TableSizeDemo(SirioTableContentSize.SMALL) + } +} + +@Preview +@Composable +private fun TableMediumDemoPreview() { + SirioTheme { + TableSizeDemo(SirioTableContentSize.MEDIUM) + } +} + +@Preview +@Composable +private fun TableMediumLargePreview() { + SirioTheme { + TableSizeDemo(SirioTableContentSize.LARGE) + } +} + +@Preview +@Composable +private fun TableMediumExtraSmallPreview() { + SirioTheme { + TableSizeDemo(SirioTableContentSize.EXTRASMALL) + } +} + +@Preview +@Composable +private fun TableVerticalDemoPreview() { + SirioTheme { + TableVerticalDemo() + } +} + +@Preview +@Composable +private fun TableDrawerBarCollapsedDemoPreview() { + SirioTheme { + TableDrawerBarCollapsedDemo() + } +} + +@Preview +@Composable +private fun TableDrawerBarExpandedDemoPreview() { + SirioTheme { + TableDrawerBarExpandedDemo() + } +} + +@Preview +@Composable +private fun Table1DemoPreview() { + SirioTheme(darkTheme = true) { + Table1Demo() + } +} + +@Preview +@Composable +private fun Table2DemoPreview() { + SirioTheme(darkTheme = true) { + Table2Demo() + } +} + +@Preview +@Composable +private fun Table3DemoPreview() { + SirioTheme(darkTheme = true) { + Table3Demo() + } +} \ No newline at end of file diff --git a/sample/src/main/java/it/inps/design/titlebar/TitleBarActivity.kt b/sample/src/main/java/it/inps/design/titlebar/TitleBarActivity.kt new file mode 100644 index 0000000..f86db78 --- /dev/null +++ b/sample/src/main/java/it/inps/design/titlebar/TitleBarActivity.kt @@ -0,0 +1,103 @@ +@file:OptIn(ExperimentalMaterial3Api::class) + +package it.inps.design.titlebar + +import android.os.Bundle +import androidx.activity.ComponentActivity +import androidx.activity.compose.setContent +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Text +import androidx.compose.material3.TopAppBar +import androidx.compose.material3.TopAppBarDefaults +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import com.guru.fontawesomecomposelib.FaIcons +import it.inps.sirio.theme.SirioTheme +import it.inps.sirio.ui.titlebar.SirioTitleBar +import it.inps.sirio.ui.titlebar.SirioTitleBarItemData + +class TitleBarActivity : ComponentActivity() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContent { + SirioTheme { + TitleBarDemoView() + } + } + } +} + +@Composable +private fun TitleBarDemoView() { + Scaffold( + Modifier.fillMaxSize(), + topBar = { + TopAppBar( + title = { Text(text = "TitleBar") }, + colors = TopAppBarDefaults.topAppBarColors(containerColor = SirioTheme.colors.brand) + ) + } + ) { + Column( + Modifier + .fillMaxSize() + .padding(it) + .verticalScroll(rememberScrollState()) + ) { + val title = "Titolo" + val items = listOf( + SirioTitleBarItemData( + icon = FaIcons.Filter, + text = "", + contentDescription = null, + action = {}, + ), + SirioTitleBarItemData( + icon = FaIcons.EllipsisH, + text = "", + contentDescription = null, + action = {}, + ) + ) + Text( + text = "Light", + Modifier + .fillMaxWidth() + .padding(16.dp), + fontSize = 20.sp, + textAlign = TextAlign.Center, + ) + SirioTheme(darkTheme = false) { + SirioTitleBar(title = title, items = items) + } + Text( + text = "Dark", + Modifier + .fillMaxWidth() + .padding(16.dp), + fontSize = 20.sp, + textAlign = TextAlign.Center, + ) + SirioTheme(darkTheme = true) { + SirioTitleBar(title = title, items = items) + } + } + } +} + +@Preview +@Composable +private fun TitleBarActivityPreview() { + TitleBarDemoView() +} \ No newline at end of file diff --git a/sample/src/main/java/it/inps/design/toggle/ToggleActivity.kt b/sample/src/main/java/it/inps/design/toggle/ToggleActivity.kt index fc4039f..d071b50 100644 --- a/sample/src/main/java/it/inps/design/toggle/ToggleActivity.kt +++ b/sample/src/main/java/it/inps/design/toggle/ToggleActivity.kt @@ -35,7 +35,7 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.navigation.compose.rememberNavController import it.inps.sirio.theme.SirioTheme -import it.inps.sirio.ui.toggle.Toggle +import it.inps.sirio.ui.toggle.SirioToggle class ToggleActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { @@ -81,17 +81,17 @@ private fun ToggleDemoView() { var isOn4 by remember { mutableStateOf(true) } val label = "Title" Text(text = "Toggle Only False") - Toggle(isOn = isOn1, onToggleChange = { isOn1 = it }) - Toggle(isOn = false, onToggleChange = {}, enabled = false) + SirioToggle(isOn = isOn1, onToggleChange = { isOn1 = it }) + SirioToggle(isOn = false, onToggleChange = {}, enabled = false) Text(text = "Toggle Only True") - Toggle(isOn = isOn2, onToggleChange = { isOn2 = it }) - Toggle(isOn = true, onToggleChange = {}, enabled = false) + SirioToggle(isOn = isOn2, onToggleChange = { isOn2 = it }) + SirioToggle(isOn = true, onToggleChange = {}, enabled = false) Text(text = "Toggle Text False") - Toggle(label = label, isOn = isOn3, onToggleChange = { isOn3 = it }) - Toggle(label = label, isOn = false, onToggleChange = {}, enabled = false) + SirioToggle(label = label, isOn = isOn3, onToggleChange = { isOn3 = it }) + SirioToggle(label = label, isOn = false, onToggleChange = {}, enabled = false) Text(text = "Toggle Text True") - Toggle(label = label, isOn = isOn4, onToggleChange = { isOn4 = it }) - Toggle(label = label, isOn = true, onToggleChange = {}, enabled = false) + SirioToggle(label = label, isOn = isOn4, onToggleChange = { isOn4 = it }) + SirioToggle(label = label, isOn = true, onToggleChange = {}, enabled = false) } } } diff --git a/sample/src/main/java/it/inps/design/ui/DemoActivity.kt b/sample/src/main/java/it/inps/design/ui/DemoActivity.kt deleted file mode 100644 index f413ee8..0000000 --- a/sample/src/main/java/it/inps/design/ui/DemoActivity.kt +++ /dev/null @@ -1,152 +0,0 @@ -// -// DemoActivity.kt -// -// SPDX-FileCopyrightText: 2024 Istituto Nazionale Previdenza Sociale -// -// SPDX-License-Identifier: BSD-3-Clause -// - -package it.inps.design.ui - -import android.content.res.Configuration -import android.os.Bundle -import androidx.activity.ComponentActivity -import androidx.activity.compose.setContent -import androidx.compose.material3.ExperimentalMaterial3Api -import androidx.compose.material3.TopAppBarScrollBehavior -import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.runtime.setValue -import androidx.compose.ui.tooling.preview.Preview -import com.guru.fontawesomecomposelib.FaIcons -import it.inps.sirio.theme.SirioTheme -import it.inps.sirio.ui.appnavigation.AppNavigationItemData -import it.inps.sirio.ui.appnavigation.AppNavigationLongTitle -import it.inps.sirio.ui.appnavigation.AppNavigationSearch -import it.inps.sirio.ui.appnavigation.AppNavigationSelection -import it.inps.sirio.ui.tabbar.TabBarItemData - -class DemoActivity : ComponentActivity() { - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setContent { - SirioTheme { - DemoView() - } - } - } -} - -val HOME_TAB = TabBarItemData(label = "Home", icon = FaIcons.Home, route = "Home") -val NEWS_TAB = TabBarItemData(label = "News", icon = FaIcons.Bell, route = "Notizie", badge = true) -val MAP_TAB = TabBarItemData(label = "Mappa", icon = FaIcons.Globe, route = "Mappa") -val CONTACTS_TAB = TabBarItemData(label = "Contatti", icon = FaIcons.CommentAlt, route = "Contatti") -val SERVICES_TAB = - TabBarItemData(label = "Servizi", icon = FaIcons.GripHorizontal, route = "Servizi") - -enum class TopAppBarDemoType { - SEARCH, - LONG, - SELECTION, - LOGGED_IN -} - -@Composable -private fun DemoView() { -// val decayAnimationSpec = rememberSplineBasedDecay() -// val scrollBehavior = remember(decayAnimationSpec) { -// TopAppBarDefaults.exitUntilCollapsedScrollBehavior(decayAnimationSpec) -// } -// val navController = rememberNavController() -// val title = "Titolo\npagina" -// val listItems = listOf( -// HOME_TAB, -// NEWS_TAB, -// MAP_TAB, -// CONTACTS_TAB, -// SERVICES_TAB -// ) -// -// Scaffold( -// Modifier -// .fillMaxSize() -// .nestedScroll(scrollBehavior.nestedScrollConnection), -// topBar = topBar(title, scrollBehavior), -// bottomBar = { -// TabBar(items = listItems, navController = navController) -// } -// ) { -// DemoNavigationGraph(navController = navController) -// } -} - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -private fun topBar( - title: String, - scrollBehavior: TopAppBarScrollBehavior -): @Composable () -> Unit { - var topBarType by remember { mutableStateOf(TopAppBarDemoType.LONG) } - var text by remember { mutableStateOf("") } - return { - when (topBarType) { - TopAppBarDemoType.SEARCH -> AppNavigationSearch( - title = title, - searchText = text, - placeholderText = "Ricerca", - onSearchTextChanged = { text = it }, - rightFirstItem = AppNavigationItemData( - icon = FaIcons.Square, - action = { topBarType = TopAppBarDemoType.SELECTION }) - ) - TopAppBarDemoType.LONG -> { - AppNavigationLongTitle( - title = title, - leftItem = AppNavigationItemData(icon = FaIcons.Bars, action = {}), - rightFirstItem = AppNavigationItemData( - icon = FaIcons.User, - action = { topBarType = TopAppBarDemoType.LOGGED_IN }), - rightSecondItem = AppNavigationItemData( - icon = FaIcons.Search, - action = { topBarType = TopAppBarDemoType.SEARCH }), - scrollBehavior = scrollBehavior - ) - } - TopAppBarDemoType.LOGGED_IN -> { - AppNavigationLongTitle( - title = title, - leftItem = AppNavigationItemData(icon = FaIcons.Bars, action = {}), - rightFirstItem = AppNavigationItemData( - icon = FaIcons.User, - action = { topBarType = TopAppBarDemoType.LONG }, - username = "MC" - ), - rightSecondItem = AppNavigationItemData( - icon = FaIcons.Search, - action = { topBarType = TopAppBarDemoType.SEARCH }), - scrollBehavior = scrollBehavior - ) - } - TopAppBarDemoType.SELECTION -> AppNavigationSelection( - title = "0 elementi", - leftItem = AppNavigationItemData( - icon = FaIcons.AngleLeft, - action = { topBarType = TopAppBarDemoType.LONG }), - rightFirstItem = AppNavigationItemData(icon = FaIcons.Download, action = {}), - rightSecondItem = AppNavigationItemData(icon = FaIcons.Trash, action = {}), - ) - } - } -} - - -@Preview(showSystemUi = true) -@Preview(showSystemUi = true, uiMode = Configuration.UI_MODE_NIGHT_YES) -@Composable -private fun DemoPreview() { - SirioTheme { - DemoView() - } -} diff --git a/sample/src/main/java/it/inps/design/ui/DemoNavigation.kt b/sample/src/main/java/it/inps/design/ui/DemoNavigation.kt deleted file mode 100644 index f810d00..0000000 --- a/sample/src/main/java/it/inps/design/ui/DemoNavigation.kt +++ /dev/null @@ -1,57 +0,0 @@ -// -// DemoNavigation.kt -// -// SPDX-FileCopyrightText: 2024 Istituto Nazionale Previdenza Sociale -// -// SPDX-License-Identifier: BSD-3-Clause -// - -package it.inps.design.ui - -import androidx.compose.runtime.Composable -import androidx.navigation.NavHostController -import androidx.navigation.compose.NavHost -import androidx.navigation.compose.composable - -@Composable -fun DemoNavigationGraph(navController: NavHostController) { - NavHost(navController, startDestination = HOME_TAB.route) { - composable(HOME_TAB.route) { - HomeScreen() - } - composable(NEWS_TAB.route) { - NewsScreen() - } - composable(MAP_TAB.route) { - MapScreen() - } - composable(CONTACTS_TAB.route) { - ContactsScreen() - } - composable(SERVICES_TAB.route) { - ServicesScreen() - } - } -} - -//const val TABBAR_ROUTE = "tabbar" -// -//fun NavGraphBuilder.tabBarGraph(navController: NavHostController) { -// navigation(route = TABBAR_ROUTE, startDestination = HOME_TAB.route) { -// composable(HOME_TAB.route) { -// HomeScreen() -// } -// composable(NEWS_TAB.route) { -// NewsScreen() -// } -// composable(MAP_TAB.route) { -// MapScreen() -// } -// composable(CONTACTS_TAB.route) { -// ContactsScreen() -// } -// composable(SERVICES_TAB.route) { -// ServicesScreen() -// } -// } -//} \ No newline at end of file diff --git a/sample/src/main/java/it/inps/design/ui/DemoTabs.kt b/sample/src/main/java/it/inps/design/ui/DemoTabs.kt deleted file mode 100644 index fb34804..0000000 --- a/sample/src/main/java/it/inps/design/ui/DemoTabs.kt +++ /dev/null @@ -1,121 +0,0 @@ -// -// DemoTabs.kt -// -// SPDX-FileCopyrightText: 2024 Istituto Nazionale Previdenza Sociale -// -// SPDX-License-Identifier: BSD-3-Clause -// - -package it.inps.design.ui - -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.wrapContentSize -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.res.colorResource -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.unit.sp -import it.inps.design.sample.R - -@Composable -fun HomeScreen() { - Column( - modifier = Modifier - .fillMaxSize() - .background(colorResource(id = R.color.teal_700)) - .wrapContentSize(Alignment.Center) - ) { - Text( - text = "Home Screen", - fontWeight = FontWeight.Bold, - color = Color.White, - modifier = Modifier.align(Alignment.CenterHorizontally), - textAlign = TextAlign.Center, - fontSize = 20.sp - ) - } -} - -@Composable -fun NewsScreen() { - Column( - modifier = Modifier - .fillMaxSize() - .background(colorResource(id = R.color.teal_700)) - .wrapContentSize(Alignment.Center) - ) { - Text( - text = "News Screen", - fontWeight = FontWeight.Bold, - color = Color.White, - modifier = Modifier.align(Alignment.CenterHorizontally), - textAlign = TextAlign.Center, - fontSize = 20.sp - ) - } -} - -@Composable -fun MapScreen() { - Column( - modifier = Modifier - .fillMaxSize() - .background(colorResource(id = R.color.teal_700)) - .wrapContentSize(Alignment.Center) - ) { - Text( - text = "Map Screen", - fontWeight = FontWeight.Bold, - color = Color.White, - modifier = Modifier.align(Alignment.CenterHorizontally), - textAlign = TextAlign.Center, - fontSize = 20.sp - ) - } -} - - -@Composable -fun ContactsScreen() { - Column( - modifier = Modifier - .fillMaxSize() - .background(colorResource(id = R.color.teal_700)) - .wrapContentSize(Alignment.Center) - ) { - Text( - text = "Contacts Screen", - fontWeight = FontWeight.Bold, - color = Color.White, - modifier = Modifier.align(Alignment.CenterHorizontally), - textAlign = TextAlign.Center, - fontSize = 20.sp - ) - } -} - - -@Composable -fun ServicesScreen() { - Column( - modifier = Modifier - .fillMaxSize() - .background(colorResource(id = R.color.teal_700)) - .wrapContentSize(Alignment.Center) - ) { - Text( - text = "Services Screen", - fontWeight = FontWeight.Bold, - color = Color.White, - modifier = Modifier.align(Alignment.CenterHorizontally), - textAlign = TextAlign.Center, - fontSize = 20.sp - ) - } -}