formica-ui-lib 1.0.149 → 1.0.151

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.
Files changed (27) hide show
  1. package/README.md +267 -7
  2. package/dist/componentProps/atoms/layout/ContentContainerProps.d.ts +8 -0
  3. package/dist/componentProps/atoms/layout/ContentGridProps.d.ts +12 -0
  4. package/dist/componentProps/atoms/layout/FlowRowProps.d.ts +12 -0
  5. package/dist/componentProps/molecules/selectors/filterbar/DropdownFilterProps.d.ts +5 -0
  6. package/dist/componentProps/molecules/selectors/filterbar/FilterBarButtonProps.d.ts +5 -0
  7. package/dist/componentProps/molecules/selectors/filterbar/FilterBarProps.d.ts +6 -0
  8. package/dist/componentProps/molecules/selectors/filterbar/SearchFilterProps.d.ts +5 -0
  9. package/dist/componentProps/organisms/imagegrid/ImageGridProps.d.ts +5 -0
  10. package/dist/componentProps/scene/category/CategorySceneProps.d.ts +8 -2
  11. package/dist/componentProps/scene/gallery/GallerySceneProps.d.ts +4 -2
  12. package/dist/index.cjs +8 -8
  13. package/dist/index.d.ts +14 -0
  14. package/dist/index.js +1071 -992
  15. package/dist/stories/atoms/layout/ContentContainer/ContentContainer.d.ts +4 -0
  16. package/dist/stories/atoms/layout/ContentGrid/ContentGrid.d.ts +4 -0
  17. package/dist/stories/atoms/layout/FlowRow/FlowRow.d.ts +4 -0
  18. package/dist/stories/molecules/selectors/filterbar/DropdownFilter.d.ts +4 -0
  19. package/dist/stories/molecules/selectors/filterbar/FilterBar.d.ts +4 -0
  20. package/dist/stories/molecules/selectors/filterbar/FilterBarButton.d.ts +4 -0
  21. package/dist/stories/molecules/selectors/filterbar/SearchFilter.d.ts +4 -0
  22. package/package.json +1 -1
  23. package/dist/componentProps/molecules/selectors/sortandfilterbar/SortAndFilterBarProps.d.ts +0 -8
  24. package/dist/componentProps/molecules/selectors/tripledropdownbar/TripleDropdownBarProps.d.ts +0 -4
  25. package/dist/stories/molecules/selectors/sortandfilterbar/SortAndFilterBar.d.ts +0 -4
  26. package/dist/stories/molecules/selectors/tripledropdownbar/TripleDropdownBar.d.ts +0 -4
  27. /package/dist/stories/molecules/selectors/{sortandfilterbar/SortAndFilterBar.test.d.ts → filterbar/FilterBar.test.d.ts} +0 -0
package/README.md CHANGED
@@ -1,17 +1,263 @@
1
- # formicaui
1
+ # Formica UI
2
2
 
