@mohasinac/appkit 4.52.2 → 4.52.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,82 @@
1
+ /*
2
+ * WHY: Authored six-part procedures for the design-ux/feature-badge-picker page.
3
+ * WHAT: 5 case(s), keyed by full checklist id.
4
+ *
5
+ * @tag domain:tester
6
+ * @tag layer:seed
7
+ * @tag pattern:none
8
+ * @tag access:server-only
9
+ * @tag consumers:seed-data/authored/index.ts
10
+ * @tag sideEffects:none
11
+ */
12
+ export const authored = {
13
+ "checklist-design-ux-feature-badge-picker-features-are-searchable": {
14
+ roles: ["seller"],
15
+ startPage: "/store/products",
16
+ steps: [
17
+ "Sign in as the seller who owns the store and open /store/products.",
18
+ "Open any product for editing.",
19
+ "Scroll to the 'Feature badges' section of the form.",
20
+ "Open the control and type a few letters of a badge name.",
21
+ ],
22
+ expectedBehaviour: "Anything over five options is a searchable picker in this codebase. The control loads the platform badges eligible for this listing type plus the store's own, and filters them client-side as you type.",
23
+ expectedUiState: "'Feature badges' is a SINGLE control that opens a searchable list with a text input — not a two-column grid of bordered checkbox tiles, which is what it was. Typing narrows the visible options, and selected badges appear as removable chips on the control.",
24
+ endResult: "Closing and reopening the picker preserves the current selection. Nothing is saved until the product form itself is saved.",
25
+ },
26
+ "checklist-design-ux-feature-badge-picker-features-search-matches-description": {
27
+ roles: ["seller"],
28
+ startPage: "/store/products",
29
+ steps: [
30
+ "With the badge picker open, note a badge whose description contains a word that is NOT in its label — 'Sealed' is described as 'Factory wrap intact and never opened'.",
31
+ "Type that description-only word into the picker's search box, e.g. 'factory'.",
32
+ ],
33
+ inputs: { "picker search": "factory" },
34
+ expectedBehaviour: "Each option's description is folded into its label text specifically so it remains searchable after the conversion. In the old grid the description was visible on every tile, so it was findable by eye; in a filtered list it would be unreachable unless it is part of what is matched.",
35
+ expectedUiState: "The badge whose DESCRIPTION contains the typed word is listed, even though its name does not contain it. Searching a word in neither the label nor any description shows the no-results message instead.",
36
+ endResult: "Clearing the search box restores the full list. No selection has changed.",
37
+ },
38
+ "checklist-design-ux-feature-badge-picker-features-scope-is-visible": {
39
+ roles: ["seller"],
40
+ startPage: "/store/products",
41
+ steps: [
42
+ "Open the badge picker on a product belonging to a store that has at least one custom badge of its own.",
43
+ "Read the full text of several options in the list.",
44
+ "Select one platform badge and one store badge, then close the picker and read the two chips.",
45
+ ],
46
+ expectedBehaviour: "The grid separated the two scopes under 'Platform features' and 'Store custom features' headings. A flat searchable list has no headings, so the scope is carried in each option's own text — which also means it survives into the selected chip, where the grid's headings never reached.",
47
+ expectedUiState: "Every option ends with '(platform)' or '(your store)'. The two selected chips each still show which scope they came from. An option with no scope marker at all is a regression.",
48
+ endResult: "The distinction persists after saving and reopening the product — it is derived from the badge's own scope, not from selection order.",
49
+ },
50
+ "checklist-design-ux-feature-badge-picker-features-respects-the-cap": {
51
+ roles: ["seller"],
52
+ startPage: "/store/products",
53
+ steps: [
54
+ "Open the badge picker and read the 'Selected: N of 24' line above it.",
55
+ "Select badges one at a time until N reaches the stated maximum.",
56
+ "Try to select one more badge.",
57
+ ],
58
+ expectedBehaviour: "The ceiling is applied to the incoming selection rather than by disabling unticked rows, because a multi-select has no per-row disabled state. Selections beyond the cap are refused, keeping the earliest ones — so the badge that fails is the one just clicked, which is what a user expects.",
59
+ expectedUiState: "The counter stops at the maximum and does not go above it. Attempting to add one more does not increase the count and does not silently replace an existing selection. The counter line always matches the number of chips shown.",
60
+ expectedData: { "selected badge count": "never exceeds the stated maximum" },
61
+ endResult: "Saving the product stores at most the maximum number of badges. Reopening the product shows the same set.",
62
+ },
63
+ "checklist-design-ux-feature-badge-picker-features-inline-create": {
64
+ roles: ["seller"],
65
+ startPage: "/store/products",
66
+ steps: [
67
+ "Open the badge picker on one of your own products.",
68
+ "Choose 'Create a badge for my store'.",
69
+ "Enter a label such as 'QA inline badge' and leave the icon as its default.",
70
+ "Submit the create form.",
71
+ "Close the picker, reload the page, and reopen the picker.",
72
+ ],
73
+ inputs: { "Badge label": "QA inline badge", Icon: "star" },
74
+ expectedBehaviour: "Creating posts to the store-scope features route, which sets the owning store server-side rather than trusting the request body, and scopes the new badge to the listing type being edited. The picker's option list is refetched afterwards so the badge becomes a real option rather than a chip with nothing behind it.",
75
+ expectedUiState: "The create drawer closes on success and the new badge appears immediately as a SELECTED chip. Reopening the picker lists it among the options, marked '(your store)'. After a full page reload it is still listed and still selected on the product.",
76
+ expectedData: {
77
+ "new badge scope": "store",
78
+ "new badge owner": "the signed-in seller's store",
79
+ },
80
+ endResult: "The badge persists as a store-scope feature and is available on that store's other products too. Remove it from the store's feature settings afterwards so it does not accumulate.",
81
+ },
82
+ };
@@ -87,6 +87,8 @@ import { authored as a_cta_layout__editor_action_bar } from "./cta-layout__edito
87
87
  import { authored as a_cta_layout__product_bottom_bar } from "./cta-layout__product-bottom-bar.js";
