diff --git a/backend/src/baserow/contrib/builder/apps.py b/backend/src/baserow/contrib/builder/apps.py index 8d0c880d2..6699cccb7 100644 --- a/backend/src/baserow/contrib/builder/apps.py +++ b/backend/src/baserow/contrib/builder/apps.py @@ -246,6 +246,7 @@ class BuilderConfig(AppConfig): InputThemeConfigBlockType, LinkThemeConfigBlockType, PageThemeConfigBlockType, + TableThemeConfigBlockType, TypographyThemeConfigBlockType, ) @@ -256,6 +257,7 @@ class BuilderConfig(AppConfig): theme_config_block_registry.register(ImageThemeConfigBlockType()) theme_config_block_registry.register(PageThemeConfigBlockType()) theme_config_block_registry.register(InputThemeConfigBlockType()) + theme_config_block_registry.register(TableThemeConfigBlockType()) from .workflow_actions.registries import builder_workflow_action_type_registry from .workflow_actions.workflow_action_types import ( diff --git a/backend/src/baserow/contrib/builder/elements/element_types.py b/backend/src/baserow/contrib/builder/elements/element_types.py index 7fc52cc4b..ec8e4c0bb 100644 --- a/backend/src/baserow/contrib/builder/elements/element_types.py +++ b/backend/src/baserow/contrib/builder/elements/element_types.py @@ -46,6 +46,9 @@ from baserow.contrib.builder.elements.registries import ( ) from baserow.contrib.builder.pages.handler import PageHandler from baserow.contrib.builder.pages.models import Page +from baserow.contrib.builder.theme.theme_config_block_types import ( + TableThemeConfigBlockType, +) from baserow.contrib.builder.types import ElementDict from baserow.core.formula import resolve_formula from baserow.core.formula.registries import formula_runtime_function_registry @@ -237,8 +240,11 @@ class TableElementType(CollectionElementWithFieldsTypeMixin, ElementType): ), "styles": DynamicConfigBlockSerializer( required=False, - property_name="button", - theme_config_block_type_name=ButtonThemeConfigBlockType.type, + property_name=["button", "table"], + theme_config_block_type_name=[ + ButtonThemeConfigBlockType.type, + TableThemeConfigBlockType.type, + ], serializer_kwargs={"required": False}, ), } diff --git a/backend/src/baserow/contrib/builder/migrations/0032_tablethemeconfigblock.py b/backend/src/baserow/contrib/builder/migrations/0032_tablethemeconfigblock.py new file mode 100644 index 000000000..fb4657b55 --- /dev/null +++ b/backend/src/baserow/contrib/builder/migrations/0032_tablethemeconfigblock.py @@ -0,0 +1,175 @@ +# Generated by Django 4.2.13 on 2024-07-25 15:37 + +import django.db.models.deletion +from django.db import migrations, models + +import baserow.core.fields + + +class Migration(migrations.Migration): + dependencies = [ + ("builder", "0031_remove_buttonelement_alignment_and_more"), + ] + + operations = [ + migrations.CreateModel( + name="TableThemeConfigBlock", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "table_border_color", + models.CharField( + blank=True, + default="#000000FF", + help_text="The color of the table border", + max_length=20, + ), + ), + ( + "table_border_size", + models.SmallIntegerField(default=1, help_text="Table border size"), + ), + ( + "table_border_radius", + models.SmallIntegerField( + default=0, help_text="Table border radius" + ), + ), + ( + "table_header_background_color", + models.CharField( + blank=True, + default="#edededff", + help_text="The background color of the table header cells", + max_length=20, + ), + ), + ( + "table_header_text_color", + models.CharField( + blank=True, + default="#000000ff", + help_text="The text color of the table header cells", + max_length=20, + ), + ), + ( + "table_header_font_size", + models.SmallIntegerField( + default=13, help_text="The font size of the header cells" + ), + ), + ( + "table_header_font_family", + models.CharField( + default="inter", + help_text="The font family of the table header cells", + max_length=250, + ), + ), + ( + "table_header_text_alignment", + models.CharField( + choices=[ + ("left", "Left"), + ("center", "Center"), + ("right", "Right"), + ], + default="left", + max_length=10, + ), + ), + ( + "table_cell_background_color", + models.CharField( + blank=True, + default="transparent", + help_text="The background color of the table cells", + max_length=20, + ), + ), + ( + "table_cell_alternate_background_color", + models.CharField( + blank=True, + default="transparent", + help_text="The alternate background color of the table cells", + max_length=20, + ), + ), + ( + "table_cell_alignment", + models.CharField( + choices=[ + ("left", "Left"), + ("center", "Center"), + ("right", "Right"), + ], + default="left", + max_length=10, + ), + ), + ( + "table_cell_vertical_padding", + models.SmallIntegerField( + default=10, help_text="Table cell vertical padding" + ), + ), + ( + "table_cell_horizontal_padding", + models.SmallIntegerField( + default=20, help_text="Table cell horizontal padding" + ), + ), + ( + "table_vertical_separator_color", + models.CharField( + blank=True, + default="#000000FF", + help_text="The color of the table vertical separator", + max_length=20, + ), + ), + ( + "table_vertical_separator_size", + models.SmallIntegerField( + default=0, help_text="Table vertical separator size" + ), + ), + ( + "table_horizontal_separator_color", + models.CharField( + blank=True, + default="#000000FF", + help_text="The color of the table horizontal separator", + max_length=20, + ), + ), + ( + "table_horizontal_separator_size", + models.SmallIntegerField( + default=1, help_text="Table horizontal separator size" + ), + ), + ( + "builder", + baserow.core.fields.AutoOneToOneField( + on_delete=django.db.models.deletion.CASCADE, + related_name="%(class)s", + to="builder.builder", + ), + ), + ], + options={ + "abstract": False, + }, + ), + ] diff --git a/backend/src/baserow/contrib/builder/theme/models.py b/backend/src/baserow/contrib/builder/theme/models.py index 80161157b..3ba6cf0ea 100644 --- a/backend/src/baserow/contrib/builder/theme/models.py +++ b/backend/src/baserow/contrib/builder/theme/models.py @@ -329,3 +329,98 @@ class InputThemeConfigBlock(ThemeConfigBlock): input_horizontal_padding = models.SmallIntegerField( default=12, help_text="Input horizontal padding" ) + + +class TableThemeConfigBlock(ThemeConfigBlock): + """ + Theme for tables. + """ + + # Table styles + table_border_color = models.CharField( + max_length=20, + default="#000000FF", + blank=True, + help_text="The color of the table border", + ) + table_border_size = models.SmallIntegerField( + default=1, help_text="Table border size" + ) + table_border_radius = models.SmallIntegerField( + default=0, help_text="Table border radius" + ) + + # Header styles + table_header_background_color = models.CharField( + max_length=20, + default="#edededff", + blank=True, + help_text="The background color of the table header cells", + ) + table_header_text_color = models.CharField( + max_length=20, + default="#000000ff", + blank=True, + help_text="The text color of the table header cells", + ) + table_header_font_size = models.SmallIntegerField( + default=13, + help_text="The font size of the header cells", + ) + table_header_font_family = models.CharField( + max_length=250, + default="inter", + help_text="The font family of the table header cells", + ) + table_header_text_alignment = models.CharField( + choices=HorizontalAlignments.choices, + max_length=10, + default=HorizontalAlignments.LEFT, + ) + + # Cell styles + table_cell_background_color = models.CharField( + max_length=20, + default="transparent", + blank=True, + help_text="The background color of the table cells", + ) + + table_cell_alternate_background_color = models.CharField( + max_length=20, + default="transparent", + blank=True, + help_text="The alternate background color of the table cells", + ) + table_cell_alignment = models.CharField( + choices=HorizontalAlignments.choices, + max_length=10, + default=HorizontalAlignments.LEFT, + ) + table_cell_vertical_padding = models.SmallIntegerField( + default=10, help_text="Table cell vertical padding" + ) + table_cell_horizontal_padding = models.SmallIntegerField( + default=20, help_text="Table cell horizontal padding" + ) + + # Separator styles + table_vertical_separator_color = models.CharField( + max_length=20, + default="#000000FF", + blank=True, + help_text="The color of the table vertical separator", + ) + table_vertical_separator_size = models.SmallIntegerField( + default=0, help_text="Table vertical separator size" + ) + + table_horizontal_separator_color = models.CharField( + max_length=20, + default="#000000FF", + blank=True, + help_text="The color of the table horizontal separator", + ) + table_horizontal_separator_size = models.SmallIntegerField( + default=1, help_text="Table horizontal separator size" + ) diff --git a/backend/src/baserow/contrib/builder/theme/theme_config_block_types.py b/backend/src/baserow/contrib/builder/theme/theme_config_block_types.py index ed8b0e886..2056fdf21 100644 --- a/backend/src/baserow/contrib/builder/theme/theme_config_block_types.py +++ b/backend/src/baserow/contrib/builder/theme/theme_config_block_types.py @@ -9,6 +9,7 @@ from .models import ( InputThemeConfigBlock, LinkThemeConfigBlock, PageThemeConfigBlock, + TableThemeConfigBlock, ThemeConfigBlock, TypographyThemeConfigBlock, ) @@ -153,3 +154,8 @@ class PageThemeConfigBlockType(ThemeConfigBlockType): class InputThemeConfigBlockType(ThemeConfigBlockType): type = "input" model_class = InputThemeConfigBlock + + +class TableThemeConfigBlockType(ThemeConfigBlockType): + type = "table" + model_class = TableThemeConfigBlock diff --git a/backend/tests/baserow/contrib/builder/test_builder_application_type.py b/backend/tests/baserow/contrib/builder/test_builder_application_type.py index 8361e27d5..ae5878b30 100644 --- a/backend/tests/baserow/contrib/builder/test_builder_application_type.py +++ b/backend/tests/baserow/contrib/builder/test_builder_application_type.py @@ -572,6 +572,23 @@ def test_builder_application_export(data_fixture): "label_font_family": "inter", "label_font_size": 13, "label_text_color": "#070810FF", + "table_border_color": "#000000FF", + "table_border_radius": 0, + "table_border_size": 1, + "table_cell_alternate_background_color": "transparent", + "table_cell_background_color": "transparent", + "table_cell_horizontal_padding": 20, + "table_cell_alignment": "left", + "table_cell_vertical_padding": 10, + "table_header_background_color": "#edededff", + "table_header_font_family": "inter", + "table_header_font_size": 13, + "table_header_text_alignment": "left", + "table_header_text_color": "#000000ff", + "table_horizontal_separator_color": "#000000FF", + "table_horizontal_separator_size": 1, + "table_vertical_separator_color": "#000000FF", + "table_vertical_separator_size": 0, }, "id": builder.id, "name": builder.name, @@ -969,6 +986,21 @@ def test_builder_application_export(data_fixture): "page_background_color": "#ffffffff", "page_background_file_id": None, "page_background_mode": "tile", + "table_border_size": 1, + "table_cell_alternate_background_color": "transparent", + "table_cell_background_color": "transparent", + "table_cell_horizontal_padding": 20, + "table_cell_alignment": "left", + "table_cell_vertical_padding": 10, + "table_header_background_color": "#edededff", + "table_header_font_family": "inter", + "table_header_font_size": 13, + "table_header_text_alignment": "left", + "table_header_text_color": "#000000ff", + "table_horizontal_separator_color": "#000000FF", + "table_horizontal_separator_size": 0, + "table_vertical_separator_color": "#000000FF", + "table_vertical_separator_size": 1, }, "user_sources": [ { diff --git a/changelog/entries/unreleased/feature/2803_builder_allow_to_style_the_table_element.json b/changelog/entries/unreleased/feature/2803_builder_allow_to_style_the_table_element.json new file mode 100644 index 000000000..23588f112 --- /dev/null +++ b/changelog/entries/unreleased/feature/2803_builder_allow_to_style_the_table_element.json @@ -0,0 +1,7 @@ +{ + "type": "feature", + "message": "[Builder] Allow to style the table element", + "issue_number": 2803, + "bullet_points": [], + "created_at": "2024-07-18" +} \ No newline at end of file diff --git a/web-frontend/modules/builder/components/elements/components/BaserowTable.vue b/web-frontend/modules/builder/components/elements/components/BaserowTable.vue index 217eb0594..2b704713e 100644 --- a/web-frontend/modules/builder/components/elements/components/BaserowTable.vue +++ b/web-frontend/modules/builder/components/elements/components/BaserowTable.vue @@ -30,19 +30,22 @@ :field="field" :row-index="index" > - {{ value }} + {{ row[field.name] }} </slot> </td> </tr> </tbody> </template> <template v-else> - <tbody v-if="rows.length"> - <template v-for="(row, rowIndex) in rows"> + <template v-if="rows.length"> + <tbody + v-for="(row, rowIndex) in rows" + :key="row.__id__" + class="baserow-table__row" + > <tr v-for="(field, fieldIndex) in fields" :key="`${row.__id__}_${field.id}`" - class="baserow-table__row" > <th class="baserow-table__header-cell" @@ -68,8 +71,8 @@ </slot> </td> </tr> - </template> - </tbody> + </tbody> + </template> </template> <tbody v-if="!rows.length"> <tr> diff --git a/web-frontend/modules/builder/components/elements/components/TableElement.vue b/web-frontend/modules/builder/components/elements/components/TableElement.vue index 955cacd0a..d66e9302d 100644 --- a/web-frontend/modules/builder/components/elements/components/TableElement.vue +++ b/web-frontend/modules/builder/components/elements/components/TableElement.vue @@ -4,6 +4,8 @@ :fields="element.fields" :rows="rows" :orientation="orientation" + class="ab-table" + :style="getStyleOverride('table')" > <template #cell-content="{ rowIndex, field, value }"> <component diff --git a/web-frontend/modules/builder/components/elements/components/forms/general/TableElementForm.vue b/web-frontend/modules/builder/components/elements/components/forms/general/TableElementForm.vue index d73e94c72..dca5e2c82 100644 --- a/web-frontend/modules/builder/components/elements/components/forms/general/TableElementForm.vue +++ b/web-frontend/modules/builder/components/elements/components/forms/general/TableElementForm.vue @@ -1,5 +1,11 @@ <template> <form class="table-element-form" @submit.prevent @keydown.enter.prevent> + <CustomStyle + v-model="values.styles" + style-key="table" + :config-block-types="['table']" + :theme="builder.theme" + /> <FormGroup class="margin-bottom-2" small-label diff --git a/web-frontend/modules/builder/components/theme/InputThemeConfigBlock.vue b/web-frontend/modules/builder/components/theme/InputThemeConfigBlock.vue index 5435f201f..bf81f2140 100644 --- a/web-frontend/modules/builder/components/theme/InputThemeConfigBlock.vue +++ b/web-frontend/modules/builder/components/theme/InputThemeConfigBlock.vue @@ -335,44 +335,17 @@ export default { }, }, validations: { - values: { - label_font_size: { - required, - integer, - minValue: minValue(minMax.label_font_size.min), - maxValue: maxValue(minMax.label_font_size.max), - }, - input_font_size: { - required, - integer, - minValue: minValue(minMax.input_font_size.min), - maxValue: maxValue(minMax.input_font_size.max), - }, - input_border_radius: { - required, - integer, - minValue: minValue(minMax.input_border_radius.min), - maxValue: maxValue(minMax.input_border_radius.max), - }, - input_border_size: { - required, - integer, - minValue: minValue(minMax.input_border_size.min), - maxValue: maxValue(minMax.input_border_size.max), - }, - input_horizontal_padding: { - required, - integer, - minValue: minValue(minMax.input_horizontal_padding.min), - maxValue: maxValue(minMax.input_horizontal_padding.max), - }, - input_vertical_padding: { - required, - integer, - minValue: minValue(minMax.input_vertical_padding.min), - maxValue: maxValue(minMax.input_vertical_padding.max), - }, - }, + values: Object.fromEntries( + Object.entries(minMax).map(([key, limits]) => [ + key, + { + required, + integer, + minValue: minValue(limits.min), + maxValue: maxValue(limits.max), + }, + ]) + ), }, } </script> diff --git a/web-frontend/modules/builder/components/theme/TableThemeConfigBlock.vue b/web-frontend/modules/builder/components/theme/TableThemeConfigBlock.vue new file mode 100644 index 000000000..759578fd1 --- /dev/null +++ b/web-frontend/modules/builder/components/theme/TableThemeConfigBlock.vue @@ -0,0 +1,432 @@ +<template> + <div> + <ThemeConfigBlockSection :title="$t('tableThemeConfigBlock.table')"> + <template #default> + <FormGroup + horizontal-narrow + small-label + :label="$t('tableThemeConfigBlock.borderSize')" + :error-message="getError('table_border_size')" + class="margin-bottom-2" + > + <PixelValueSelector v-model="values.table_border_size" /> + <template #after-input> + <ResetButton + v-model="values.table_border_size" + :default-value="theme?.table_border_size" + /> + </template> + </FormGroup> + <FormGroup + horizontal-narrow + small-label + required + :label="$t('tableThemeConfigBlock.borderColor')" + class="margin-bottom-2" + > + <ColorInput + v-model="values.table_border_color" + :color-variables="colorVariables" + :default-value="theme?.table_border_color" + small + /> + <template #after-input> + <ResetButton + v-model="values.table_border_color" + :default-value="theme?.table_border_color" + /> + </template> + </FormGroup> + <FormGroup + horizontal-narrow + small-label + :label="$t('tableThemeConfigBlock.borderRadius')" + :error-message="getError('table_border_radius')" + class="margin-bottom-2" + > + <PixelValueSelector v-model="values.table_border_radius" /> + <template #after-input> + <ResetButton + v-model="values.table_border_radius" + :default-value="theme?.table_border_radius" + /> + </template> + </FormGroup> + </template> + <template #preview> + <BaserowTable :fields="fields" :rows="rows" class="ab-table"> + </BaserowTable> + </template> + </ThemeConfigBlockSection> + + <ThemeConfigBlockSection :title="$t('tableThemeConfigBlock.header')"> + <template #default> + <FormGroup + horizontal-narrow + small-label + :label="$t('tableThemeConfigBlock.backgroundColor')" + class="margin-bottom-2" + > + <ColorInput + v-model="values.table_header_background_color" + :color-variables="colorVariables" + :default-value="theme?.table_header_background_color" + small + /> + <template #after-input> + <ResetButton + v-model="values.table_header_background_color" + :default-value="theme?.table_header_background_color" + /> + </template> + </FormGroup> + <FormGroup + horizontal-narrow + small-label + :label="$t('tableThemeConfigBlock.fontFamily')" + class="margin-bottom-2" + > + <FontFamilySelector v-model="values.table_header_font_family" /> + <template #after-input> + <ResetButton + v-model="values.table_header_font_family" + :default-value="theme?.table_header_font_family" + /> + </template> + </FormGroup> + <FormGroup + horizontal-narrow + small-label + :label="$t('tableThemeConfigBlock.fontSize')" + :error-message="getError('table_header_font_size')" + class="margin-bottom-2" + > + <PixelValueSelector v-model="values.table_header_font_size" /> + <template #after-input> + <ResetButton + v-model="values.table_header_font_size" + :default-value="theme?.table_header_font_size" + /> + </template> + </FormGroup> + <FormGroup + horizontal-narrow + small-label + :label="$t('tableThemeConfigBlock.textColor')" + class="margin-bottom-2" + > + <ColorInput + v-model="values.table_header_text_color" + :color-variables="colorVariables" + :default-value="theme?.table_header_text_color" + small + /> + <template #after-input> + <ResetButton + v-model="values.table_header_text_color" + :default-value="theme?.table_header_text_color" + /> + </template> + </FormGroup> + <FormGroup + horizontal-narrow + small-label + required + :label="$t('tableThemeConfigBlock.alignment')" + class="margin-bottom-2" + > + <HorizontalAlignmentsSelector + v-model="values.table_header_text_alignment" + /> + + <template #after-input> + <ResetButton + v-model="values.table_header_text_alignment" + :default-value="theme?.table_header_text_alignment" + /> + </template> + </FormGroup> + </template> + <template #preview> + <BaserowTable :fields="fields" :rows="rows" class="ab-table"> + </BaserowTable> + </template> + </ThemeConfigBlockSection> + + <ThemeConfigBlockSection :title="$t('tableThemeConfigBlock.cells')"> + <template #default> + <FormGroup + horizontal-narrow + small-label + :label="$t('tableThemeConfigBlock.backgroundColor')" + class="margin-bottom-2" + > + <ColorInput + v-model="values.table_cell_background_color" + :color-variables="colorVariables" + :default-value="theme?.table_cell_background_color" + small + /> + <template #after-input> + <ResetButton + v-model="values.table_cell_background_color" + :default-value="theme?.table_cell_background_color" + /> + </template> + </FormGroup> + <FormGroup + horizontal-narrow + small-label + :label="$t('tableThemeConfigBlock.backgroundAlternateColor')" + class="margin-bottom-2" + > + <ColorInput + v-model="values.table_cell_alternate_background_color" + :color-variables="colorVariables" + :default-value="theme?.table_cell_alternate_background_color" + small + /> + <template #after-input> + <ResetButton + v-model="values.table_cell_alternate_background_color" + :default-value="theme?.table_cell_alternate_background_color" + /> + </template> + </FormGroup> + <FormGroup + horizontal-narrow + small-label + required + :label="$t('tableThemeConfigBlock.alignment')" + class="margin-bottom-2" + > + <HorizontalAlignmentsSelector v-model="values.table_cell_alignment" /> + <template #after-input> + <ResetButton + v-model="values.table_cell_alignment" + :default-value="theme?.table_cell_alignment" + /> + </template> + </FormGroup> + <FormGroup + horizontal-narrow + small-label + :label="$t('tableThemeConfigBlock.padding')" + :error-message="getPaddingError()" + class="margin-bottom-2" + > + <PaddingSelector v-model="padding" /> + <template #after-input> + <ResetButton + v-model="padding" + :default-value=" + theme + ? { + vertical: theme['table_cell_vertical_padding'], + horizontal: theme['table_cell_horizontal_padding'], + } + : undefined + " + /> + </template> + </FormGroup> + </template> + <template #preview> + <BaserowTable :fields="fields" :rows="rows" class="ab-table"> + </BaserowTable> + </template> + </ThemeConfigBlockSection> + <ThemeConfigBlockSection :title="$t('tableThemeConfigBlock.separators')"> + <template #default> + <FormGroup + horizontal-narrow + small-label + :label="$t('tableThemeConfigBlock.horizontalSeparatorColor')" + class="margin-bottom-2" + > + <ColorInput + v-model="values.table_horizontal_separator_color" + :color-variables="colorVariables" + :default-value="theme?.table_horizontal_separator_color" + small + /> + <template #after-input> + <ResetButton + v-model="values.table_horizontal_separator_color" + :default-value="theme?.table_horizontal_separator_color" + /> + </template> + </FormGroup> + <FormGroup + horizontal-narrow + small-label + :label="$t('tableThemeConfigBlock.horizontalSeparatorSize')" + :error-message="getError('table_horizontal_separator_size')" + class="margin-bottom-2" + > + <PixelValueSelector + v-model="values.table_horizontal_separator_size" + /> + <template #after-input> + <ResetButton + v-model="values.table_horizontal_separator_size" + :default-value="theme?.table_horizontal_separator_size" + /> + </template> + </FormGroup> + <FormGroup + horizontal-narrow + small-label + :label="$t('tableThemeConfigBlock.verticalSeparatorColor')" + class="margin-bottom-2" + > + <ColorInput + v-model="values.table_vertical_separator_color" + :color-variables="colorVariables" + :default-value="theme?.table_vertical_separator_color" + small + /> + <template #after-input> + <ResetButton + v-model="values.table_vertical_separator_color" + :default-value="theme?.table_vertical_separator_color" + /> + </template> + </FormGroup> + <FormGroup + horizontal-narrow + small-label + :label="$t('tableThemeConfigBlock.verticalSeparatorSize')" + :error-message="getError('table_vertical_separator_size')" + class="margin-bottom-2" + > + <PixelValueSelector v-model="values.table_vertical_separator_size" /> + <template #after-input> + <ResetButton + v-model="values.table_vertical_separator_size" + :default-value="theme?.table_vertical_separator_size" + /> + </template> + </FormGroup> + </template> + <template #preview> + <BaserowTable :fields="fields" :rows="rows" class="ab-table"> + </BaserowTable> + </template> + </ThemeConfigBlockSection> + </div> +</template> + +<script> +import themeConfigBlock from '@baserow/modules/builder/mixins/themeConfigBlock' +import ThemeConfigBlockSection from '@baserow/modules/builder/components/theme/ThemeConfigBlockSection' +import ResetButton from '@baserow/modules/builder/components/theme/ResetButton' +import HorizontalAlignmentsSelector from '@baserow/modules/builder/components/HorizontalAlignmentsSelector' +import FontFamilySelector from '@baserow/modules/builder/components/FontFamilySelector' +import PixelValueSelector from '@baserow/modules/builder/components/PixelValueSelector' +import PaddingSelector from '@baserow/modules/builder/components/PaddingSelector' +import { required, integer, minValue, maxValue } from 'vuelidate/lib/validators' +import BaserowTable from '@baserow/modules/builder/components/elements/components/BaserowTable' + +const minMax = { + table_border_size: { + min: 0, + max: 30, + }, + table_border_radius: { + min: 0, + max: 100, + }, + table_header_font_size: { + min: 1, + max: 100, + }, + table_cell_vertical_padding: { + min: 0, + max: 100, + }, + table_cell_horizontal_padding: { + min: 0, + max: 100, + }, + table_horizontal_separator_size: { + min: 0, + max: 100, + }, + table_vertical_separator_size: { + min: 0, + max: 100, + }, +} + +export default { + name: 'ButtonThemeConfigBlock', + components: { + ThemeConfigBlockSection, + ResetButton, + BaserowTable, + HorizontalAlignmentsSelector, + FontFamilySelector, + PixelValueSelector, + PaddingSelector, + }, + mixins: [themeConfigBlock], + data() { + return { + values: {}, + fields: [ + { __id__: 1, id: 1, name: 'Header 1' }, + { __id__: 2, id: 2, name: 'Header 2' }, + ], + rows: [ + { 'Header 1': 'Row 1 cell 1', 'Header 2': 'Row 1 cell 2' }, + { 'Header 1': 'Row 2 cell 1', 'Header 2': 'Row 2 cell 2' }, + ], + } + }, + computed: { + padding: { + get() { + return { + vertical: this.values.table_cell_vertical_padding, + horizontal: this.values.table_cell_horizontal_padding, + } + }, + set(newValue) { + this.values.table_cell_vertical_padding = newValue.vertical + this.values.table_cell_horizontal_padding = newValue.horizontal + }, + }, + }, + methods: { + isAllowedKey(key) { + return key.startsWith('table_') + }, + getError(property) { + if (this.$v.values[property].$invalid) { + return this.$t('error.minMaxValueField', minMax[property]) + } + return null + }, + getPaddingError() { + return ( + this.getError('table_cell_vertical_padding') || + this.getError('table_cell_horizontal_padding') + ) + }, + }, + validations: { + values: Object.fromEntries( + Object.entries(minMax).map(([key, limits]) => [ + key, + { + required, + integer, + minValue: minValue(limits.min), + maxValue: maxValue(limits.max), + }, + ]) + ), + }, +} +</script> diff --git a/web-frontend/modules/builder/locales/en.json b/web-frontend/modules/builder/locales/en.json index af78bd2e4..7ce095fa1 100644 --- a/web-frontend/modules/builder/locales/en.json +++ b/web-frontend/modules/builder/locales/en.json @@ -379,7 +379,8 @@ "button": "Button", "link": "Link", "image": "Image", - "input": "Input" + "input": "Input", + "table": "Table" }, "colorThemeConfigBlock": { "primaryColor": "Primary", @@ -395,6 +396,7 @@ "backgroundMode": "Background mode" }, "colorThemeConfigBlockType": { + "transparent": "Transparent", "primary": "Primary", "secondary": "Secondary", "border": "Border", @@ -460,6 +462,27 @@ "imageConstraintContain": "Contain", "imageConstraintContainDisabled": "Unavailable with a max height." }, + "tableThemeConfigBlock": { + "borderColor": "Border color", + "backgroundAlternateColor": "Alternate color", + "backgroundColor": "Background color", + "textColor": "Text color", + "borderSize": "Border size", + "borderRadius": "Border radius", + "padding": "Padding", + "fontFamily": "Font", + "size": "Size", + "fontSize": "Font size", + "table": "Table", + "header": "Header", + "alignment": "Alignment", + "cells": "Cells", + "separators": "Separators", + "verticalSeparatorColor": "Vertical color", + "verticalSeparatorSize": "Vertical size", + "horizontalSeparatorColor": "Horizontal color", + "horizontalSeparatorSize": "Horizontal size" + }, "buttonElementForm": { "valueLabel": "Button text", "valuePlaceholder": "Enter text..." diff --git a/web-frontend/modules/builder/plugin.js b/web-frontend/modules/builder/plugin.js index 193b86415..2f80cde67 100644 --- a/web-frontend/modules/builder/plugin.js +++ b/web-frontend/modules/builder/plugin.js @@ -93,6 +93,7 @@ import { ImageThemeConfigBlockType, PageThemeConfigBlockType, InputThemeConfigBlockType, + TableThemeConfigBlockType, } from '@baserow/modules/builder/themeConfigBlockTypes' import { CreateRowWorkflowActionType, @@ -297,6 +298,10 @@ export default (context) => { 'themeConfigBlock', new InputThemeConfigBlockType(context) ) + app.$registry.register( + 'themeConfigBlock', + new TableThemeConfigBlockType(context) + ) app.$registry.register( 'workflowAction', diff --git a/web-frontend/modules/builder/themeConfigBlockTypes.js b/web-frontend/modules/builder/themeConfigBlockTypes.js index caf0e82c9..50fdfa7fb 100644 --- a/web-frontend/modules/builder/themeConfigBlockTypes.js +++ b/web-frontend/modules/builder/themeConfigBlockTypes.js @@ -6,6 +6,7 @@ import LinkThemeConfigBlock from '@baserow/modules/builder/components/theme/Link import ImageThemeConfigBlock from '@baserow/modules/builder/components/theme/ImageThemeConfigBlock' import PageThemeConfigBlock from '@baserow/modules/builder/components/theme/PageThemeConfigBlock' import InputThemeConfigBlock from '@baserow/modules/builder/components/theme/InputThemeConfigBlock' +import TableThemeConfigBlock from '@baserow/modules/builder/components/theme/TableThemeConfigBlock' import { resolveColor, colorRecommendation, @@ -21,16 +22,52 @@ import get from 'lodash/get' * Helper class to construct easily style objects. */ export class ThemeStyle { - constructor() { + constructor({ colorVariables = {}, $registry }) { this.style = {} + this.colorVariables = colorVariables + this.$registry = $registry } addIfExists(theme, propName, styleName, transform = (v) => v) { + if (!styleName) { + styleName = `--${propName.replace(/_/g, '-')}` + } if (Object.prototype.hasOwnProperty.call(theme, propName)) { this.style[styleName] = transform(theme[propName]) } } + addColorIfExists(theme, propName, styleName) { + return this.addIfExists(theme, propName, styleName, (v) => + resolveColor(v, this.colorVariables) + ) + } + + addColorRecommendationIfExists(theme, propName, styleName) { + return this.addIfExists( + theme, + propName, + styleName, + (v) => (v) => colorRecommendation(resolveColor(v, this.colorVariables)) + ) + } + + addFontFamilyIfExists(theme, propName, styleName) { + return this.addIfExists(theme, propName, styleName, (v) => { + const fontFamilyType = this.$registry.get('fontFamily', v) + return `"${fontFamilyType.name}","${fontFamilyType.safeFont}"` + }) + } + + addPixelValueIfExists(theme, propName, styleName) { + return this.addIfExists( + theme, + propName, + styleName, + (v) => `${Math.min(100, v)}px` + ) + } + toObject() { return this.style } @@ -124,7 +161,10 @@ export class ColorThemeConfigBlockType extends ThemeConfigBlockType { } getCSS(theme, colorVariables, baseTheme = null) { - const style = new ThemeStyle() + const style = new ThemeStyle({ + colorVariables, + $registry: this.app.$registry, + }) style.addIfExists(theme, 'primary_color', '--main-primary-color', (v) => resolveColor(v, colorVariables) ) @@ -155,6 +195,11 @@ export class ColorThemeConfigBlockType extends ThemeConfigBlockType { getColorVariables(theme) { const { i18n } = this.app return [ + { + name: i18n.t('colorThemeConfigBlockType.transparent'), + value: 'transparent', + color: '#00000000', + }, { name: i18n.t('colorThemeConfigBlockType.primary'), value: 'primary', @@ -207,15 +252,17 @@ export class TypographyThemeConfigBlockType extends ThemeConfigBlockType { } getCSS(theme, colorVariables, baseTheme = null) { - const style = new ThemeStyle() + const style = new ThemeStyle({ + colorVariables, + $registry: this.app.$registry, + }) Array.from([1, 2, 3, 4, 5, 6]).forEach((level) => { - style.addIfExists( + style.addPixelValueIfExists( theme, `heading_${level}_font_size`, - `--heading-h${level}-font-size`, - (v) => `${Math.min(100, v)}px` + `--heading-h${level}-font-size` ) - style.addIfExists( + style.addColorIfExists( theme, `heading_${level}_text_color`, `--heading-h${level}-color`, @@ -224,38 +271,18 @@ export class TypographyThemeConfigBlockType extends ThemeConfigBlockType { style.addIfExists( theme, `heading_${level}_text_alignment`, - `--heading-h${level}-text-alignment`, - (v) => v + `--heading-h${level}-text-alignment` ) - style.addIfExists( + style.addFontFamilyIfExists( theme, `heading_${level}_font_family`, - `--heading-h${level}-font-family`, - (v) => { - const fontFamilyType = this.app.$registry.get('fontFamily', v) - return `"${fontFamilyType.name}","${fontFamilyType.safeFont}"` - } + `--heading-h${level}-font-family` ) }) - style.addIfExists( - theme, - `body_font_size`, - `--body-font-size`, - (v) => `${Math.min(100, v)}px` - ) - style.addIfExists(theme, `body_text_color`, `--body-text-color`, (v) => - resolveColor(v, colorVariables) - ) - style.addIfExists( - theme, - `body_text_alignment`, - `--body-text-alignment`, - (v) => v - ) - style.addIfExists(theme, `body_font_family`, `--body-font-family`, (v) => { - const fontFamilyType = this.app.$registry.get('fontFamily', v) - return `"${fontFamilyType.name}","${fontFamilyType.safeFont}"` - }) + style.addPixelValueIfExists(theme, `body_font_size`) + style.addColorIfExists(theme, `body_text_color`) + style.addIfExists(theme, `body_text_alignment`) + style.addFontFamilyIfExists(theme, `body_font_family`) return style.toObject() } @@ -278,53 +305,24 @@ export class ButtonThemeConfigBlockType extends ThemeConfigBlockType { } getCSS(theme, colorVariables, baseTheme = null) { - const style = new ThemeStyle() - style.addIfExists( - theme, - 'button_background_color', - '--button-background-color', - (v) => resolveColor(v, colorVariables) - ) - style.addIfExists( - theme, - 'button_hover_background_color', - '--button-hover-background-color', - (v) => resolveColor(v, colorVariables) - ) - style.addIfExists(theme, 'button_text_color', '--button-text-color', (v) => - resolveColor(v, colorVariables) - ) - style.addIfExists( - theme, - 'button_hover_text_color', - '--button-hover-text-color', - (v) => resolveColor(v, colorVariables) - ) - style.addIfExists( - theme, - 'button_border_color', - '--button-border-color', - (v) => resolveColor(v, colorVariables) - ) - style.addIfExists( - theme, - 'button_hover_border_color', - '--button-hover-border-color', - (v) => resolveColor(v, colorVariables) - ) - style.addIfExists(theme, 'button_width', '--button-width', (v) => + const style = new ThemeStyle({ + colorVariables, + $registry: this.app.$registry, + }) + style.addColorIfExists(theme, 'button_background_color') + style.addColorIfExists(theme, 'button_hover_background_color') + style.addColorIfExists(theme, 'button_text_color') + style.addColorIfExists(theme, 'button_hover_text_color') + style.addColorIfExists(theme, 'button_border_color') + style.addColorIfExists(theme, 'button_hover_border_color') + style.addIfExists(theme, 'button_width', null, (v) => v === WIDTHS_NEW.FULL ? '100%' : 'auto' ) - style.addIfExists( - theme, - 'button_text_alignment', - '--button-text-alignment', - (v) => v - ) + style.addIfExists(theme, 'button_text_alignment') style.addIfExists( theme, 'button_alignment', - '--button-alignment', + null, (v) => ({ [HORIZONTAL_ALIGNMENTS.LEFT]: 'flex-start', @@ -332,51 +330,12 @@ export class ButtonThemeConfigBlockType extends ThemeConfigBlockType { [HORIZONTAL_ALIGNMENTS.RIGHT]: 'flex-end', }[v]) ) - style.addIfExists( - theme, - 'button_font_alignment', - '--button-text-alignment', - (v) => v - ) - style.addIfExists( - theme, - `button_font_family`, - `--button-font-family`, - (v) => { - const fontFamilyType = this.app.$registry.get('fontFamily', v) - return `"${fontFamilyType.name}","${fontFamilyType.safeFont}"` - } - ) - style.addIfExists( - theme, - `button_font_size`, - `--button-font-size`, - (v) => `${Math.min(100, v)}px` - ) - style.addIfExists( - theme, - `button_border_radius`, - `--button-border-radius`, - (v) => `${v}px` - ) - style.addIfExists( - theme, - `button_border_size`, - `--button-border-size`, - (v) => `${v}px` - ) - style.addIfExists( - theme, - `button_horizontal_padding`, - `--button-horizontal-padding`, - (v) => `${v}px` - ) - style.addIfExists( - theme, - `button_vertical_padding`, - `--button-vertical-padding`, - (v) => `${v}px` - ) + style.addFontFamilyIfExists(theme, `button_font_family`) + style.addPixelValueIfExists(theme, `button_font_size`) + style.addPixelValueIfExists(theme, `button_border_radius`) + style.addPixelValueIfExists(theme, `button_border_size`) + style.addPixelValueIfExists(theme, `button_horizontal_padding`) + style.addPixelValueIfExists(theme, `button_vertical_padding`) return style.toObject() } @@ -399,16 +358,12 @@ export class LinkThemeConfigBlockType extends ThemeConfigBlockType { } getCSS(theme, colorVariables, baseTheme = null) { - const style = new ThemeStyle() - style.addIfExists(theme, 'link_text_color', '--link-text-color', (v) => - resolveColor(v, colorVariables) - ) - style.addIfExists( - theme, - 'link_hover_text_color', - '--link-hover-text-color', - (v) => resolveColor(v, colorVariables) - ) + const style = new ThemeStyle({ + colorVariables, + $registry: this.app.$registry, + }) + style.addColorIfExists(theme, 'link_text_color') + style.addColorIfExists(theme, 'link_hover_text_color') style.addIfExists( theme, 'link_text_alignment', @@ -446,7 +401,10 @@ export class ImageThemeConfigBlockType extends ThemeConfigBlockType { } getCSS(theme, colorVariables, baseTheme = null) { - const style = new ThemeStyle() + const style = new ThemeStyle({ + colorVariables, + $registry: this.app.$registry, + }) style.addIfExists( theme, 'image_alignment', @@ -532,13 +490,11 @@ export class PageThemeConfigBlockType extends ThemeConfigBlockType { } getCSS(theme, colorVariables, baseTheme = null) { - const style = new ThemeStyle() - style.addIfExists( - theme, - 'page_background_color', - '--page-background-color', - (v) => resolveColor(v, colorVariables) - ) + const style = new ThemeStyle({ + colorVariables, + $registry: this.app.$registry, + }) + style.addColorIfExists(theme, 'page_background_color') style.addIfExists( theme, 'page_background_file', @@ -579,98 +535,40 @@ export class InputThemeConfigBlockType extends ThemeConfigBlockType { } getCSS(theme, colorVariables, baseTheme = null) { - const style = new ThemeStyle() - style.addIfExists(theme, 'label_text_color', '--label-text-color', (v) => - resolveColor(v, colorVariables) - ) - style.addIfExists( - theme, - `label_font_family`, - `--label-font-family`, - (v) => { - const fontFamilyType = this.app.$registry.get('fontFamily', v) - return `"${fontFamilyType.name}","${fontFamilyType.safeFont}"` - } - ) - style.addIfExists( - theme, - `label_font_size`, - `--label-font-size`, - (v) => `${Math.min(100, v)}px` - ) + const style = new ThemeStyle({ + colorVariables, + $registry: this.app.$registry, + }) - style.addIfExists(theme, 'input_text_color', '--input-text-color', (v) => - resolveColor(v, colorVariables) - ) + style.addColorIfExists(theme, 'label_text_color') + style.addFontFamilyIfExists(theme, `label_font_family`) + style.addPixelValueIfExists(theme, `label_font_size`) + + style.addColorIfExists(theme, 'input_text_color') style.addIfExists( theme, 'input_text_color', '--input-text-color-complement', (v) => colorRecommendation(resolveColor(v, colorVariables)) ) - style.addIfExists( - theme, - `input_font_family`, - `--input-font-family`, - (v) => { - const fontFamilyType = this.app.$registry.get('fontFamily', v) - return `"${fontFamilyType.name}","${fontFamilyType.safeFont}"` - } - ) - style.addIfExists( - theme, - `input_font_size`, - `--input-font-size`, - (v) => `${Math.min(100, v)}px` - ) - style.addIfExists( + style.addFontFamilyIfExists(theme, `input_font_family`) + style.addPixelValueIfExists(theme, `input_font_size`) + style.addColorIfExists(theme, 'input_background_color') + style.addColorRecommendationIfExists( theme, 'input_background_color', - '--input-background-color', - (v) => resolveColor(v, colorVariables) + '--input-background-color-complement' ) - style.addIfExists( - theme, - 'input_background_color', - '--input-background-color-complement', - (v) => colorRecommendation(resolveColor(v, colorVariables)) - ) - style.addIfExists( + style.addColorIfExists(theme, 'input_border_color') + style.addColorRecommendationIfExists( theme, 'input_border_color', - '--input-border-color', - (v) => resolveColor(v, colorVariables) - ) - style.addIfExists( - theme, - 'input_border_color', - '--input-border-color-complement', - (v) => colorRecommendation(resolveColor(v, colorVariables)) - ) - style.addIfExists( - theme, - `input_border_radius`, - `--input-border-radius`, - (v) => `${v}px` - ) - style.addIfExists( - theme, - `input_border_size`, - `--input-border-size`, - (v) => `${v}px` - ) - style.addIfExists( - theme, - `input_horizontal_padding`, - `--input-horizontal-padding`, - (v) => `${v}px` - ) - style.addIfExists( - theme, - `input_vertical_padding`, - `--input-vertical-padding`, - (v) => `${v}px` + '--input-border-color-complement' ) + style.addPixelValueIfExists(theme, `input_border_radius`) + style.addPixelValueIfExists(theme, `input_border_size`) + style.addPixelValueIfExists(theme, `input_horizontal_padding`) + style.addPixelValueIfExists(theme, `input_vertical_padding`) return style.toObject() } @@ -682,3 +580,53 @@ export class InputThemeConfigBlockType extends ThemeConfigBlockType { return 55 } } + +export class TableThemeConfigBlockType extends ThemeConfigBlockType { + static getType() { + return 'table' + } + + get label() { + return this.app.i18n.t('themeConfigBlockType.table') + } + + getCSS(theme, colorVariables, baseTheme = null) { + const style = new ThemeStyle({ + colorVariables, + $registry: this.app.$registry, + }) + style.addColorIfExists(theme, 'table_border_color') + style.addPixelValueIfExists(theme, `table_border_size`) + style.addPixelValueIfExists(theme, `table_border_radius`) + + style.addColorIfExists(theme, 'table_header_background_color') + style.addColorIfExists(theme, 'table_header_text_color') + style.addPixelValueIfExists(theme, `table_header_font_size`) + style.addFontFamilyIfExists(theme, `table_header_font_family`) + style.addIfExists(theme, `table_header_text_alignment`) + + style.addColorIfExists(theme, 'table_cell_background_color') + style.addColorIfExists(theme, 'table_cell_alternate_background_color') + style.addColorIfExists(theme, 'table_cell_text_color') + style.addFontFamilyIfExists(theme, `table_cell_font_family`) + style.addPixelValueIfExists(theme, `table_cell_font_size`) + style.addIfExists(theme, `table_cell_alignment`) + style.addPixelValueIfExists(theme, `table_cell_vertical_padding`) + style.addPixelValueIfExists(theme, `table_cell_horizontal_padding`) + + style.addColorIfExists(theme, 'table_vertical_separator_color') + style.addPixelValueIfExists(theme, `table_vertical_separator_size`) + style.addColorIfExists(theme, 'table_horizontal_separator_color') + style.addPixelValueIfExists(theme, `table_horizontal_separator_size`) + + return style.toObject() + } + + get component() { + return TableThemeConfigBlock + } + + getOrder() { + return 65 + } +} diff --git a/web-frontend/modules/core/assets/scss/components/builder/elements/ab_components/ab_table.scss b/web-frontend/modules/core/assets/scss/components/builder/elements/ab_components/ab_table.scss new file mode 100644 index 000000000..f275b42b8 --- /dev/null +++ b/web-frontend/modules/core/assets/scss/components/builder/elements/ab_components/ab_table.scss @@ -0,0 +1,81 @@ +.ab-table { + border: var(--table-border-size, 1px) solid var(--table-border-color, $black); + text-align: var(--table-cell-alignment, left); + font-size: var(--body-font-size, 13px); + border-radius: var(--table-border-radius, 0); + background-color: var(--table-cell-background-color, $palette-neutral-200); + + .baserow-table__header-cell, + .baserow-table__cell { + padding: var(--table-cell-vertical-padding, 10px) + var(--table-cell-horizontal-padding, 20px); + } + + .baserow-table__cell { + font-size: var(--body-font-size, 13px); + color: var(--body-text-color, $color-neutral-900); + font-family: var(--body-font-family, Inter); + text-align: var(--table-cell-alignment, left); + } + + .baserow-table__header-cell { + font-weight: 600; + background-color: var( + --table-header-background-color, + $palette-neutral-200 + ); + font-size: var(--table-header-font-size, 13px); + color: var(--table-header-text-color, $color-neutral-900); + font-family: var(--table-header-font-family, Inter); + text-align: var(--table-header-text-alignment, left); + } + + & .baserow-table__row:not(:last-child) .baserow-table__separator { + border-bottom: var(--table-horizontal-separator-size, 1px) solid + var(--table-horizontal-separator-color, $black); + } + + .baserow-table--vertical { + .baserow-table__header-cell { + border-right: var(--table-vertical-separator-size, 1px) solid + var(--table-vertical-separator-color, $black); + } + + tbody.baserow-table__row:nth-child(even) { + background-color: var( + --table-cell-alternate-background-color, + transparent + ); + } + } + + .baserow-table--horizontal { + .baserow-table__header-cell, + .baserow-table__cell { + border-bottom: var(--table-horizontal-separator-size, 1px) solid + var(--table-horizontal-separator-color, $black); + border-right: var(--table-vertical-separator-size, 1px) solid + var(--table-vertical-separator-color, $black); + } + + .baserow-table__row { + .baserow-table__cell:last-child, + .baserow-table__header-cell:last-child { + border-right: none; + } + } + + .baserow-table__row:last-child { + .baserow-table__cell { + border-bottom: none; + } + } + + tbody .baserow-table__row:nth-child(even) { + background-color: var( + --table-cell-alternate-background-color, + transparent + ); + } + } +} diff --git a/web-frontend/modules/core/assets/scss/components/builder/elements/ab_components/all.scss b/web-frontend/modules/core/assets/scss/components/builder/elements/ab_components/all.scss index 078f8c064..0bfbe73e2 100644 --- a/web-frontend/modules/core/assets/scss/components/builder/elements/ab_components/all.scss +++ b/web-frontend/modules/core/assets/scss/components/builder/elements/ab_components/all.scss @@ -10,3 +10,4 @@ @import 'ab_tag'; @import 'ab_radio'; @import 'ab_image'; +@import 'ab_table'; diff --git a/web-frontend/modules/core/assets/scss/components/builder/elements/baserow_table.scss b/web-frontend/modules/core/assets/scss/components/builder/elements/baserow_table.scss index 5a8afb9a5..09fe7de04 100644 --- a/web-frontend/modules/core/assets/scss/components/builder/elements/baserow_table.scss +++ b/web-frontend/modules/core/assets/scss/components/builder/elements/baserow_table.scss @@ -4,41 +4,6 @@ .baserow-table { width: 100%; - border: 1px solid $black; border-spacing: 0; text-align: left; - font-size: 12px; -} - -.baserow-table__header-cell, -.baserow-table__cell { - padding: 12px 20px 10px; -} - -.baserow-table__header-cell { - font-weight: 600; - background-color: $palette-neutral-200; -} - -.baserow-table__separator { - .baserow-table__row:not(:last-child) & { - border-bottom: 1px solid $black; - } -} - -.baserow-table--horizontal { - .baserow-table__header-cell, - .baserow-table__cell { - border-bottom: 1px solid $black; - } - - .baserow-table__row:last-child .baserow-table__cell { - border-bottom: none; - } -} - -.baserow-table--vertical { - .baserow-table__header-cell { - border-right: 1px solid $black; - } } diff --git a/web-frontend/modules/core/components/ColorInputGroup.vue b/web-frontend/modules/core/components/ColorInputGroup.vue deleted file mode 100644 index b5d1e92f5..000000000 --- a/web-frontend/modules/core/components/ColorInputGroup.vue +++ /dev/null @@ -1,62 +0,0 @@ -<template> - <FormGroup v-if="!labelAfter" small-label required :label="label"> - <ColorInput - :value="value" - :color-variables="colorVariables" - @input="$emit('input', $event)" - /> - <template #after-input> - <slot name="after-input"></slot> - </template> - </FormGroup> - <div v-else class="control"> - <div class="control__elements"> - <div class="color-input-group--label-after"> - <ColorInput - :value="value" - :color-variables="colorVariables" - :horizontal="horizontal" - @input="$emit('input', $event)" - /> - <div class="color-input-group__label-after"> - {{ label }} - </div> - </div> - </div> - </div> -</template> - -<script> -import ColorInput from '@baserow/modules/core/components/ColorInput' - -export default { - name: 'ColorInputGroup', - components: { ColorInput }, - props: { - value: { - type: String, - required: false, - default: 'primary', - }, - label: { - type: String, - required: true, - }, - labelAfter: { - type: Boolean, - required: false, - default: false, - }, - colorVariables: { - type: Array, - required: false, - default: () => [], - }, - horizontal: { - type: Boolean, - required: false, - default: false, - }, - }, -} -</script> diff --git a/web-frontend/modules/core/components/ColorPickerContext.vue b/web-frontend/modules/core/components/ColorPickerContext.vue index e99d8ebcc..f4bb22076 100644 --- a/web-frontend/modules/core/components/ColorPickerContext.vue +++ b/web-frontend/modules/core/components/ColorPickerContext.vue @@ -164,6 +164,13 @@ export default { }, methods: { setColorFromPicker(value) { + if (this.selectedVariable) { + // If we come from a variable before we reset the alpha channel to 1 otherwise + // You could think something doesn't work. + const rgba = convertHexToRgb(value) + rgba.a = 1 + value = convertRgbToHex(rgba) + } this.colorUpdated(value) this.$emit( 'input', diff --git a/web-frontend/modules/core/plugins/global.js b/web-frontend/modules/core/plugins/global.js index 2ef38e3d4..5b432d6ed 100644 --- a/web-frontend/modules/core/plugins/global.js +++ b/web-frontend/modules/core/plugins/global.js @@ -57,7 +57,6 @@ import Expandable from '@baserow/modules/core/components/Expandable.vue' import RadioButton from '@baserow/modules/core/components/RadioButton' import Thumbnail from '@baserow/modules/core/components/Thumbnail' import ColorInput from '@baserow/modules/core/components/ColorInput' -import ColorInputGroup from '@baserow/modules/core/components/ColorInputGroup' import SelectSearch from '@baserow/modules/core/components/SelectSearch' function setupVue(Vue) { @@ -101,7 +100,6 @@ function setupVue(Vue) { Vue.component('FormGroup', FormGroup) Vue.component('FormRow', FormRow) Vue.component('ColorInput', ColorInput) - Vue.component('ColorInputGroup', ColorInputGroup) Vue.component('ImageInput', ImageInput) Vue.component('SelectSearch', SelectSearch) Vue.component('Logo', Logo)