From 2ad17ab8a129ed8fc165621e39c49adbe2f270d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Osorio?= <5873627+sirgalleto@users.noreply.github.com> Date: Fri, 29 Sep 2023 13:52:48 -0600 Subject: [PATCH 1/2] Revert "Revert "[IndexFilters] Add Edit Columns optional button" (#10759)" This reverts commit 4f5fbe113ebc29f8c6d28c97c63c5ae3962108b8. --- .changeset/strange-bananas-obey.md | 11 + polaris-react/locales/cs.json | 7 +- polaris-react/locales/da.json | 5 +- polaris-react/locales/de.json | 5 +- polaris-react/locales/en.json | 5 +- polaris-react/locales/es.json | 5 +- polaris-react/locales/fi.json | 7 +- polaris-react/locales/fr.json | 5 +- polaris-react/locales/it.json | 5 +- polaris-react/locales/ja.json | 5 +- polaris-react/locales/ko.json | 5 +- polaris-react/locales/nb.json | 5 +- polaris-react/locales/nl.json | 5 +- polaris-react/locales/pl.json | 5 +- polaris-react/locales/pt-BR.json | 5 +- polaris-react/locales/pt-PT.json | 5 +- polaris-react/locales/sv.json | 5 +- polaris-react/locales/th.json | 5 +- polaris-react/locales/tr.json | 5 +- polaris-react/locales/vi.json | 5 +- polaris-react/locales/zh-CN.json | 5 +- polaris-react/locales/zh-TW.json | 7 +- .../IndexFilters/IndexFilters.stories.tsx | 5 + .../components/IndexFilters/IndexFilters.tsx | 38 +- .../EditColumnsButton/EditColumnsButton.tsx | 46 ++ .../components/EditColumnsButton/index.ts | 1 + .../IndexFilters/components/index.ts | 1 + .../IndexFilters/tests/IndexFilters.test.tsx | 111 ++++- .../src/components/Tabs/Tabs.stories.tsx | 7 +- .../components/Tabs/components/Tab/Tab.tsx | 5 - .../Tabs/components/Tab/tests/Tab.test.tsx | 17 - polaris-react/src/components/Tabs/types.ts | 7 +- .../content/components/tables/index-table.md | 5 +- .../index-filters-with-edit-colums-button.tsx | 400 ++++++++++++++++++ 34 files changed, 696 insertions(+), 69 deletions(-) create mode 100644 .changeset/strange-bananas-obey.md create mode 100644 polaris-react/src/components/IndexFilters/components/EditColumnsButton/EditColumnsButton.tsx create mode 100644 polaris-react/src/components/IndexFilters/components/EditColumnsButton/index.ts create mode 100644 polaris.shopify.com/pages/examples/index-filters-with-edit-colums-button.tsx diff --git a/.changeset/strange-bananas-obey.md b/.changeset/strange-bananas-obey.md new file mode 100644 index 00000000000..3735026db35 --- /dev/null +++ b/.changeset/strange-bananas-obey.md @@ -0,0 +1,11 @@ +--- +'@shopify/polaris': minor +--- + +Added support for an `EditColumns` button rendered in the `IndexFilters` deprecating the `Tabs`'s `edit-columns` action. + +- `IndexFilters` + - Added support for rendering an Edit Columns button using the `showEditColumnsButton` flag. + - Added the edition `mode` to the `onEditStart(mode)` callback. +- `Tabs` + - Removed the `edit-columns` action type. diff --git a/polaris-react/locales/cs.json b/polaris-react/locales/cs.json index fbe80e16b66..9c5da0e0c77 100644 --- a/polaris-react/locales/cs.json +++ b/polaris-react/locales/cs.json @@ -214,7 +214,6 @@ "rename": "Přejmenovat zobrazení", "duplicate": "Duplikování zobrazení", "edit": "Upravit zobrazení", - "editColumns": "Upravit sloupce", "delete": "Odstranit zobrazení", "copy": "{name} – kopie", "deleteModal": { @@ -391,7 +390,11 @@ "cancel": "Zrušit" } }, - "searchFilterTooltipWithShortcut": "Hledejte a filtrujte (F)" + "searchFilterTooltipWithShortcut": "Hledejte a filtrujte (F)", + "EditColumnsButton": { + "tooltip": "Upravit sloupce", + "accessibilityLabel": "Přizpůsobit pořadí a viditelnost sloupců tabulky" + } }, "ActionList": { "SearchField": { diff --git a/polaris-react/locales/da.json b/polaris-react/locales/da.json index 4f3d39fdfcd..017e6fa3c57 100644 --- a/polaris-react/locales/da.json +++ b/polaris-react/locales/da.json @@ -214,7 +214,6 @@ "rename": "Omdøb visning", "duplicate": "Dupliker visning", "edit": "Rediger visning", - "editColumns": "Rediger kolonner", "delete": "Slet visning", "copy": "Kopi af {name}", "deleteModal": { @@ -389,6 +388,10 @@ "save": "Gem", "cancel": "Annuller" } + }, + "EditColumnsButton": { + "tooltip": "Rediger kolonner", + "accessibilityLabel": "Tilpas rækkefølgen og synligheden af tabelkolonner" } }, "ActionList": { diff --git a/polaris-react/locales/de.json b/polaris-react/locales/de.json index 1066bf858ac..cbd575ea79e 100644 --- a/polaris-react/locales/de.json +++ b/polaris-react/locales/de.json @@ -214,7 +214,6 @@ "rename": "Ansicht umbenennen", "duplicate": "Ansicht duplizieren", "edit": "Ansicht bearbeiten", - "editColumns": "Spalten bearbeiten", "delete": "Ansicht löschen", "copy": "Kopie von {name}", "deleteModal": { @@ -389,6 +388,10 @@ "save": "Speichern", "cancel": "Abbrechen" } + }, + "EditColumnsButton": { + "tooltip": "Spalten bearbeiten", + "accessibilityLabel": "Reihenfolge und Sichtbarkeit der Tabellenspalten anpassen" } }, "ActionList": { diff --git a/polaris-react/locales/en.json b/polaris-react/locales/en.json index 133a633151c..05b6fc13eae 100644 --- a/polaris-react/locales/en.json +++ b/polaris-react/locales/en.json @@ -192,6 +192,10 @@ "za": "Z-A" } }, + "EditColumnsButton": { + "tooltip": "Edit columns", + "accessibilityLabel": "Customize table column order and visibility" + }, "UpdateButtons": { "cancel": "Cancel", "update": "Update", @@ -291,7 +295,6 @@ "rename": "Rename view", "duplicate": "Duplicate view", "edit": "Edit view", - "editColumns": "Edit columns", "delete": "Delete view", "copy": "Copy of {name}", "deleteModal": { diff --git a/polaris-react/locales/es.json b/polaris-react/locales/es.json index f2294fa6368..9a5b11ae52b 100644 --- a/polaris-react/locales/es.json +++ b/polaris-react/locales/es.json @@ -214,7 +214,6 @@ "rename": "Cambiar nombre de vista", "duplicate": "Duplicar vista", "edit": "Editar vista", - "editColumns": "Editar columnas", "delete": "Eliminar vista", "copy": "Copia de {name}", "deleteModal": { @@ -390,6 +389,10 @@ "save": "Guardar", "cancel": "Cancelar" } + }, + "EditColumnsButton": { + "tooltip": "Editar columnas", + "accessibilityLabel": "Personalizar el orden y la visibilidad de las columnas de la tabla" } }, "ActionList": { diff --git a/polaris-react/locales/fi.json b/polaris-react/locales/fi.json index bcdd010fdbb..c26e3c61751 100644 --- a/polaris-react/locales/fi.json +++ b/polaris-react/locales/fi.json @@ -214,7 +214,6 @@ "rename": "Nimeä näkymä uudelleen", "duplicate": "Kopioi näkymä", "edit": "Muokkaa näkymää", - "editColumns": "Muokkaa sarakkeita", "delete": "Poista näkymä", "copy": "Kopio tiedostosta {name}", "deleteModal": { @@ -389,7 +388,11 @@ "cancel": "Peruuta" } }, - "searchFilterTooltipWithShortcut": "Hae ja suodata (F)" + "searchFilterTooltipWithShortcut": "Hae ja suodata (F)", + "EditColumnsButton": { + "tooltip": "Muokkaa sarakkeita", + "accessibilityLabel": "Muokkaa taulukon sarakkeiden järjestystä ja näkyvyyttä" + } }, "ActionList": { "SearchField": { diff --git a/polaris-react/locales/fr.json b/polaris-react/locales/fr.json index 3fb24bdb206..7c8e7ee6c81 100644 --- a/polaris-react/locales/fr.json +++ b/polaris-react/locales/fr.json @@ -214,7 +214,6 @@ "rename": "Renommer la vue", "duplicate": "Dupliquer la vue", "edit": "Modifier la vue", - "editColumns": "Modifier les colonnes", "delete": "Supprimer la vue", "copy": "Copie de {name}", "deleteModal": { @@ -390,6 +389,10 @@ "save": "Enregistrer", "cancel": "Annuler" } + }, + "EditColumnsButton": { + "tooltip": "Modifier les colonnes", + "accessibilityLabel": "Personnaliser l’ordre et la visibilité des colonnes du tableau" } }, "ActionList": { diff --git a/polaris-react/locales/it.json b/polaris-react/locales/it.json index 5d2271b9fa6..b7fb6853b69 100644 --- a/polaris-react/locales/it.json +++ b/polaris-react/locales/it.json @@ -214,7 +214,6 @@ "rename": "Rinomina vista", "duplicate": "Duplica vista", "edit": "Modifica vista", - "editColumns": "Modifica colonne", "delete": "Elimina vista", "copy": "Copia di {name}", "deleteModal": { @@ -390,6 +389,10 @@ "save": "Salva", "cancel": "Annulla" } + }, + "EditColumnsButton": { + "tooltip": "Modifica colonne", + "accessibilityLabel": "Personalizza l'ordine e la visibilità delle colonne della tabella" } }, "ActionList": { diff --git a/polaris-react/locales/ja.json b/polaris-react/locales/ja.json index 49b90ad07a4..7299f1d11f8 100644 --- a/polaris-react/locales/ja.json +++ b/polaris-react/locales/ja.json @@ -214,7 +214,6 @@ "rename": "ビューの名前を変更", "duplicate": "ビューを複製", "edit": "ビューを編集", - "editColumns": "列を編集", "delete": "ビューを削除", "copy": "{name}のコピー", "deleteModal": { @@ -389,6 +388,10 @@ "save": "保存", "cancel": "キャンセル" } + }, + "EditColumnsButton": { + "tooltip": "列を編集", + "accessibilityLabel": "表の列の順序および表示をカスタマイズする" } }, "ActionList": { diff --git a/polaris-react/locales/ko.json b/polaris-react/locales/ko.json index 23912856465..f6f1d817849 100644 --- a/polaris-react/locales/ko.json +++ b/polaris-react/locales/ko.json @@ -214,7 +214,6 @@ "rename": "보기 이름 바꾸기", "duplicate": "보기 복제", "edit": "보기 편집", - "editColumns": "열 편집", "delete": "보기 삭제", "copy": "{name}의 사본", "deleteModal": { @@ -389,6 +388,10 @@ "save": "저장", "cancel": "취소" } + }, + "EditColumnsButton": { + "tooltip": "열 편집", + "accessibilityLabel": "표의 주문 열 및 표시 방법 사용자 지정" } }, "ActionList": { diff --git a/polaris-react/locales/nb.json b/polaris-react/locales/nb.json index 8596d73d578..03908de8c90 100644 --- a/polaris-react/locales/nb.json +++ b/polaris-react/locales/nb.json @@ -214,7 +214,6 @@ "rename": "Gi visning nytt navn", "duplicate": "Dupliser visning", "edit": "Rediger visning", - "editColumns": "Rediger kolonner", "delete": "Slett visning", "copy": "Kopi av {name}", "deleteModal": { @@ -389,6 +388,10 @@ "save": "Lagre", "cancel": "Avbryt" } + }, + "EditColumnsButton": { + "tooltip": "Endre kolonner", + "accessibilityLabel": "Tilpass kolonnerekkefølge og -synlighet i tabellen" } }, "ActionList": { diff --git a/polaris-react/locales/nl.json b/polaris-react/locales/nl.json index 2232bf5af5b..ba933543236 100644 --- a/polaris-react/locales/nl.json +++ b/polaris-react/locales/nl.json @@ -214,7 +214,6 @@ "rename": "Naam van weergave wijzigen", "duplicate": "Weergave dupliceren", "edit": "Weergave bewerken", - "editColumns": "Kolommen bewerken", "delete": "Weergave verwijderen", "copy": "Kopie van {name}", "deleteModal": { @@ -389,6 +388,10 @@ "save": "Opslaan", "cancel": "Annuleren" } + }, + "EditColumnsButton": { + "tooltip": "Kolommen bewerken", + "accessibilityLabel": "Kolomvolgorde en zichtbaarheid van tabel aanpassen" } }, "ActionList": { diff --git a/polaris-react/locales/pl.json b/polaris-react/locales/pl.json index f5b44fb783e..dc6d6098d74 100644 --- a/polaris-react/locales/pl.json +++ b/polaris-react/locales/pl.json @@ -214,7 +214,6 @@ "rename": "Zmień nazwę widoku", "duplicate": "Duplikuj widok", "edit": "Edytuj widok", - "editColumns": "Edytuj kolumny", "delete": "Usuń widok", "copy": "Kopia {name}", "deleteModal": { @@ -391,6 +390,10 @@ "save": "Zapisz", "cancel": "Anuluj" } + }, + "EditColumnsButton": { + "tooltip": "Edytuj kolumny", + "accessibilityLabel": "Dostosuj kolejność i widoczność kolumn tabeli" } }, "ActionList": { diff --git a/polaris-react/locales/pt-BR.json b/polaris-react/locales/pt-BR.json index 2479dcb22d6..0261cdbad43 100644 --- a/polaris-react/locales/pt-BR.json +++ b/polaris-react/locales/pt-BR.json @@ -214,7 +214,6 @@ "rename": "Renomear visualização", "duplicate": "Duplicar visualização", "edit": "Editar visualização", - "editColumns": "Editar colunas", "delete": "Excluir visualização", "copy": "Cópia de {name}", "deleteModal": { @@ -390,6 +389,10 @@ "save": "Salvar", "cancel": "Cancelar" } + }, + "EditColumnsButton": { + "tooltip": "Editar colunas", + "accessibilityLabel": "Personalizar a ordem e a visibilidade das colunas da tabela" } }, "ActionList": { diff --git a/polaris-react/locales/pt-PT.json b/polaris-react/locales/pt-PT.json index 6054a65c21b..fe32c16b993 100644 --- a/polaris-react/locales/pt-PT.json +++ b/polaris-react/locales/pt-PT.json @@ -214,7 +214,6 @@ "rename": "Renomear visualização", "duplicate": "Duplicar visualização", "edit": "Editar visualização", - "editColumns": "Editar colunas", "delete": "Eliminar visualização", "copy": "Cópia de {name}", "deleteModal": { @@ -390,6 +389,10 @@ "save": "Guardar", "cancel": "Cancelar" } + }, + "EditColumnsButton": { + "tooltip": "Editar colunas", + "accessibilityLabel": "Personalizar visibilidade e ordem da coluna da tabela" } }, "ActionList": { diff --git a/polaris-react/locales/sv.json b/polaris-react/locales/sv.json index 31b04d806f4..f347cb985bb 100644 --- a/polaris-react/locales/sv.json +++ b/polaris-react/locales/sv.json @@ -214,7 +214,6 @@ "rename": "Döp om vy", "duplicate": "Duplicera vy", "edit": "Redigera vy", - "editColumns": "Redigera kolumner", "delete": "Radera vy", "copy": "Kopia av {name}", "deleteModal": { @@ -389,6 +388,10 @@ "save": "Spara", "cancel": "Avbryt" } + }, + "EditColumnsButton": { + "tooltip": "Redigera kolumner", + "accessibilityLabel": "Anpassa tabellkolumnernas ordning och synlighet" } }, "ActionList": { diff --git a/polaris-react/locales/th.json b/polaris-react/locales/th.json index e86ec0e8f1f..dace0a6950f 100644 --- a/polaris-react/locales/th.json +++ b/polaris-react/locales/th.json @@ -214,7 +214,6 @@ "rename": "เปลี่ยนชื่อมุมมอง", "duplicate": "ทำซ้ำมุมมอง", "edit": "แก้ไขมุมมอง", - "editColumns": "แก้ไขคอลัมน์", "delete": "ลบมุมมอง", "copy": "สำเนาของ {name}", "deleteModal": { @@ -389,6 +388,10 @@ "save": "บันทึก", "cancel": "ยกเลิก" } + }, + "EditColumnsButton": { + "tooltip": "แก้ไขคอลัมน์", + "accessibilityLabel": "ปรับแต่งลำดับและการแสดงผลคอลัมน์ในตาราง" } }, "ActionList": { diff --git a/polaris-react/locales/tr.json b/polaris-react/locales/tr.json index 4290695aeef..02bc265b773 100644 --- a/polaris-react/locales/tr.json +++ b/polaris-react/locales/tr.json @@ -214,7 +214,6 @@ "rename": "Görünümü yeniden adlandır", "duplicate": "Görünümü çoğalt", "edit": "Görünümü düzenle", - "editColumns": "Sütunları düzenle", "delete": "Görünümü sil", "copy": "{name} kopyası", "deleteModal": { @@ -389,6 +388,10 @@ "save": "Kaydet", "cancel": "İptal" } + }, + "EditColumnsButton": { + "tooltip": "Sütunları düzenleyin", + "accessibilityLabel": "Tablonun sütun sırasını ve görünürlüğünü özelleştirin" } }, "ActionList": { diff --git a/polaris-react/locales/vi.json b/polaris-react/locales/vi.json index 701c8911ac2..283ad465365 100644 --- a/polaris-react/locales/vi.json +++ b/polaris-react/locales/vi.json @@ -214,7 +214,6 @@ "rename": "Đổi tên chế độ xem", "duplicate": "Sao chép chế độ xem", "edit": "Chỉnh sửa chế độ xem", - "editColumns": "Sửa cột", "delete": "Xóa chế độ xem", "copy": "Bản sao của {name}", "deleteModal": { @@ -389,6 +388,10 @@ "save": "Lưu", "cancel": "Hủy" } + }, + "EditColumnsButton": { + "tooltip": "Sửa cột", + "accessibilityLabel": "Tùy chỉnh thứ tự và khả năng hiển thị của cột trong bảng" } }, "ActionList": { diff --git a/polaris-react/locales/zh-CN.json b/polaris-react/locales/zh-CN.json index 4c9a640826c..39be4afc9dd 100644 --- a/polaris-react/locales/zh-CN.json +++ b/polaris-react/locales/zh-CN.json @@ -214,7 +214,6 @@ "rename": "重命名视图", "duplicate": "复制视图", "edit": "编辑视图", - "editColumns": "编辑列", "delete": "删除视图", "copy": "{name} 的副本", "deleteModal": { @@ -389,6 +388,10 @@ "save": "保存", "cancel": "取消" } + }, + "EditColumnsButton": { + "tooltip": "编辑列", + "accessibilityLabel": "自定义表列顺序和可见性" } }, "ActionList": { diff --git a/polaris-react/locales/zh-TW.json b/polaris-react/locales/zh-TW.json index 02b4ad72d08..a119423dd6b 100644 --- a/polaris-react/locales/zh-TW.json +++ b/polaris-react/locales/zh-TW.json @@ -214,7 +214,6 @@ "rename": "重新命名檢視畫面", "duplicate": "複製檢視畫面", "edit": "編輯檢視畫面", - "editColumns": "編輯欄", "delete": "刪除檢視畫面", "copy": "{name}的副本", "deleteModal": { @@ -389,7 +388,11 @@ "cancel": "取消" } }, - "searchFilterTooltipWithShortcut": "搜尋和篩選 (F)" + "searchFilterTooltipWithShortcut": "搜尋和篩選 (F)", + "EditColumnsButton": { + "tooltip": "編輯欄", + "accessibilityLabel": "自訂表格欄順序和能見度" + } }, "ActionList": { "SearchField": { diff --git a/polaris-react/src/components/IndexFilters/IndexFilters.stories.tsx b/polaris-react/src/components/IndexFilters/IndexFilters.stories.tsx index f30b136577e..ba3d0b4b9cb 100644 --- a/polaris-react/src/components/IndexFilters/IndexFilters.stories.tsx +++ b/polaris-react/src/components/IndexFilters/IndexFilters.stories.tsx @@ -403,6 +403,10 @@ export function WithFilteringByDefault() { return ; } +export function WithEditColumsButton() { + return ; +} + export function WithoutKeyboardShortcuts() { return ; } @@ -951,6 +955,7 @@ export function Disabled() { mode={mode} setMode={setMode} disabled + showEditColumnsButton /> diff --git a/polaris-react/src/components/IndexFilters/IndexFilters.tsx b/polaris-react/src/components/IndexFilters/IndexFilters.tsx index 9aaae0fcbbb..73c0d6e45c0 100644 --- a/polaris-react/src/components/IndexFilters/IndexFilters.tsx +++ b/polaris-react/src/components/IndexFilters/IndexFilters.tsx @@ -21,6 +21,7 @@ import { SortButton, SearchFilterButton, UpdateButtons, + EditColumnsButton, } from './components'; import type { IndexFiltersPrimaryAction, @@ -48,6 +49,11 @@ const transitionStyles = { type ExecutedCallback = (name: string) => Promise; +type ActionableIndexFiltersMode = Exclude< + IndexFiltersMode, + IndexFiltersMode.Default +>; + export interface IndexFiltersProps extends Omit< FiltersProps, @@ -71,7 +77,7 @@ export interface IndexFiltersProps /** The cancel action to display */ cancelAction: IndexFiltersCancelAction; /** Optional callback invoked when a merchant begins to edit a view */ - onEditStart?: () => void; + onEditStart?: (mode: ActionableIndexFiltersMode) => void; /** The current mode of the IndexFilters component. Used to determine which view to show */ mode: IndexFiltersMode; /** Callback to set the mode of the IndexFilters component */ @@ -96,6 +102,8 @@ export interface IndexFiltersProps closeOnChildOverlayClick?: boolean; /** Optional override to the default keyboard shortcuts available */ disableKeyboardShortcuts?: boolean; + /** Whether to display the edit columns button with the other default mode filter actions */ + showEditColumnsButton?: boolean; } export function IndexFilters({ @@ -134,6 +142,7 @@ export function IndexFilters({ hideQueryField, closeOnChildOverlayClick, disableKeyboardShortcuts, + showEditColumnsButton, }: IndexFiltersProps) { const i18n = useI18n(); const {mdDown} = useBreakpoints(); @@ -230,10 +239,13 @@ export function IndexFilters({ }; }, [cancelAction, onExecutedCancelAction]); - const beginEdit = useCallback(() => { - setMode(IndexFiltersMode.Filtering); - onEditStart?.(); - }, [onEditStart, setMode]); + const beginEdit = useCallback( + (mode: ActionableIndexFiltersMode) => { + setMode(mode); + onEditStart?.(mode); + }, + [onEditStart, setMode], + ); const updateButtonsMarkup = useMemo( () => ( @@ -270,10 +282,21 @@ export function IndexFilters({ disabled, ]); + function handleClickEditColumnsButon() { + beginEdit(IndexFiltersMode.EditingColumns); + } + + const editColumnsMarkup = showEditColumnsButton ? ( + + ) : null; + const isActionLoading = primaryAction?.loading || cancelAction?.loading; function handleClickFilterButton() { - beginEdit(); + beginEdit(IndexFiltersMode.Filtering); } const searchFilterTooltipLabelId = disableKeyboardShortcuts @@ -310,7 +333,7 @@ export function IndexFilters({ if (mode !== IndexFiltersMode.Default) { return; } - beginEdit(); + beginEdit(IndexFiltersMode.Filtering); } return ( @@ -393,6 +416,7 @@ export function IndexFilters({ }} /> )} + {editColumnsMarkup} {sortMarkup} ) : null} diff --git a/polaris-react/src/components/IndexFilters/components/EditColumnsButton/EditColumnsButton.tsx b/polaris-react/src/components/IndexFilters/components/EditColumnsButton/EditColumnsButton.tsx new file mode 100644 index 00000000000..59b4433b757 --- /dev/null +++ b/polaris-react/src/components/IndexFilters/components/EditColumnsButton/EditColumnsButton.tsx @@ -0,0 +1,46 @@ +import React from 'react'; +import {Columns3Minor} from '@shopify/polaris-icons'; + +import {useFeatures} from '../../../../utilities/features'; +import {Icon} from '../../../Icon'; +import {useI18n} from '../../../../utilities/i18n'; +import {FilterButton} from '../FilterButton'; +import {Tooltip} from '../../../Tooltip'; +import {Text} from '../../../Text'; + +export interface EditColumnsButtonProps { + onClick: () => void; + disabled?: boolean; +} + +export function EditColumnsButton({onClick, disabled}: EditColumnsButtonProps) { + const i18n = useI18n(); + const {polarisSummerEditions2023} = useFeatures(); + + const tooltipContent = ( + + {i18n.translate('Polaris.IndexFilters.EditColumnsButton.tooltip')} + + ); + + return ( + + + {!polarisSummerEditions2023 ? ( + + ) : null} + + + ); +} diff --git a/polaris-react/src/components/IndexFilters/components/EditColumnsButton/index.ts b/polaris-react/src/components/IndexFilters/components/EditColumnsButton/index.ts new file mode 100644 index 00000000000..6557d2de83b --- /dev/null +++ b/polaris-react/src/components/IndexFilters/components/EditColumnsButton/index.ts @@ -0,0 +1 @@ +export {EditColumnsButton} from './EditColumnsButton'; diff --git a/polaris-react/src/components/IndexFilters/components/index.ts b/polaris-react/src/components/IndexFilters/components/index.ts index 6989dec4cce..956db0bf98b 100644 --- a/polaris-react/src/components/IndexFilters/components/index.ts +++ b/polaris-react/src/components/IndexFilters/components/index.ts @@ -2,3 +2,4 @@ export {Container} from './Container'; export {SearchFilterButton} from './SearchFilterButton'; export {SortButton} from './SortButton'; export {UpdateButtons} from './UpdateButtons'; +export {EditColumnsButton} from './EditColumnsButton'; diff --git a/polaris-react/src/components/IndexFilters/tests/IndexFilters.test.tsx b/polaris-react/src/components/IndexFilters/tests/IndexFilters.test.tsx index 1eb9e2b6373..edd5cde4baf 100644 --- a/polaris-react/src/components/IndexFilters/tests/IndexFilters.test.tsx +++ b/polaris-react/src/components/IndexFilters/tests/IndexFilters.test.tsx @@ -8,7 +8,12 @@ import {Filters} from '../../Filters'; import {IndexFilters} from '..'; import {IndexFiltersMode} from '../../../utilities/index-filters'; import type {IndexFiltersProps} from '../IndexFilters'; -import {SearchFilterButton, SortButton, UpdateButtons} from '../components'; +import { + SearchFilterButton, + SortButton, + UpdateButtons, + EditColumnsButton, +} from '../components'; describe('IndexFilters', () => { const defaultProps: IndexFiltersProps = { @@ -86,6 +91,7 @@ describe('IndexFilters', () => { setMode: jest.fn(), canCreateNewView: true, onCreateNewView: jest.fn(), + showEditColumnsButton: false, }; beforeEach(() => { @@ -109,6 +115,23 @@ describe('IndexFilters', () => { expect(setMode).toHaveBeenCalledWith(IndexFiltersMode.Filtering); }); + it('calls onEditStart with IndexFiltersMode.Filtering when clicked', () => { + const setMode = jest.fn(); + const onEditStart = jest.fn(); + const wrapper = mountWithApp( + , + ); + wrapper.act(() => { + wrapper.find(SearchFilterButton)!.trigger('onClick'); + }); + + expect(onEditStart).toHaveBeenCalledWith(IndexFiltersMode.Filtering); + }); + it('renders non-disabled tabs if the current mode is Default', () => { const wrapper = mountWithApp(); @@ -214,6 +237,17 @@ describe('IndexFilters', () => { expect(wrapper).not.toContainReactComponent(SortButton); expect(wrapper).not.toContainReactComponent(SearchFilterButton); }); + + it('does not render the EditColumnsButton', () => { + const wrapper = mountWithApp( + , + ); + + expect(wrapper).not.toContainReactComponent(EditColumnsButton); + }); }); describe('pressing f', () => { @@ -234,7 +268,7 @@ describe('IndexFilters', () => { }), ); - expect(onEditStart).toHaveBeenCalled(); + expect(onEditStart).toHaveBeenCalledWith(IndexFiltersMode.Filtering); }); }); @@ -314,7 +348,7 @@ describe('IndexFilters', () => { }), ); - expect(onEditStart).not.toHaveBeenCalled(); + expect(onEditStart).not.toHaveBeenCalledWith(IndexFiltersMode.Filtering); }); it('does not call the cancelAction.onAction method when pressing escape in Filtering mode', () => { @@ -395,5 +429,76 @@ describe('IndexFilters', () => { disabled: true, }); }); + + it('renders EditColumnsButton with the disabled prop', () => { + const wrapper = mountWithApp( + , + ); + + expect(wrapper).toContainReactComponent(EditColumnsButton, { + disabled: true, + }); + }); + }); + + describe('EditColumnsButton', () => { + it('renders when showEditColumnsButton is true', () => { + const wrapper = mountWithApp( + , + ); + + expect(wrapper).toContainReactComponent(EditColumnsButton); + }); + + it('does not renders when showEditColumnsButton is false', () => { + const wrapper = mountWithApp( + , + ); + + expect(wrapper).not.toContainReactComponent(EditColumnsButton); + }); + + it.each([IndexFiltersMode.EditingColumns, IndexFiltersMode.Filtering])( + 'does not renders when IndexFiltersMode is %s', + (mode: IndexFiltersMode) => { + const wrapper = mountWithApp( + , + ); + + expect(wrapper).not.toContainReactComponent(EditColumnsButton); + }, + ); + + it('sets mode to EditingColumns when clicked', () => { + const setMode = jest.fn(); + const wrapper = mountWithApp( + , + ); + wrapper.act(() => { + wrapper.find(EditColumnsButton)!.trigger('onClick'); + }); + + expect(setMode).toHaveBeenCalledWith(IndexFiltersMode.EditingColumns); + }); + + it('calls onEditStart with IndexFiltersMode.EditingColumns when clicked', () => { + const onEditStart = jest.fn(); + const wrapper = mountWithApp( + , + ); + wrapper.act(() => { + wrapper.find(EditColumnsButton)!.trigger('onClick'); + }); + + expect(onEditStart).toHaveBeenCalledWith(IndexFiltersMode.EditingColumns); + }); }); }); diff --git a/polaris-react/src/components/Tabs/Tabs.stories.tsx b/polaris-react/src/components/Tabs/Tabs.stories.tsx index a73c6cbb85a..8cab13664bf 100644 --- a/polaris-react/src/components/Tabs/Tabs.stories.tsx +++ b/polaris-react/src/components/Tabs/Tabs.stories.tsx @@ -108,12 +108,7 @@ export function Fitted() { ); } -type AlphaTabAction = - | 'rename' - | 'edit' - | 'edit-columns' - | 'duplicate' - | 'delete'; +type AlphaTabAction = 'rename' | 'edit' | 'duplicate' | 'delete'; export function WithActions() { const sleep = (ms: number) => diff --git a/polaris-react/src/components/Tabs/components/Tab/Tab.tsx b/polaris-react/src/components/Tabs/components/Tab/Tab.tsx index b6ef30c4074..e97b7d2edb6 100644 --- a/polaris-react/src/components/Tabs/components/Tab/Tab.tsx +++ b/polaris-react/src/components/Tabs/components/Tab/Tab.tsx @@ -14,7 +14,6 @@ import type { import { InfoMinor, DuplicateMinor, - Columns3Minor, EditMinor, DeleteMinor, ChevronDownMinor, @@ -221,10 +220,6 @@ export const Tab = forwardRef( icon: EditMinor, content: i18n.translate('Polaris.Tabs.Tab.edit'), }, - 'edit-columns': { - icon: Columns3Minor, - content: i18n.translate('Polaris.Tabs.Tab.editColumns'), - }, delete: { icon: DeleteMinor, content: i18n.translate('Polaris.Tabs.Tab.delete'), diff --git a/polaris-react/src/components/Tabs/components/Tab/tests/Tab.test.tsx b/polaris-react/src/components/Tabs/components/Tab/tests/Tab.test.tsx index 999ac2128e5..e20b1841e5d 100644 --- a/polaris-react/src/components/Tabs/components/Tab/tests/Tab.test.tsx +++ b/polaris-react/src/components/Tabs/components/Tab/tests/Tab.test.tsx @@ -25,11 +25,6 @@ describe('Tab', () => { onAction: jest.fn(), onPrimaryAction: jest.fn(), }, - { - type: 'edit-columns', - onAction: jest.fn(), - onPrimaryAction: jest.fn(), - }, { type: 'duplicate', onAction: jest.fn(), @@ -160,11 +155,6 @@ describe('Tab', () => { icon: expect.any(Function), onAction: expect.any(Function), }, - { - content: 'Edit columns', - icon: expect.any(Function), - onAction: expect.any(Function), - }, { content: 'Duplicate view', icon: expect.any(Function), @@ -207,12 +197,6 @@ describe('Tab', () => { onAction: expect.any(Function), disabled: true, }, - { - content: 'Edit columns', - icon: expect.any(Function), - onAction: expect.any(Function), - disabled: true, - }, { content: 'Duplicate view', icon: expect.any(Function), @@ -233,7 +217,6 @@ describe('Tab', () => { it.each([ ['rename', 'Rename view'], ['edit', 'Edit view'], - ['edit-columns', 'Edit columns'], ['duplicate', 'Duplicate view'], ['delete', 'Delete view'], ])( diff --git a/polaris-react/src/components/Tabs/types.ts b/polaris-react/src/components/Tabs/types.ts index 08e64ef5e60..865ffcb9d8d 100644 --- a/polaris-react/src/components/Tabs/types.ts +++ b/polaris-react/src/components/Tabs/types.ts @@ -2,12 +2,7 @@ import type {ReactNode} from 'react'; import type {ActionListItemDescriptor} from '../../types'; -export type TabAction = - | 'rename' - | 'edit' - | 'edit-columns' - | 'duplicate' - | 'delete'; +export type TabAction = 'rename' | 'edit' | 'duplicate' | 'delete'; interface TabActionDescriptor extends Omit { diff --git a/polaris.shopify.com/content/components/tables/index-table.md b/polaris.shopify.com/content/components/tables/index-table.md index 64498ba1e4f..4b1e5842e5d 100644 --- a/polaris.shopify.com/content/components/tables/index-table.md +++ b/polaris.shopify.com/content/components/tables/index-table.md @@ -29,10 +29,13 @@ keywords: examples: - fileName: index-table-default.tsx title: Default - description: A index table with simple items and no bulk actions, sorting, or filtering. + description: An index table with simple items and no bulk actions, sorting, or filtering. - fileName: index-table-with-views-search-filter-sorting.tsx title: With saved views, search, filtering, and sorting description: An index table with saved views, search, filtering, sorting, and bulk actions + - fileName: index-filters-with-edit-colums-button.tsx + title: With edit columns button + description: An index table with edit columns, saved views, search, filtering, sorting, and bulk actions - fileName: index-table-with-disabled-rows.tsx title: With disabled rows description: An index table with saved views, search, filtering, sorting, and bulk actions diff --git a/polaris.shopify.com/pages/examples/index-filters-with-edit-colums-button.tsx b/polaris.shopify.com/pages/examples/index-filters-with-edit-colums-button.tsx new file mode 100644 index 00000000000..782cb5c6d91 --- /dev/null +++ b/polaris.shopify.com/pages/examples/index-filters-with-edit-colums-button.tsx @@ -0,0 +1,400 @@ +import { + TextField, + IndexTable, + LegacyCard, + IndexFilters, + useSetIndexFiltersMode, + useIndexResourceState, + Text, + ChoiceList, + RangeSlider, + Badge, +} from '@shopify/polaris'; +import type {IndexFiltersProps, TabProps} from '@shopify/polaris'; +import {useState, useCallback} from 'react'; +import {withPolarisExample} from '../../src/components/PolarisExampleWrapper'; + +function IndexFiltersDefaultExample() { + const sleep = (ms: number) => + new Promise((resolve) => setTimeout(resolve, ms)); + const [itemStrings, setItemStrings] = useState([ + 'All', + 'Unpaid', + 'Open', + 'Closed', + 'Local delivery', + 'Local pickup', + ]); + const deleteView = (index: number) => { + const newItemStrings = [...itemStrings]; + newItemStrings.splice(index, 1); + setItemStrings(newItemStrings); + setSelected(0); + }; + + const duplicateView = async (name: string) => { + setItemStrings([...itemStrings, name]); + setSelected(itemStrings.length); + await sleep(1); + return true; + }; + + const tabs: TabProps[] = itemStrings.map((item, index) => ({ + content: item, + index, + onAction: () => {}, + id: `${item}-${index}`, + isLocked: index === 0, + actions: + index === 0 + ? [] + : [ + { + type: 'rename', + onAction: () => {}, + onPrimaryAction: async (value: string): Promise => { + const newItemsStrings = tabs.map((item, idx) => { + if (idx === index) { + return value; + } + return item.content; + }); + await sleep(1); + setItemStrings(newItemsStrings); + return true; + }, + }, + { + type: 'duplicate', + onPrimaryAction: async (value: string): Promise => { + await sleep(1); + duplicateView(value); + return true; + }, + }, + { + type: 'edit', + }, + { + type: 'delete', + onPrimaryAction: async () => { + await sleep(1); + deleteView(index); + return true; + }, + }, + ], + })); + const [selected, setSelected] = useState(0); + const onCreateNewView = async (value: string) => { + await sleep(500); + setItemStrings([...itemStrings, value]); + setSelected(itemStrings.length); + return true; + }; + const sortOptions: IndexFiltersProps['sortOptions'] = [ + {label: 'Order', value: 'order asc', directionLabel: 'Ascending'}, + {label: 'Order', value: 'order desc', directionLabel: 'Descending'}, + {label: 'Customer', value: 'customer asc', directionLabel: 'A-Z'}, + {label: 'Customer', value: 'customer desc', directionLabel: 'Z-A'}, + {label: 'Date', value: 'date asc', directionLabel: 'A-Z'}, + {label: 'Date', value: 'date desc', directionLabel: 'Z-A'}, + {label: 'Total', value: 'total asc', directionLabel: 'Ascending'}, + {label: 'Total', value: 'total desc', directionLabel: 'Descending'}, + ]; + const [sortSelected, setSortSelected] = useState(['order asc']); + const {mode, setMode} = useSetIndexFiltersMode(); + const onHandleCancel = () => {}; + + const onHandleSave = async () => { + await sleep(1); + return true; + }; + + const primaryAction: IndexFiltersProps['primaryAction'] = + selected === 0 + ? { + type: 'save-as', + onAction: onCreateNewView, + disabled: false, + loading: false, + } + : { + type: 'save', + onAction: onHandleSave, + disabled: false, + loading: false, + }; + const [accountStatus, setAccountStatus] = useState( + undefined, + ); + const [moneySpent, setMoneySpent] = useState<[number, number] | undefined>( + undefined, + ); + const [taggedWith, setTaggedWith] = useState(''); + const [queryValue, setQueryValue] = useState(''); + + const handleAccountStatusChange = useCallback( + (value: string[]) => setAccountStatus(value), + [], + ); + const handleMoneySpentChange = useCallback( + (value: [number, number]) => setMoneySpent(value), + [], + ); + const handleTaggedWithChange = useCallback( + (value: string) => setTaggedWith(value), + [], + ); + const handleFiltersQueryChange = useCallback( + (value: string) => setQueryValue(value), + [], + ); + const handleAccountStatusRemove = useCallback( + () => setAccountStatus(undefined), + [], + ); + const handleMoneySpentRemove = useCallback( + () => setMoneySpent(undefined), + [], + ); + const handleTaggedWithRemove = useCallback(() => setTaggedWith(''), []); + const handleQueryValueRemove = useCallback(() => setQueryValue(''), []); + const handleFiltersClearAll = useCallback(() => { + handleAccountStatusRemove(); + handleMoneySpentRemove(); + handleTaggedWithRemove(); + handleQueryValueRemove(); + }, [ + handleAccountStatusRemove, + handleMoneySpentRemove, + handleQueryValueRemove, + handleTaggedWithRemove, + ]); + + const filters = [ + { + key: 'accountStatus', + label: 'Account status', + filter: ( + + ), + shortcut: true, + }, + { + key: 'taggedWith', + label: 'Tagged with', + filter: ( + + ), + shortcut: true, + }, + { + key: 'moneySpent', + label: 'Money spent', + filter: ( + + ), + }, + ]; + + const appliedFilters: IndexFiltersProps['appliedFilters'] = []; + if (accountStatus && !isEmpty(accountStatus)) { + const key = 'accountStatus'; + appliedFilters.push({ + key, + label: disambiguateLabel(key, accountStatus), + onRemove: handleAccountStatusRemove, + }); + } + if (moneySpent) { + const key = 'moneySpent'; + appliedFilters.push({ + key, + label: disambiguateLabel(key, moneySpent), + onRemove: handleMoneySpentRemove, + }); + } + if (!isEmpty(taggedWith)) { + const key = 'taggedWith'; + appliedFilters.push({ + key, + label: disambiguateLabel(key, taggedWith), + onRemove: handleTaggedWithRemove, + }); + } + + const orders = [ + { + id: '1020', + order: ( + + #1020 + + ), + date: 'Jul 20 at 4:34pm', + customer: 'Jaydon Stanton', + total: '$969.44', + paymentStatus: Paid, + fulfillmentStatus: Unfulfilled, + }, + { + id: '1019', + order: ( + + #1019 + + ), + date: 'Jul 20 at 3:46pm', + customer: 'Ruben Westerfelt', + total: '$701.19', + paymentStatus: Partially paid, + fulfillmentStatus: Unfulfilled, + }, + { + id: '1018', + order: ( + + #1018 + + ), + date: 'Jul 20 at 3.44pm', + customer: 'Leo Carder', + total: '$798.24', + paymentStatus: Paid, + fulfillmentStatus: Unfulfilled, + }, + ]; + const resourceName = { + singular: 'order', + plural: 'orders', + }; + + const {selectedResources, allResourcesSelected, handleSelectionChange} = + useIndexResourceState(orders); + + const rowMarkup = orders.map( + ( + {id, order, date, customer, total, paymentStatus, fulfillmentStatus}, + index, + ) => ( + + + + {order} + + + {date} + {customer} + {total} + {paymentStatus} + {fulfillmentStatus} + + ), + ); + + return ( + + {}} + onSort={setSortSelected} + primaryAction={primaryAction} + cancelAction={{ + onAction: onHandleCancel, + disabled: false, + loading: false, + }} + tabs={tabs} + selected={selected} + onSelect={setSelected} + canCreateNewView + onCreateNewView={onCreateNewView} + filters={filters} + appliedFilters={appliedFilters} + onClearAll={handleFiltersClearAll} + mode={mode} + setMode={setMode} + showEditColumnsButton + /> + + {rowMarkup} + + + ); + + function disambiguateLabel(key: string, value: string | any[]): string { + switch (key) { + case 'moneySpent': + return `Money spent is between $${value[0]} and $${value[1]}`; + case 'taggedWith': + return `Tagged with ${value}`; + case 'accountStatus': + return (value as string[]).map((val) => `Customer ${val}`).join(', '); + default: + return value as string; + } + } + + function isEmpty(value: string | any[]) { + if (Array.isArray(value)) { + return value.length === 0; + } else { + return value === '' || value == null; + } + } +} + +export default withPolarisExample(IndexFiltersDefaultExample); From 75c4db456a308a59172abbf81b8d23ff26c9f1d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Osorio?= Date: Mon, 2 Oct 2023 14:30:32 -0600 Subject: [PATCH 2/2] Update markup for polaris v12.x.x --- .../EditColumnsButton/EditColumnsButton.tsx | 20 +++++++------------ 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/polaris-react/src/components/IndexFilters/components/EditColumnsButton/EditColumnsButton.tsx b/polaris-react/src/components/IndexFilters/components/EditColumnsButton/EditColumnsButton.tsx index 59b4433b757..f531c77a33b 100644 --- a/polaris-react/src/components/IndexFilters/components/EditColumnsButton/EditColumnsButton.tsx +++ b/polaris-react/src/components/IndexFilters/components/EditColumnsButton/EditColumnsButton.tsx @@ -1,10 +1,8 @@ import React from 'react'; import {Columns3Minor} from '@shopify/polaris-icons'; -import {useFeatures} from '../../../../utilities/features'; -import {Icon} from '../../../Icon'; import {useI18n} from '../../../../utilities/i18n'; -import {FilterButton} from '../FilterButton'; +import {Button} from '../../../Button'; import {Tooltip} from '../../../Tooltip'; import {Text} from '../../../Text'; @@ -15,7 +13,6 @@ export interface EditColumnsButtonProps { export function EditColumnsButton({onClick, disabled}: EditColumnsButtonProps) { const i18n = useI18n(); - const {polarisSummerEditions2023} = useFeatures(); const tooltipContent = ( @@ -29,18 +26,15 @@ export function EditColumnsButton({onClick, disabled}: EditColumnsButtonProps) { preferredPosition="above" hoverDelay={400} > - - {!polarisSummerEditions2023 ? ( - - ) : null} - + /> ); }