88
88
  import { authored as a_design_ux__back_to_top_button } from "./design-ux__back-to-top-button.js";
89
89
  import { authored as a_design_ux__rich_text_readability } from "./design-ux__rich-text-readability.js";
90
+ import { authored as a_design_ux__action_bar_placement } from "./design-ux__action-bar-placement.js";
91
+ import { authored as a_design_ux__feature_badge_picker } from "./design-ux__feature-badge-picker.js";
90
92
  import { authored as a_design_ux__dashboard_layout } from "./design-ux__dashboard-layout.js";
91
93
  import { authored as a_design_ux__footer_theme } from "./design-ux__footer-theme.js";
92
94
  import { authored as a_design_ux__form_validation_errors } from "./design-ux__form-validation-errors.js";
@@ -210,6 +212,8 @@ export const AUTHORED_CASES = {
210
212
  ...a_cta_layout__product_bottom_bar,
211
213
  ...a_design_ux__back_to_top_button,
212
214
  ...a_design_ux__rich_text_readability,
215
+ ...a_design_ux__action_bar_placement,
216
+ ...a_design_ux__feature_badge_picker,
213
217
  ...a_design_ux__dashboard_layout,
214
218
  ...a_design_ux__footer_theme,
215
219
  ...a_design_ux__form_validation_errors,
@@ -3892,6 +3892,86 @@ const rawTesterChecklistItems = [
3892
3892
  },
3893
3893
  ],
3894
3894
  },