3
- This is the home of Formica's Storybook components for the UI
3
+ This repository contains Formica's Storybook-based UI component library.
4
+
5
+ The goal of this repo is to keep UI pieces:
6
+
7
+ - reusable
8
+ - easy to compose
9
+ - easy to wire into a BFF or app layer
10
+ - free from business logic
11
+
12
+ If you are new to the codebase, read this file first. If you need the stricter engineering rules, read [CONTRIBUTING.md](./CONTRIBUTING.md).
13
+
14
+ ## What Lives Here
15
+
16
+ This project is mainly for:
17
+
18
+ - atoms, molecules, organisms, templates, and scenes
19
+ - Storybook stories for those components
20
+ - shared prop contracts and callback payload types
21
+
22
+ This project is not where UI components should:
23
+
24
+ - fetch data
25
+ - handle routing
26
+ - talk directly to APIs
27
+ - make business decisions
28
+
29
+ ## Folder Basics
30
+
31
+ - `src/stories/...`
32
+ UI components and Storybook-facing implementations
33
+ - `src/componentProps/...`
34
+ prop contracts and shared exported types
35
+ - `mocks/...`
36
+ mock data used by stories and scene simulations
37
+
38
+ ## Working Rule Of Thumb
39
+
40
+ Think of most UI components as display components.
41
+
42
+ Their job is to:
43
+
44
+ - render data
45
+ - accept callback props
46
+ - emit typed payloads upward
47
+ - keep only small visual state when needed
48
+
49
+ Their job is not to:
50
+
51
+ - decide where the app navigates
52
+ - call APIs
53
+ - manage app-wide state
54
+ - invent behavior on their own
55
+
56
+ ## Coding Standards In Plain English
57
+
58
+ ### 1. Put props and types in their own files
59
+
60
+ If a component needs props, create a dedicated prop file for it under `src/componentProps/...`.
61
+
62
+ Do not define the full prop contract inline inside the component unless it is truly private and temporary.
63
+
64
+ Good:
65
+
66
+ ```ts
67
+ export type ImageGridProps = {
68
+ images: GridImage[];
69
+ onImageClick?: (payload: ImageGridClickPayload) => void;
70
+ };
71
+ ```
72
+
73
+ ### 2. Keep UI components dumb
74
+
75
+ A UI component should mostly just render what it is given.
76
+
77
+ Good:
78
+
79
+ - render text, images, layout, and controls
80
+ - call `onClick`, `onChange`, `onSelect`, etc.
81
+
82
+ Bad:
83
+
84
+ - calling `fetch`
85
+ - importing routing logic
86
+ - mutating app-wide data
87
+ - logging app behavior from deep inside a presentational component unless it is only a temporary local debug step
88
+
89
+ ### 3. Pass behavior down, emit events up
90
+
91
+ The app layer, BFF simulation layer, or scene story should own behavior.
92
+
93
+ The deeper UI component should only emit a typed callback.
94
+
95
+ Example flow:
96
+
97
+ 1. story or scene owns the state
98
+ 2. scene passes callback props down
99
+ 3. item component calls the callback
100
+ 4. typed payload comes back up
101
+
102
+ ### 4. Use explicit callback names
103
+
104
+ Prefer clear names over generic handlers.
105
+
106
+ Good:
107
+
108
+ - `onCartClick`
109
+ - `onLoginClick`
110
+ - `onPromoClick`
111
+ - `onImageClick`
112
+ - `onCountrySelect`
113
+
114
+ Less preferred:
115
+
116
+ - `onAction`
117
+ - `onEvent`
118
+ - `handleThing`
119
+
120
+ ### 5. Do not use `any`
121
+
122
+ If a callback sends data upward, define a real payload type and export it.
123
+
124
+ Good:
125
+
126
+ ```ts
127
+ export type ImageGridClickPayload = {
128
+ image: GridImage;
129
+ index: number;
130
+ };
131
+ ```
132
+
133
+ ## Storybook Standards
134
+
135
+ ### Stories should use `.stories.js`
136
+
137
+ Use `.stories.js` files for Storybook stories in this repo.
138
+
139
+ ### Stories should use args
140
+
141
+ Prefer `args`-based stories and simple templates.
142
+
143
+ Avoid complex JSX-heavy story files unless there is a real need.
144
+
145
+ ### Stories must match the final prop contract
146
+
147
+ If the component props change, update the story right away.
148
+
149
+ Do not leave stale story args, controls, or fake props around.
150
+
151
+ ## Scene Stories
152
+
153
+ Scene stories are special.
154
+
155
+ They should act like a lightweight simulation of how the UI will behave when wired into a BFF or application layer.
156
+
157
+ That means scene stories should often own:
158
+
159
+ - selected values
160
+ - visible/hidden state
161
+ - click handlers
162
+ - change handlers
163
+ - log output for interaction testing
164
+
165
+ In other words: if a child component needs a callback to feel real, the scene story should usually provide it.
166
+
167
+ ## Generic Layout Containers
168
+
169
+ We now have a few reusable layout primitives:
170
+
171
+ - `ContentContainer`
172
+ - `ContentGrid`
173
+ - `FlowRow`
174
+
175
+ Use them when several components share the same layout pattern.
176
+
177
+ Examples:
178
+
179
+ - centered max-width wrappers
180
+ - responsive content grids
181
+ - rows of controls or logos with shared spacing
182
+
183
+ Do not force everything into one generic container.
184
+
185
+ A generic container is worth using when the shared part is structural:
186
+
187
+ - width
188
+ - spacing
189
+ - columns
190
+ - wrapping
191
+ - alignment
192
+
193
+ It is not the right tool when the component needs domain-specific rules.
194
+
195
+ ### Good use of a generic container
196
+
197
+ - `ImageGrid` using `ContentGrid`
198
+ - `DecorGrid` using `ContentGrid`
199
+
200
+ ### Bad use of a generic container
201
+
202
+ - a grid deciding what happens when a card is clicked
203
+ - a layout wrapper deciding navigation or selection logic
204
+
205
+ ## When To Use `ClickableCard`
206
+
207
+ Use `ClickableCard` when a whole card or large visual surface acts as one click target.
208
+
209
+ Examples:
210
+
211
+ - an image tile that opens detail
212
+ - a swatch card where clicking the image opens the decor
213
+
214
+ Do not use `ClickableCard` when only a normal CTA inside the card is interactive.
215
+
216
+ Examples:
217
+
218
+ - a card with a single "Learn More" button
219
+ - a card with a standard text link
220
+
221
+ ### Important rule
222
+
223
+ The component that owns the clickable surface should own `ClickableCard`.
224
+
225
+ Good:
226
+
227
+ - `SwatchCard` uses `ClickableCard`
228
+ - `ImageGrid` uses `ClickableCard` per image tile
229
+
230
+ Bad:
231
+
232
+ - `DecorGrid` wrapping every child in `ClickableCard`
233
+ - `ContentGrid` trying to handle clicks
234
+
235
+ ## Atomic Design Guidance
236
+
237
+ Try to keep responsibility at the right layer:
238
+
239
+ - atoms
240
+ simple UI pieces and layout primitives
241
+ - molecules
242
+ small composed patterns like `ClickableCard`
243
+ - organisms
244
+ richer composed sections like grids, navs, banners, panels
245
+ - scenes
246
+ higher-level composition and interaction simulation
247
+
248
+ If a primitive starts learning too much about a domain concept, it is probably in the wrong layer.
4
249
 
5
250
  ## Branching / Git Workflow
6
251
 
7
- ⚠️ **Direct commits to `main` are not allowed.** All work must be done in a feature branch created from `dev`.
252
+ Direct commits to `main` are not allowed.
8
253
 
9
- ### Create a feature branch from `dev`
254
+ Create feature branches from `dev`.
10
255
 
11
- 1. Checkout `dev` and pull the latest changes
12
- 2. Create a new feature branch named `feature/YourFeature`
256
+ ### Create a feature branch from `dev`
13
257
 
14
- **Commands:**
258
+ 1. Checkout `dev`
259
+ 2. Pull the latest changes
260
+ 3. Create a feature branch named `feature/YourFeature`
15
261
 
16
262
  ```bash
17
263
  git fetch
@@ -19,3 +265,17 @@ git checkout dev
19
265
  git pull
20
266
  git checkout -b feature/YourFeature
21
267
  ```
268
+
269
+ ## Final Advice For Junior Devs
270
+
271
+ If you are unsure where code should live, ask these questions:
272
+
273
+ 1. Is this layout or behavior?
274
+ 2. Does this component need to know app logic, or just render?
275
+ 3. Is this click target owned by the item, or by the container?
276
+ 4. Is this type reusable enough to belong in `componentProps`?
277
+ 5. Would this be easier to understand if the story owned the state instead?
278
+
279
+ If you stay strict about those five questions, your changes will usually fit the codebase well.
280
+
281
+ For the stricter rule set, examples, and review checklist, see [CONTRIBUTING.md](./CONTRIBUTING.md).
@@ -0,0 +1,8 @@
1
+ import React from "react";
2
+ export type ContentContainerMaxWidth = "sm" | "md" | "lg" | "xl" | "2xl" | "4xl" | "6xl";
3
+ export type ContentContainerProps = {
4
+ children?: React.ReactNode;
5
+ className?: string;
6
+ innerClassName?: string;
7
+ maxWidth?: ContentContainerMaxWidth;
8
+ };
@@ -0,0 +1,12 @@
1
+ import React from "react";
2
+ import type { ContentContainerMaxWidth } from "./ContentContainerProps";
3
+ export type ContentGridColumns = 1 | 2 | 3 | 4;
4
+ export type ContentGridGap = "sm" | "md" | "lg" | "xl";
5
+ export type ContentGridProps = {
6
+ children?: React.ReactNode;
7
+ className?: string;
8
+ gridClassName?: string;
9
+ maxWidth?: ContentContainerMaxWidth;
10
+ columns?: ContentGridColumns;
11
+ gap?: ContentGridGap;
12
+ };
@@ -0,0 +1,12 @@
1
+ import React from "react";
2
+ export type FlowRowGap = "sm" | "md" | "lg" | "xl";
3
+ export type FlowRowAlign = "start" | "center" | "end" | "stretch";
4
+ export type FlowRowJustify = "start" | "center" | "end" | "between" | "around" | "evenly";
5
+ export type FlowRowProps = {
6
+ children?: React.ReactNode;
7
+ className?: string;
8
+ gap?: FlowRowGap;
9
+ align?: FlowRowAlign;
10
+ justify?: FlowRowJustify;
11
+ wrap?: boolean;
12
+ };
@@ -0,0 +1,5 @@
1
+ import type { DropdownProps } from "../../../atoms/dropdown/DropdownProps";
2
+ export type DropdownFilterProps = {
3
+ dropdownProps: DropdownProps;
4
+ className?: string;
5
+ };
@@ -0,0 +1,5 @@
1
+ import type { ButtonProps } from "../../../atoms/buttons/button/ButtonProps";
2
+ export type FilterBarButtonProps = {
3
+ buttonProps: ButtonProps;
4
+ className?: string;
5
+ };
@@ -0,0 +1,6 @@
1
+ import React from "react";
2
+ export type FilterBarProps = {
3
+ children?: React.ReactNode;
4
+ className?: string;
5
+ barClassName?: string;
6
+ };
@@ -0,0 +1,5 @@
1
+ import type { SearchBarProps } from "../../searchbar/SearchBarProps";
2
+ export type SearchFilterProps = {
3
+ searchBarProps: SearchBarProps;
4
+ className?: string;
5
+ };
@@ -4,6 +4,11 @@ export type GridImage = Omit<React.ImgHTMLAttributes<HTMLImageElement>, "src" |
4
4
  alt: string;