3895
+ {
3896
+ pageKey: "action-bar-placement",
3897
+ pageLabel: "Action Bar & Back-to-Top — Desktop vs Mobile",
3898
+ href: "/products",
3899
+ cases: [
3900
+ {
3901
+ key: "back-to-top-dismiss-visible",
3902
+ label: "The small ✕ beside the back-to-top button actually shows a ✕ — not an empty outlined pill",
3903
+ description: "Fixed 2026-10-15. BEFORE: the dismiss control was a `<Button size=\"sm\">` forced to 24px wide, but that size carries 12px of padding on each side — so the content box was exactly 0px and the ✕ glyph shrank to nothing. The button was there and clickable; the icon was invisible. AFTER: scroll any long page past ~400px. Two round controls appear in the corner: a large one with an up-chevron, and a small one with a clearly visible ✕. Clicking the ✕ hides both until you navigate to another page.",
3904
+ href: "/products",
3905
+ },
3906
+ {
3907
+ key: "action-bar-top-on-desktop",
3908
+ label: "ON DESKTOP (window wider than ~1024px): the page action bar sits directly UNDER the header, not welded to the bottom of the window",
3909
+ description: "Changed 2026-10-15. BEFORE: the same full-width bar was pinned to the bottom edge on every screen size — a mobile pattern on a desktop window, where it reads as a browser download bar and sits as far from the content as possible. AFTER: maximise the window and open a product detail page (or any admin list and tick a row to enter bulk mode). The bar must appear immediately below the site header, full width, with its shadow falling DOWNWARD onto the page.",
3910
+ href: "/products",
3911
+ },
3912
+ {
3913
+ key: "action-bar-bottom-on-mobile",
3914
+ label: "ON MOBILE (narrow window): the same action bar is still at the BOTTOM, stacked directly above the bottom tab bar",
3915
+ description: "The other half of the change, and the real regression risk — the two layouts share one component. Narrow the browser to phone width (or use device emulation) on the same page. The bar must be at the bottom, immediately above the bottom navigation, with its shadow falling UPWARD. Resize the window slowly across the ~1024px line both ways: the bar must move cleanly between the two positions and never appear in both places or in neither.",
3916
+ href: "/products",
3917
+ },
3918
+ {
3919
+ key: "action-bar-no-content-overlap",
3920
+ label: "ON DESKTOP: the top action bar never covers the first rows of page content, and leaves no empty gap when it is absent",
3921
+ description: "The bar is fixed, so the page reserves space for it. Two checks. (1) With the bar showing, the first heading/row of content must be fully readable, not hidden behind it. (2) On a page with NO action bar, there must be no blank band under the header — the reservation collapses to zero when nothing is published.",
3922
+ href: "/products",
3923
+ },
3924
+ {
3925
+ key: "action-bar-panels-open-into-screen",
3926
+ label: "Expandable panels on the action bar open INTO the screen — downward on desktop, upward on mobile",
3927
+ description: "On desktop, open an admin list, tick two rows to enter bulk mode, then open the action-type picker: it must expand DOWNWARD over the page. Repeat at phone width: it must expand UPWARD. A panel that opens off-screen is unusable, and the direction has to follow whichever edge the bar is attached to.",
3928
+ href: "/admin/products",
3929
+ },
3930
+ {
3931
+ key: "back-to-top-clears-the-bar",
3932
+ label: "The back-to-top button never overlaps the action bar or the bottom tab bar at any window width",
3933
+ description: "On mobile the button floats above whatever is stacked at the bottom edge; on desktop the bar is at the top so the button should sit lower. Scroll a long page at phone width with an action bar showing — the button must sit clear above it. Widen to desktop: the button must move down as the bottom tier empties, with no overlap at any point during the resize.",
3934
+ href: "/products",
3935
+ },
3936
+ ],
3937
+ },
3938
+ {
3939
+ pageKey: "feature-badge-picker",
3940
+ pageLabel: "Feature Badges — Searchable Picker",
3941
+ href: "/store/products",
3942
+ cases: [
3943
+ {
3944
+ key: "features-are-searchable",
3945
+ label: "The product form's Feature badges control is a SEARCHABLE dropdown, not a long grid of checkboxes",
3946
+ description: "Changed 2026-10-15. BEFORE: every eligible badge rendered as a bordered checkbox tile in a two-column grid — a wall a seller had to read end-to-end, which grew every time an admin added a badge. AFTER: as a seller, open any product for editing and find 'Feature badges'. It must be a single control that opens a searchable list. Type part of a badge name and confirm the list narrows.",
3947
+ href: "/store/products",
3948
+ },
3949
+ {
3950
+ key: "features-search-matches-description",
3951
+ label: "Searching the badge picker matches a badge's DESCRIPTION, not only its name",
3952
+ description: "The description is folded into each option so it stays searchable. Open the picker and type a word that appears only in a badge's description (e.g. 'factory', which is in Sealed's description but not its label). That badge must still appear in the filtered list.",
3953
+ href: "/store/products",
3954
+ },
3955
+ {
3956
+ key: "features-scope-is-visible",
3957
+ label: "Each badge option says whether it is a platform badge or one of your own store's",
3958
+ description: "The old grid showed two separate headings. A flat searchable list has none, so the scope rides in the option text — every option must end with '(platform)' or '(your store)', and the selected chips must keep that distinction too.",
3959
+ href: "/store/products",
3960
+ },
3961
+ {
3962
+ key: "features-respects-the-cap",
3963
+ label: "Selecting more than the allowed number of badges is prevented, and an over-limit product loads without blocking save",
3964
+ description: "Select badges until you hit the stated limit ('Selected: N of 24'), then try to select one more — the selection must not exceed the cap. This replaced a mechanism that disabled every unticked checkbox at the limit, so confirm the control still communicates that you are full rather than silently ignoring clicks.",
3965
+ href: "/store/products",
3966
+ },
3967
+ {
3968
+ key: "features-inline-create",
3969
+ label: "A seller can create a NEW store badge from inside the picker, and it is immediately selectable",
3970
+ description: "Added 2026-10-15. As a seller, open the badge picker and use 'Create a badge for my store'. Fill in a label and icon and submit. The drawer must close, the new badge must appear as a selected chip, and reopening the picker must list it as a real option marked '(your store)' — not a one-off chip that disappears on reload. Reload the page and confirm it persisted.",
3971
+ href: "/store/products",
3972
+ },
3973
+ ],
3974
+ },
3895
3975
  {
3896
3976
  pageKey: "rich-text-readability",
3897
3977
  pageLabel: "Admin-Authored Rich Text — Readability in Both Themes",