5
5
  quality: number;
6
6
  };
7
+ export type ImageGridClickPayload = {
8
+ image: GridImage;
9
+ index: number;
10
+ };
7
11
  export interface ImageGridProps {
8
12
  images: GridImage[];
13
+ onImageClick?: (payload: ImageGridClickPayload) => void;
9
14
  }
@@ -1,12 +1,18 @@
1
1
  import type { StandardCopyHeroProps } from "../../organisms/banner/standardcopyhero/StandardCopyHeroProps";
2
2
  import type { MultiButtonBarProps } from "../../molecules/selectors/multibuttonbar/MultiButtonBarProps";
3
- import type { SortAndFilterBarProps } from "../../molecules/selectors/sortandfilterbar/SortAndFilterBarProps";
3
+ import type { FilterBarProps } from "../../molecules/selectors/filterbar/FilterBarProps";
4
+ import type { FilterBarButtonProps } from "../../molecules/selectors/filterbar/FilterBarButtonProps";
5
+ import type { DropdownFilterProps } from "../../molecules/selectors/filterbar/DropdownFilterProps";
6
+ import type { SearchFilterProps } from "../../molecules/selectors/filterbar/SearchFilterProps";
4
7
  import type { DecorGridProps } from "../../organisms/decorgrid/DecorGridProps";
5
8
  import type { VerticalCheckboxListCollectionProps } from "../../organisms/verticalcheckboxlistcollection/VerticalCheckboxListCollectionProps";
6
9
  export type CategorySceneProps = {
7
10
  standardCopyHeroProps: StandardCopyHeroProps;
8
11
  multiButtonBarProps: MultiButtonBarProps;
9
- sortAndSearchBarProps: SortAndFilterBarProps;
12
+ filterBarProps: FilterBarProps;
13
+ filterToggleButtonProps: FilterBarButtonProps;
14
+ sortDropdownFilterProps: DropdownFilterProps;
15
+ searchFilterProps: SearchFilterProps;
10
16
  verticalCheckboxListCollectionProps?: VerticalCheckboxListCollectionProps;
11
17
  decorGridProps: DecorGridProps;
12
18
  };
@@ -1,10 +1,12 @@
1
1
  import type { StandardCopyHeroProps } from "../../organisms/banner/standardcopyhero/StandardCopyHeroProps";
2
2
  import type { MultiButtonBarProps } from "../../molecules/selectors/multibuttonbar/MultiButtonBarProps";
3
- import type { TripleDropdownBarProps } from "../../molecules/selectors/tripledropdownbar/TripleDropdownBarProps";
3
+ import type { FilterBarProps } from "../../molecules/selectors/filterbar/FilterBarProps";
4
+ import type { DropdownFilterProps } from "../../molecules/selectors/filterbar/DropdownFilterProps";
4
5
  import type { ImageGridProps } from "../../organisms/imagegrid/ImageGridProps";
5
6
  export type GallerySceneProps = {
6
7
  standardCopyHeroProps: StandardCopyHeroProps;
7
8
  multiButtonBarProps: MultiButtonBarProps;
8
- tripleDropdownBarProps: TripleDropdownBarProps;
9
+ filterBarProps: FilterBarProps;
10
+ dropdownFilterPropsList: DropdownFilterProps[];
9
11
  imageGridProps: ImageGridProps;
10
12
  };