@7shifts/sous-chef 4.4.1 → 4.5.0
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.
- package/dist/forms/ColorField/ColorOverlay/ColorOverlay.d.ts +1 -1
- package/dist/forms/ColorField/ColorOverlay/domain.d.ts +27 -0
- package/dist/foundation/tokens/color/color-constants.d.ts +23 -0
- package/dist/foundation/tokens/color/color-types.d.ts +1 -1
- package/dist/icons/components/image/IconSchool.d.ts +10 -0
- package/dist/icons/components/image/index.d.ts +1 -0
- package/dist/index.css +69 -139
- package/dist/index.css.map +1 -1
- package/dist/index.js +542 -362
- package/dist/index.js.map +1 -1
- package/dist/index.modern.js +534 -363
- package/dist/index.modern.js.map +1 -1
- package/dist/overlay/DropdownListItem/DropdownListItem.d.ts +3 -1
- package/dist/overlay/hooks/useSubmenu.d.ts +1 -0
- package/llms-instructions/guidelines/Accordion.guidelines.md +36 -0
- package/llms-instructions/guidelines/ActionList.guidelines.md +59 -0
- package/llms-instructions/guidelines/Avatar.guidelines.md +51 -0
- package/llms-instructions/guidelines/Badge.guidelines.md +40 -0
- package/llms-instructions/guidelines/Breadcrumbs.guidelines.md +41 -0
- package/llms-instructions/guidelines/Button.guidelines.md +41 -0
- package/llms-instructions/guidelines/Calendar.guidelines.md +40 -0
- package/llms-instructions/guidelines/Card.guidelines.md +58 -0
- package/llms-instructions/guidelines/Chip.guidelines.md +64 -0
- package/llms-instructions/guidelines/CircularProgress.guidelines.md +28 -0
- package/llms-instructions/guidelines/DataTable.guidelines.md +88 -0
- package/llms-instructions/guidelines/DateFilter.guidelines.md +32 -0
- package/llms-instructions/guidelines/Dropdown.guidelines.md +54 -0
- package/llms-instructions/guidelines/EmptyState.guidelines.md +58 -0
- package/llms-instructions/guidelines/Forms.guidelines.md +99 -0
- package/llms-instructions/guidelines/HintModal.guidelines.md +47 -0
- package/llms-instructions/guidelines/Icons.guidelines.md +59 -0
- package/llms-instructions/guidelines/InkIllustrations.guidelines.md +38 -0
- package/llms-instructions/guidelines/InlineBanner.guidelines.md +52 -0
- package/llms-instructions/guidelines/Link.guidelines.md +26 -0
- package/llms-instructions/guidelines/MicroBanner.guidelines.md +21 -0
- package/llms-instructions/guidelines/Modal.guidelines.md +52 -0
- package/llms-instructions/guidelines/PaginationControls.guidelines.md +21 -0
- package/llms-instructions/guidelines/Paywall.guidelines.md +57 -0
- package/llms-instructions/guidelines/PersistentBanner.guidelines.md +33 -0
- package/llms-instructions/guidelines/Pill.guidelines.md +55 -0
- package/llms-instructions/guidelines/Popover.guidelines.md +42 -0
- package/llms-instructions/guidelines/ProgressBar.guidelines.md +35 -0
- package/llms-instructions/guidelines/SegmentedControl.guidelines.md +21 -0
- package/llms-instructions/guidelines/Skeleton.guidelines.md +30 -0
- package/llms-instructions/guidelines/Spinner.guidelines.md +32 -0
- package/llms-instructions/guidelines/Toast.guidelines.md +34 -0
- package/llms-instructions/guidelines/Toggle.guidelines.md +19 -0
- package/llms-instructions/guidelines/ToolbarSelect.guidelines.md +22 -0
- package/llms-instructions/guidelines/Tooltip.guidelines.md +45 -0
- package/llms-instructions/llms-components.md +61 -261
- package/llms-instructions/llms-icons-and-illustrations.md +2 -0
- package/llms-instructions/llms-tokens.md +97 -16
- package/package.json +6 -1
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
<!-- AUTO-GENERATED by scripts/build-llms-guidelines.js. Do not edit manually. Run `yarn build-llms-guidelines` to regenerate. -->
|
|
2
|
+
|
|
3
|
+
## When to Use
|
|
4
|
+
|
|
5
|
+
- For contextual action menus — a set of actions tied to a specific item or element
|
|
6
|
+
- When multiple related controls need to be grouped behind a single trigger to save space
|
|
7
|
+
- For secondary navigation or settings that don't warrant permanent placement in the UI
|
|
8
|
+
- When the options are a simple list — labels, icons, or selectable items
|
|
9
|
+
|
|
10
|
+
## When Not to Use
|
|
11
|
+
|
|
12
|
+
- When the content inside needs to be a form, rich content, or more than a list of actions — use `Popover` instead
|
|
13
|
+
- When only one action is available — surface it as a `Button` directly
|
|
14
|
+
- For primary navigation or actions the user needs to discover — dropdown content is hidden and easy to miss
|
|
15
|
+
- When the user needs to compare options with supporting detail — consider a dedicated UI surface instead
|
|
16
|
+
|
|
17
|
+
## Usage
|
|
18
|
+
|
|
19
|
+
### Trigger
|
|
20
|
+
|
|
21
|
+
- The trigger is any interactive element — typically a button or icon — that the user clicks to open the menu.
|
|
22
|
+
- Dropdowns default to opening on click (`triggersOn="click"`), which is the recommended setting.
|
|
23
|
+
- Hover (`triggersOn="hover"`) is available but should be used sparingly — hover menus are harder to use on touch devices and can feel surprising. Prefer click unless there's a strong reason for hover.
|
|
24
|
+
|
|
25
|
+
### Submenus
|
|
26
|
+
|
|
27
|
+
- Dropdowns can have Submenus which fly off to the right or left of the main Dropdown.
|
|
28
|
+
- Use these to nest different options within a single menu item - For example choosing a flag to apply from a list, or choosing an optional theme (Light mode, Dark mode)
|
|
29
|
+
- You can trigger a Submenu from a Submenu, however try to avoid this whenever possible.
|
|
30
|
+
- Use `IconChevronRight` in the suffix to indicate a Submenu will trigger off this menu item.
|
|
31
|
+
|
|
32
|
+
### Alignment
|
|
33
|
+
|
|
34
|
+
- The dropdown panel aligns to the trigger by default.
|
|
35
|
+
- Use `alignment` to control whether the panel opens left or right of the trigger when needed to avoid overflow.
|
|
36
|
+
|
|
37
|
+
### Dividers
|
|
38
|
+
|
|
39
|
+
Use `DropdownListDivider` to group related items visually. A divider between destructive actions (like Delete) and the rest of the list is a common and useful pattern.
|
|
40
|
+
|
|
41
|
+
## Tips & Tricks
|
|
42
|
+
|
|
43
|
+
- Keep dropdown lists short and scannable. If a menu has more than 6–8 items, consider grouping with dividers or rethinking the information architecture.
|
|
44
|
+
- Lead with the most commonly used actions. Users scan from the top — don't bury "Edit" below five less-frequent options.
|
|
45
|
+
- Destructive actions like Delete should always sit at the bottom of the list, separated by a divider, and use a danger theme to signal their weight.
|
|
46
|
+
- Avoid putting form fields or multi-step interactions inside a Dropdown. If you need that, use a `Popover`.
|
|
47
|
+
- Icons in list items help scannability, but aren't required. If you use icons, be consistent across the whole list — mixing icon and non-icon items looks unbalanced.
|
|
48
|
+
|
|
49
|
+
## Additional Rules
|
|
50
|
+
|
|
51
|
+
- `trigger` is required and must accept a forwarded ref.
|
|
52
|
+
- Prefer `triggersOn="click"` over `triggersOn="hover"` — the hover variant is flagged as a non-preferred option in the component API.
|
|
53
|
+
- `DropdownList` is required as the direct child of `Dropdown` to correctly apply list styles and spacing.
|
|
54
|
+
- `triggerWidth="full"` stretches the panel to match the full trigger width — useful for select-style dropdowns.
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
<!-- AUTO-GENERATED by scripts/build-llms-guidelines.js. Do not edit manually. Run `yarn build-llms-guidelines` to regenerate. -->
|
|
2
|
+
|
|
3
|
+
## When to Use
|
|
4
|
+
|
|
5
|
+
- When a page or section has no data to display and the user needs context and a next step
|
|
6
|
+
- For first-time experiences where a feature has not yet been set up
|
|
7
|
+
- When a user doesn't have access to content in a given section
|
|
8
|
+
- When an error occurred within a page or section
|
|
9
|
+
- User cleared: Occurs when a user has successfully completed an action like clearing their inbox or task list, and there is nothing left to show
|
|
10
|
+
|
|
11
|
+
## When Not to Use
|
|
12
|
+
|
|
13
|
+
- When content is loading — use a skeleton or loading state instead
|
|
14
|
+
- When the absence of content is expected and unremarkable — don't force an empty state where a blank area is sufficient
|
|
15
|
+
- When a page is locked behind a paywall — use `Paywall` instead
|
|
16
|
+
|
|
17
|
+
## Usage
|
|
18
|
+
|
|
19
|
+
### Small Small should be used either when only a portion of the content on a page
|
|
20
|
+
|
|
21
|
+
isn't shown or when a sub-feature on a page isn't shown.{' '}
|
|
22
|
+
|
|
23
|
+
### Medium
|
|
24
|
+
|
|
25
|
+
Also known as horizontal empty states. Used inline either when only a portion of the content on a page isn't shown or when a sub-feature on a page isn't shown. They differ from Small in that they provide the user more context to the empty state and they have some kind of call-to-action.
|
|
26
|
+
|
|
27
|
+
### large
|
|
28
|
+
|
|
29
|
+
Also known as the Full Page empty states. Used when an entire page isn't available.
|
|
30
|
+
|
|
31
|
+
### As a Card
|
|
32
|
+
|
|
33
|
+
Use `as="card"` with `size="medium"` when the empty state needs to sit within a card container. Pass `onClose` to let the user dismiss it.
|
|
34
|
+
|
|
35
|
+
### Images
|
|
36
|
+
|
|
37
|
+
- The image should use our Bento image format.
|
|
38
|
+
- Large empty states can use either a single frame bento, or a multi-frame collage
|
|
39
|
+
- Medium and small empty states should use a single frame bento
|
|
40
|
+
- Bentos frames can contain an Inking illustration, a lifestyle photo or UI mockup
|
|
41
|
+
|
|
42
|
+
### Copy Best Practices
|
|
43
|
+
|
|
44
|
+
- Write in sentence case, with the usual exceptions of proper nouns such as a person, feature name, location, etc., being title case
|
|
45
|
+
- Use as few words as possible in the title and description. Be direct and clear.
|
|
46
|
+
- Avoid repeating content from the title in the body. Say things once with intent
|
|
47
|
+
- Avoid technical terms or jargon. Communicate using common words
|
|
48
|
+
- Always choose a simpler shorter words over longer fancier words
|
|
49
|
+
- The title should communicate the message fully if possible, users are more likely to read this
|
|
50
|
+
- The body/description should be used to provide further important details or next steps
|
|
51
|
+
- caption appears below the action buttons — use it for secondary guidance or legal-style caveats, not as a substitute for body text.
|
|
52
|
+
|
|
53
|
+
## Additional Rules
|
|
54
|
+
|
|
55
|
+
- `title` is required. All other props are optional.
|
|
56
|
+
- `as` defaults to `"banner"`. Pass `as="card"` explicitly when the empty state should render inside a `Card` wrapper.
|
|
57
|
+
- `onClose` is only valid when `as="card"`. Passing it in banner mode has no effect.
|
|
58
|
+
- `mediaUrl` expects a path to an image or gif. Use paths relative to the Storybook static directory (e.g. `"images/EmptyState.png"`) or absolute URLs.
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
<!-- AUTO-GENERATED by scripts/build-llms-guidelines.js. Do not edit manually. Run `yarn build-llms-guidelines` to regenerate. -->
|
|
2
|
+
|
|
3
|
+
## When to Use
|
|
4
|
+
|
|
5
|
+
- Any time you need to collect information from the user using field components
|
|
6
|
+
- When a group of fields belongs together as a single unit of input (creating a shift, editing a profile, configuring a setting)
|
|
7
|
+
- When fields need a consistent layout, spacing, and validation model
|
|
8
|
+
|
|
9
|
+
## When Not to Use
|
|
10
|
+
|
|
11
|
+
- When the user is making a selection rather than entering data — use a standalone `Select`, `Toggle`, or `SegmentedControl` instead
|
|
12
|
+
- When a single inline action is needed — avoid wrapping isolated controls in a Form just for layout
|
|
13
|
+
- When there is no submission of information from the user being written by the system
|
|
14
|
+
|
|
15
|
+
## Usage
|
|
16
|
+
|
|
17
|
+
### Anatomy
|
|
18
|
+
|
|
19
|
+
Forms are comprised of the following components:
|
|
20
|
+
|
|
21
|
+
- `Form` - The wrapper that the entire form sits in
|
|
22
|
+
- `FormSection` - A visual grouping of fields within a form that can have a title and subtitle
|
|
23
|
+
- `FormRow` - A horizontal row of up to 4 fields
|
|
24
|
+
- `FormFooter` Contains the CTA buttons that control the entire form
|
|
25
|
+
- `FormField` An individual field in a form
|
|
26
|
+
|
|
27
|
+

|
|
28
|
+
|
|
29
|
+
### Form Widths
|
|
30
|
+
|
|
31
|
+
- Forms have a default width of 500px, but you may override this if your design requires it. This should be done as a necessity, not as an aesthetic choice.
|
|
32
|
+
- A form field’s width includes all elements within the field (i.e. label, caption, error, and the input itself).
|
|
33
|
+
- To override the default width, pass the `wide` prop to `<Form />` to remove this constraint when the layout requires it.
|
|
34
|
+
|
|
35
|
+
### Form rows
|
|
36
|
+
|
|
37
|
+
- Form rows support up to four fields per row. Each field's width can be set to 25%, 33%, 50%, 66%, or 75% — sizes across the row must add up to 100% or less.
|
|
38
|
+
- If no sizes are specified, the fields will split the width equally.
|
|
39
|
+
- All rows in a form have 20px vertical spacing between them. Fields within a FormRow have 20px horizontal spacing. Both are built in.
|
|
40
|
+
- Use `<FormRow />` whenever you have multiple fields in a single row, or when a single field needs to be narrower than the full form width (e.g. ~240px to match an adjacent row).
|
|
41
|
+
- `<FormRow />` is not needed for a single field that can fill the full form width.
|
|
42
|
+
- `<FormRow />` always lives within a `<Form />`. Its width is determined by its parent — typically the Form's 500px.
|
|
43
|
+
- Use the columns prop on FormRow (1–4) when fields in a row need to align with another row that has a different number of fields.
|
|
44
|
+
- `<FormRow />` without a `<Form />` parent will grow to fill its container — always nest it inside a Form.
|
|
45
|
+
|
|
46
|
+
### Submission and Validation
|
|
47
|
+
|
|
48
|
+
- Typically speaking, each form uses a single submit button to complete. This uses our standard `button` component.
|
|
49
|
+
- The primary CTA Button is disabled while required fields are incomplete. A field doesn't need to be valid to enable it — just attempted (i.e. the user has interacted with it).
|
|
50
|
+
- Field error states trigger after the user interacts with a field and leaves it in an invalid state. They do not show on initial load.
|
|
51
|
+
- Example: a required field is empty, the user clicks into it and then moves focus away while it's still empty → error state triggers.
|
|
52
|
+
- Form buttons have a built-in minimum width of 100px.
|
|
53
|
+
|
|
54
|
+
### Organizing Fields
|
|
55
|
+
|
|
56
|
+
- Use the Gestalt Principles to guide how you group and order fields — proximity, similarity, and continuation all apply.
|
|
57
|
+
- Aim for a scannable layout. Users should be able to find what they need quickly.
|
|
58
|
+
- Field width should reflect the expected length of the value it holds — a short code field shouldn't span the full form width.
|
|
59
|
+
- Group fields that are directly related (e.g. start date and end date) in the same row.
|
|
60
|
+
- When you have repeating rows of the same field type, the column header can appear only on the top row if the fields are self-explanatory in context (e.g. break rows in the Add Shift modal).
|
|
61
|
+
|
|
62
|
+
### Copy
|
|
63
|
+
|
|
64
|
+
- Use sentence case for all labels, captions, and placeholder text. Proper nouns (people, feature names, locations) use title case.
|
|
65
|
+
- Set smart default values when reasonable expectations are known and the cost of being wrong is low (e.g. pre-selecting the day based on the cell that was clicked).
|
|
66
|
+
- Use placeholder text as a helpful example — not as a label substitute or instruction.
|
|
67
|
+
- Don't put "(required)" or "(optional)" signifiers inside placeholder text — put them in the label instead.
|
|
68
|
+
|
|
69
|
+
### Required vs. Optional Fields
|
|
70
|
+
|
|
71
|
+
Because forms often have many required and many optional fields, marking every field would be overwhelming. Use your judgment:
|
|
72
|
+
|
|
73
|
+
- If most fields are required and there are one or two optional outliers, label just the optional ones with "(optional)".
|
|
74
|
+
- If most fields are optional and there are one or two required outliers, label just the required ones with "(required)".
|
|
75
|
+
- Use lowercase for both.
|
|
76
|
+
|
|
77
|
+
### Field Types
|
|
78
|
+
|
|
79
|
+
| Field | Use |
|
|
80
|
+
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
81
|
+
| `AsyncSelectField` | A variation of select field that loads a dynamic list of options from a source rather than a fixed set of options. Use when you need to select from a dynamic list that can change such as roles, employees, locations, etc. |
|
|
82
|
+
| `CheckboxField` | A simple check box with an option beside it. Allows the user to confirm a statement or enable an option with a simple boolean action. Use for things like agreeing to terms, or enabling one or more options in a list (where multiple selections are allowed). |
|
|
83
|
+
| `ColorField` | A dropdown style field that lets the user choose one color token from our sequential colour palette. Use for things like choosing a role color. |
|
|
84
|
+
| `CurrencyField` | A variation of a TextField, but it only accepts numbers, and will auto format the number into a currency format when the user leaves the field. Use anytime the user must enter a currency value and nothing else. |
|
|
85
|
+
| `DateField` | A dropdown style field for selecting a single specific date. It will load a calendar widget when activated allowing the user to find and pick a day. |
|
|
86
|
+
| `DateRangeField` | A dropdown style field with 2 inputs. It allows the user to select a specific start date and end date separately to create a range of dates. |
|
|
87
|
+
| `MultiSelectField` | A dropdown style field that lets you select and input more than one option within the field. Uses removable chips to represent selected items. |
|
|
88
|
+
| `NumberField` | A special text input field that only accepts numbers. It has validation and formatting in place to properly display number values. In its default state it only allows whole numbers, but it can be configured to allow decimals and negative values. |
|
|
89
|
+
| `PasswordField` | A field used for passwords. It obfuscates the input by default, but has the option to reveal the input. Can also include required password criteria. |
|
|
90
|
+
| `PercentageField` | A special text input field that only accepts numbers. Comes with validation and formatting in place to properly display percentage values. In its default state it only allows integers between 0 and 100, but it can be configured to allow decimals and negative values. |
|
|
91
|
+
| `PhoneField` | A field for entering phone numbers. It includes a selection field for country code and can validate phone numbers. |
|
|
92
|
+
| `PillSelectField` | A field where the user can select one or more from a vertical line of pills. Can also be made fully reactive allowing users to add and delete their own options. Use this to select from a more visual list with a limited number of options, like selecting the day of the week. |
|
|
93
|
+
| `RadioGroupField` | A list of radio options appearing either as an input or box. Use when the user can only select one option from a visual list and the user needs to be able to see all the options to make an informed decision. |
|
|
94
|
+
| `SelectField` | Simple dropdown field where the user chooses one option from a set list. |
|
|
95
|
+
| `TextAreaField` | A taller input field used to get long form text from the user. Has options to add a toolbar, character counter and character limit. Use when the input is expected to be longer than a single line. |
|
|
96
|
+
| `TextField` | A basic open input field used to get text from the user, with options to add a prefix or suffix element if necessary. Accepts any characters, so do not use if you want to limit the format of the input to numbers only. |
|
|
97
|
+
| `TimeField` | A special field designed for selecting a specific time of the day. Users can choose from a dropdown of preset time intervals, or type directly into the field. When the user leaves the field, the input is automatically formatted into either AM/PM time or 24h time. |
|
|
98
|
+
| `TimeRangeField` | A special input field for selecting a time range. Comprised of 2 individual time fields, the user selects a start time and an end time individually. |
|
|
99
|
+
| `WeekField` | A special dropdown style field used to select a single week from a calendar widget. Selections must always be 7 consecutive days, but you may customize the day of the week the selectable range starts on. |
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
<!-- AUTO-GENERATED by scripts/build-llms-guidelines.js. Do not edit manually. Run `yarn build-llms-guidelines` to regenerate. -->
|
|
2
|
+
|
|
3
|
+
## When to Use
|
|
4
|
+
|
|
5
|
+
- To introduce a new feature or page the first time a user encounters it
|
|
6
|
+
- When proactive guidance would meaningfully reduce confusion or friction
|
|
7
|
+
- For short onboarding tips that are helpful once but don't need to repeat on every visit
|
|
8
|
+
- When a media asset (image, illustration) helps communicate the tip more clearly
|
|
9
|
+
|
|
10
|
+
## When Not to Use
|
|
11
|
+
|
|
12
|
+
- As a replacement for a regular `Modal` when a decision or action is required from the user — Hint Modal is guidance-only
|
|
13
|
+
- For critical information the user must act on — use a `Modal` or `InlineBanner` instead
|
|
14
|
+
- For tips that are always relevant — if the content is useful every visit, surface it persistently in the UI rather than in an overlay
|
|
15
|
+
- Repeatedly on the same page — if users keep seeing it, the "Don't show again" mechanism isn't working or the feature needs better in-context documentation
|
|
16
|
+
|
|
17
|
+
## Usage
|
|
18
|
+
|
|
19
|
+
### Triggering
|
|
20
|
+
|
|
21
|
+
Hint Modal is not wired to a button click. Render it conditionally when the user lands on the relevant page — it will manage its own visibility using local storage, keyed to the `modalId` you provide. If the user has previously checked "Don't show this again", the component will not render.
|
|
22
|
+
|
|
23
|
+
### Content
|
|
24
|
+
|
|
25
|
+
Keep the header short and direct — name the feature or the thing the user is looking at. The body should explain what it does and why it's useful, in plain language. One or two short paragraphs is the right length.
|
|
26
|
+
|
|
27
|
+
### Media
|
|
28
|
+
|
|
29
|
+
An optional `mediaUrl` adds an image above the content area — useful for showing a screenshot, illustration, or short animation that makes the tip concrete. Use real product imagery where possible rather than generic illustrations.
|
|
30
|
+
|
|
31
|
+
### Actions
|
|
32
|
+
|
|
33
|
+
A `primaryButton` is required — typically a "Got it" button that closes the modal. An optional `secondaryButton` can be used for a secondary action like linking to a help article. Keep the primary action label affirming and simple.
|
|
34
|
+
|
|
35
|
+
## Tips & Tricks
|
|
36
|
+
|
|
37
|
+
- The "Don't show this again" checkbox is built in — don't add your own dismiss mechanism. Trust the component to handle repeat visits.
|
|
38
|
+
- If your tip needs more than a short paragraph to explain, the feature probably needs better in-product documentation rather than a longer modal.
|
|
39
|
+
- Hint Modals work best for genuinely new things. Using them for features that have been in the product a long time feels out of place and will be dismissed quickly.
|
|
40
|
+
- Pair with a meaningful `mediaUrl` when you have one — a screenshot or annotated image dramatically increases how much information a user absorbs at a glance.
|
|
41
|
+
|
|
42
|
+
## Additional Rules
|
|
43
|
+
|
|
44
|
+
- `modalId` is required and must be unique per hint — it is used as the local storage key to track "Don't show again" state.
|
|
45
|
+
- `primaryButton` is required. Pass a `Button` element — the component does not render default actions on its own.
|
|
46
|
+
- Visibility is partially managed internally via local storage. Once a user checks "Don't show again", the modal will not render again for that `modalId` unless the key is cleared.
|
|
47
|
+
- `onSetDoNotShowAgainStatus` fires when the checkbox state changes, if you need to sync this externally.
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
<!-- AUTO-GENERATED by scripts/build-llms-guidelines.js. Do not edit manually. Run `yarn build-llms-guidelines` to regenerate. -->
|
|
2
|
+
|
|
3
|
+
## When to Use
|
|
4
|
+
|
|
5
|
+
- Alongside a label to reinforce meaning and aid scannability — a save icon next to "Save changes", a warning icon next to an error message
|
|
6
|
+
- As the sole content of an icon button when the action is well-established and space is tight — always pair with a `Tooltip` in this case
|
|
7
|
+
- To communicate status at a glance in a list or table row — a status icon can convey meaning faster than text alone
|
|
8
|
+
- In navigation items, section headers, or feature names where a visual anchor helps users orient quickly
|
|
9
|
+
|
|
10
|
+
## When Not to Use
|
|
11
|
+
|
|
12
|
+
- As a standalone element without a label or tooltip — icons are rarely self-explanatory enough to stand alone, especially for new or infrequent users
|
|
13
|
+
- As decoration or expressive visual element with no functional meaning — use an `InkIllustration` for empty states, onboarding moments, or anywhere illustration-quality imagery is appropriate
|
|
14
|
+
|
|
15
|
+
## Usage
|
|
16
|
+
|
|
17
|
+
### Sourcing Icons
|
|
18
|
+
|
|
19
|
+
- We use `Font Awesome` from the `Classic` family which can be found on fontawesome.com
|
|
20
|
+
- For `outline` use the `Classic Light`
|
|
21
|
+
- For `solid` use `Classic Solid`
|
|
22
|
+
- If using a new icon that doesn't exist in the current Sous Chef library, send a message in the #sous-chef channel and the Design Systems team can add it to Sous Chef
|
|
23
|
+
|
|
24
|
+
### Variants
|
|
25
|
+
|
|
26
|
+
Each icon comes in two variants: `outline` (default) and `solid`. Outline is the standard choice for most UI contexts. Solid is used to communicate a selected, active, or filled state. Solid may also be used selectively as a visual choice when extra contrast is needed, but this should be done sparingly and with care.
|
|
27
|
+
|
|
28
|
+
### Sizes
|
|
29
|
+
|
|
30
|
+
| Size | Dimensions |
|
|
31
|
+
| --------- | ---------- |
|
|
32
|
+
| `small` | 12×12px |
|
|
33
|
+
| `medium` | 16×16px |
|
|
34
|
+
| `default` | 20×20px |
|
|
35
|
+
| `large` | 24×24px |
|
|
36
|
+
|
|
37
|
+
`default` is the standard for most UI contexts. Use `small` for dense layouts like table cells or compact toolbars. `flexible` removes the fixed width and height entirely, letting you control the size through CSS — useful in edge cases where none of the named sizes fit the surrounding layout.
|
|
38
|
+
|
|
39
|
+

|
|
40
|
+
|
|
41
|
+
When an icon is placed inside a `Button`, its size is automatically set to `medium` — you don't need to specify it.
|
|
42
|
+
|
|
43
|
+
### Colour
|
|
44
|
+
|
|
45
|
+
By default, icons inherit the colour of their surrounding text. Pass a `color` prop to override this when the icon needs to carry its own colour — for example, a red warning icon or a green success indicator.
|
|
46
|
+
|
|
47
|
+
## Tips & Tricks
|
|
48
|
+
|
|
49
|
+
- When using an icon-only button, always add a `Tooltip` so keyboard and mouse users can discover what the button does. An icon without a label is an assumption about what users already know.
|
|
50
|
+
- When using a stand alone icon as an interactive control, place the icon inside a `button` component. Do not use it as a raw icon. This will ensure it has the correct hit box, hover, active and disabled states.
|
|
51
|
+
- If you're not finding the icon you need, search by concept rather than exact name. "Arrow right" might be called `IconChevronRight` or `IconArrowRight` depending on the style.
|
|
52
|
+
|
|
53
|
+
## Additional Rules
|
|
54
|
+
|
|
55
|
+
- All icon components accept `size`, `variant`, `color`, and `testId` props.
|
|
56
|
+
- `variant` defaults to `'outline'` if not specified.
|
|
57
|
+
- `size` defaults to `'default'` (20×20px) if not specified.
|
|
58
|
+
- When used inside a `Button`, icon `size` is automatically overridden to `'medium'` — passing a different size inside a button will have no effect.
|
|
59
|
+
- `size="flexible"` renders with no `width` or `height` attributes — size must be controlled entirely via CSS.
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
<!-- AUTO-GENERATED by scripts/build-llms-guidelines.js. Do not edit manually. Run `yarn build-llms-guidelines` to regenerate. -->
|
|
2
|
+
|
|
3
|
+
## When to Use
|
|
4
|
+
|
|
5
|
+
- In empty states, when a page or list has no content yet — an illustration softens the experience and gives users a sense of what the space is for
|
|
6
|
+
- In onboarding flows, tooltips, or hint modals where a visual makes a concept easier to grasp
|
|
7
|
+
- On confirmation or success screens where a moment of delight is appropriate
|
|
8
|
+
- As supporting imagery in marketing or promotional content within the product
|
|
9
|
+
|
|
10
|
+
## When Not to Use
|
|
11
|
+
|
|
12
|
+
- As a substitute for a functional icon — use the icon library for UI controls, status indicators, and interface actions
|
|
13
|
+
- In dense, data-heavy interfaces where space is at a premium and illustrations compete with content
|
|
14
|
+
- When the illustration doesn't clearly relate to the surrounding content — an unrelated illustration creates confusion rather than delight
|
|
15
|
+
- Repeatedly on the same screen — one illustration per view is almost always the right amount
|
|
16
|
+
|
|
17
|
+
## Usage
|
|
18
|
+
|
|
19
|
+
### Sizing
|
|
20
|
+
|
|
21
|
+
Unlike icons, illustration size is set as a CSS value string — for example `"100px"`, `"200px"`, or a responsive value like `"100%"`. There are no named size tokens. Choose a size that gives the illustration enough presence without overwhelming the surrounding layout. In empty states, something in the range of 80–150px typically works well.
|
|
22
|
+
|
|
23
|
+
### Colour
|
|
24
|
+
|
|
25
|
+
Ink Illustrations are fixed illustrations — they are not colour-customisable. They are designed to work across both light and dark contexts and should be used as-is. Standard illustrations use a single neutral colour token. Custom illustrations are special branded illustrations that use more than one colour. These often have several variations with different colour treatments you can choose from.
|
|
26
|
+
|
|
27
|
+
## Tips & Tricks
|
|
28
|
+
|
|
29
|
+
- Empty states are the most common use case. A well-chosen illustration paired with a clear heading and a call-to-action ("Add your first employee") transforms a dead end into an invitation.
|
|
30
|
+
- People and hands illustrations work well for onboarding and educational moments — they feel approachable and human without being overly literal.
|
|
31
|
+
- Don't stretch illustrations with mismatched aspect ratios. Set either width or height and let the other dimension scale naturally.
|
|
32
|
+
- When pairing an illustration with text in an empty state, centre both horizontally and keep the text concise. The illustration draws the eye — the text closes the loop.
|
|
33
|
+
|
|
34
|
+
## Additional Rules
|
|
35
|
+
|
|
36
|
+
- Each illustration is a standalone React component — import and use it directly, no wrapper component required.
|
|
37
|
+
- `size` accepts any valid CSS dimension string and defaults to `'100px'` if not provided.
|
|
38
|
+
- Illustrations are not interactive and do not accept event handlers.
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
<!-- AUTO-GENERATED by scripts/build-llms-guidelines.js. Do not edit manually. Run `yarn build-llms-guidelines` to regenerate. -->
|
|
2
|
+
|
|
3
|
+
## When to Use
|
|
4
|
+
|
|
5
|
+
- To surface information, warnings, errors, or success states that are directly relevant to the content on the current page
|
|
6
|
+
- When the message should remain visible until the user dismisses it or the condition resolves
|
|
7
|
+
- When a CTA is needed alongside the message — upgrading a plan, resolving an issue, taking an action
|
|
8
|
+
|
|
9
|
+
## When Not to Use
|
|
10
|
+
|
|
11
|
+
- For brief confirmations of completed actions — use `Toast` instead
|
|
12
|
+
- For app-wide or top-of-page announcements — use `PersistentBanner` instead
|
|
13
|
+
- For compact, space-constrained contexts — use `MicroBanner` instead
|
|
14
|
+
- For inline form field validation errors — show errors on the field itself instead
|
|
15
|
+
- Do not use banners as primary entry points to a flow or to communicate actions a user needs to complete on a regular basis.
|
|
16
|
+
- Avoid multiple banners on a page if possible. More than one banner dilutes their ability to draw attention and is disruptive to the user flow.
|
|
17
|
+
|
|
18
|
+
## Usage
|
|
19
|
+
|
|
20
|
+
- Banners are naturally interruptive, but keep in mind their level of interruption should match the priority of the message they contain.
|
|
21
|
+
- Avoid more than one banner on screen at a time
|
|
22
|
+
- Add a title when the message needs a headline — this switches the banner to a multi-line layout
|
|
23
|
+
- Without a title, the banner renders as a compact single-line layout
|
|
24
|
+
- If the message is critical, do not let the user dismiss it.
|
|
25
|
+
- Use `primaryButton` and `secondaryButton` to offer CTAs. Button themes are inferred from the banner theme automatically — do not manually set button themes inside InlineBanner
|
|
26
|
+
- Use a caption below the CTAs for supplementary detail, plan names, or pricing info
|
|
27
|
+
- Only override the icon when there is a strong contextual reason — the default icon communicates the theme reliably
|
|
28
|
+
|
|
29
|
+
### Where Do Banners Go?
|
|
30
|
+
|
|
31
|
+
- A good rule is to keep the banner relatively nearby to what it is referring to.
|
|
32
|
+
- Banners relevant to an entire page should be placed at the top of that page, below the page header. They should occupy the full width of the content area.
|
|
33
|
+
- Banners related to a section of a page (like a card, drawer, or modal) should be placed inside that section, below any section heading.
|
|
34
|
+
- When only a specific UI element is paywalled within a section of content, the feature is typically replaced with an UpsellBanner for said feature.
|
|
35
|
+
|
|
36
|
+
### Choosing a theme
|
|
37
|
+
|
|
38
|
+
| Theme | When to use | Copy Tone |
|
|
39
|
+
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
40
|
+
| `info` | Helpful information, an update or advice relevant to the current state. | Written to highlight an opportunity: “Let's get you started\!”“Did you know…” |
|
|
41
|
+
| `warning` | Something that may cause problems if ignored or a potential problem on the current state. | Casual but direct, _You should know before you proceed,_ tone. |
|
|
42
|
+
| `danger` | Something has gone wrong that must or should be resolved immediately. When the user is presented with a high risk action. | Direct, clear and prescriptive about the next action. Explain what is wrong or dangerous, the consequences and how to resolve it. |
|
|
43
|
+
| `success` | In most cases a toast can be used for a completed action. Use this instead when feedback is delayed, needs to be persistent or requires a call to action. | Direct. Celebratory. Reiterating the benefit of the successful action . |
|
|
44
|
+
| `upsell` | When we need to communicate a message and it provides an opportunity to upsell a feature or addon. Should not be used as a persistent upsell state when a feature is missing \- use \`Paywall\` instead | Focus on the benefit a user will gain by upgrading. The benefit should be in context to what the user was doing or what section/page this banner is on. |
|
|
45
|
+
|
|
46
|
+
## Additional Rules
|
|
47
|
+
|
|
48
|
+
- `children` is required — the banner body text.
|
|
49
|
+
- `theme` defaults to `"info"`. Always pass it explicitly so the intent is clear.
|
|
50
|
+
- Providing `title` changes the layout from single-line to multi-line. Do not use `title` for single-line messages where the body text is sufficient.
|
|
51
|
+
- `primaryButton` and `secondaryButton` accept a `Button` element. The component infers the correct button theme (`hollow` for primary, `link-primary` / `link-upsell` for secondary) — do not pass a `theme` prop on the button unless you intentionally need to override it.
|
|
52
|
+
- The `icon` prop is an escape hatch. Only use icons from Sous Chef — custom SVGs will break visual consistency.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
<!-- AUTO-GENERATED by scripts/build-llms-guidelines.js. Do not edit manually. Run `yarn build-llms-guidelines` to regenerate. -->
|
|
2
|
+
|
|
3
|
+
## When to Use
|
|
4
|
+
|
|
5
|
+
- To navigate to an external URL, opening it in a new tab
|
|
6
|
+
- To navigate within the app when the destination itself is the point — "View profile", "Learn more"
|
|
7
|
+
- When the clickable element lives inline inside a sentence or body copy
|
|
8
|
+
|
|
9
|
+
## When Not to Use
|
|
10
|
+
|
|
11
|
+
- When the click triggers an action rather than navigation — use `Button` instead
|
|
12
|
+
- When the element stands alone as a primary or secondary call to action — use `Button` instead
|
|
13
|
+
- When opening a modal, drawer, or overlay — use `Button` instead
|
|
14
|
+
|
|
15
|
+
## Usage
|
|
16
|
+
|
|
17
|
+
- Use theme="primary" (the default) on standard backgrounds. Use theme="contrast" when the link sits on a dark or inverse-coloured surface so it remains legible.
|
|
18
|
+
- Link text should describe the destination, not the action — "Scheduling documentation", not "Click here"
|
|
19
|
+
- Keep link labels concise; avoid linking full sentences
|
|
20
|
+
- Do not use Link for buttons that happen to be styled as text — if it triggers something, it's a Button
|
|
21
|
+
|
|
22
|
+
## Additional Rules
|
|
23
|
+
|
|
24
|
+
- href is required. Do not render a Link without a valid destination.
|
|
25
|
+
- target defaults to \_blank. Explicitly pass target="\_self" for in-app navigation where staying in the same tab is the correct behaviour.
|
|
26
|
+
- theme defaults to "primary". Only pass theme="contrast" when the link is on a dark or inverse surface — using it on light backgrounds produces incorrect contrast ratios.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<!-- AUTO-GENERATED by scripts/build-llms-guidelines.js. Do not edit manually. Run `yarn build-llms-guidelines` to regenerate. -->
|
|
2
|
+
|
|
3
|
+
## When to Use
|
|
4
|
+
|
|
5
|
+
- When a contextual message needs to fit inside a card, sidebar, or other constrained layout
|
|
6
|
+
- When only one action is needed alongside a brief message
|
|
7
|
+
- When the full scale of `InlineBanner` would be too dominant for the surrounding content
|
|
8
|
+
|
|
9
|
+
## When Not to Use
|
|
10
|
+
|
|
11
|
+
- When the message needs two CTAs or a dismiss button — use `InlineBanner` instead
|
|
12
|
+
- For app-wide announcements — use `PersistentBanner` instead
|
|
13
|
+
- For transient action confirmations — use `Toast` instead
|
|
14
|
+
|
|
15
|
+
## Usage
|
|
16
|
+
|
|
17
|
+
- See `InlineBanner` for broader guidelines on usage
|
|
18
|
+
- Unlike InlineBanners, MicroBanners can only have a maximum of 1 button
|
|
19
|
+
- Choosing between an `InlineBanner` and a `MicroBanner` is a design decision.
|
|
20
|
+
- As a general rule, you should use a MicroBanner when the space you're working within is too tight for a full banner (such as in a menu or sidebar).
|
|
21
|
+
- Use MicroBanner when it's ok to communicate less information and an InlineBanner is too disruptive to the layout of the page.
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
<!-- AUTO-GENERATED by scripts/build-llms-guidelines.js. Do not edit manually. Run `yarn build-llms-guidelines` to regenerate. -->
|
|
2
|
+
|
|
3
|
+
## When to Use
|
|
4
|
+
|
|
5
|
+
- When the user needs to make a decision before continuing — a confirmation, a destructive action, or a high-stakes choice
|
|
6
|
+
- As the entry or exit point of a short, self-contained flow — adding a location, inviting a team member, completing a quick setup
|
|
7
|
+
- When a complete task needs to stay in context without navigating to a new page
|
|
8
|
+
- For critical alerts that must be acknowledged before the user can proceed
|
|
9
|
+
|
|
10
|
+
## When Not to Use
|
|
11
|
+
|
|
12
|
+
- In the middle of a longer multi-step flow — modal-within-modal patterns become disorienting quickly
|
|
13
|
+
- When the task only needs 1 or 2 lightweight actions — a `Popover` is less disruptive
|
|
14
|
+
- When the information is purely informational and requires no decision — use `InlineBanner`, `MicroBanner`, or `Tooltip` instead
|
|
15
|
+
- When the modal would cover content the user needs to reference while completing the task
|
|
16
|
+
|
|
17
|
+
## Usage
|
|
18
|
+
|
|
19
|
+
### Common Mistakes
|
|
20
|
+
|
|
21
|
+
- Modals are highly disruptive to a user's flow. As such, we should use them sparingly and with intention.
|
|
22
|
+
- Modal fatigue is a real problem, and occurs when users are served too many modals in a single experience. It causes users to lose focus, lose context and become frustrated.
|
|
23
|
+
- **NEVER** launch a modal from another modal.
|
|
24
|
+
- It can be tempting to use modals as a design short-cut when adding new functionality to an existing page without having to touch the existing design. Avoid this habit, and think about how you would design this page from scratch if the new functionality existed in the first place.
|
|
25
|
+
|
|
26
|
+
### Structure
|
|
27
|
+
|
|
28
|
+
A Modal is composed of four parts: the `Modal` wrapper (which handles the overlay and focus trapping), a `header` which contains the title (and an optional `subHeader`), a `ModalBody` for content, and a `ModalFooter` for actions. The `header` and optional `subHeader` appear at the top of the modal.
|
|
29
|
+
|
|
30
|
+
### Sizing
|
|
31
|
+
|
|
32
|
+
- Modals by default are `500px` wide. We recommend sticking to this size whenever possible.
|
|
33
|
+
- A modal's height is variable based on the content. We recommend never making a modal more than `750px` in height.
|
|
34
|
+
- Avoid making a modal so large it feels like a full page; if content is that complex, consider whether a dedicated page is more appropriate.
|
|
35
|
+
|
|
36
|
+
### Non-closable modals
|
|
37
|
+
|
|
38
|
+
When `onClose` is omitted, the modal renders without a close button. Use this sparingly — during loading, for flows where closing partway through would leave data in an inconsistent state or for a critical action the user cannot ignore.
|
|
39
|
+
|
|
40
|
+
## Tips & Tricks
|
|
41
|
+
|
|
42
|
+
- Modals are high interruption and high interaction. Use them deliberately — every unnecessary modal trains users to dismiss them without reading.
|
|
43
|
+
- A modal with a single "OK" button is usually a sign the content belongs in a banner or toast instead.
|
|
44
|
+
- Keep modal content focused. If you find yourself adding tabs, accordions, or nested forms, the modal is doing too much.
|
|
45
|
+
- The modal traps keyboard focus automatically — don't try to manage focus manually inside it.
|
|
46
|
+
|
|
47
|
+
## Additional Rules
|
|
48
|
+
|
|
49
|
+
- `Modal` requires `Modal.setAppElement('#root')` (or equivalent) to be called once in the app, or `rootElementId` to be passed per instance, for correct accessibility behaviour.
|
|
50
|
+
- `ModalBody` and `ModalFooter` are required sub-components — do not render content directly as children of `Modal` without them.
|
|
51
|
+
- Use `loading={true}` during async operations to disable the close button and prevent users from interrupting a save or delete in progress.
|
|
52
|
+
- Modal uses a backdrop overlay; interaction with the page behind it is blocked while open.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<!-- AUTO-GENERATED by scripts/build-llms-guidelines.js. Do not edit manually. Run `yarn build-llms-guidelines` to regenerate. -->
|
|
2
|
+
|
|
3
|
+
## When to Use
|
|
4
|
+
|
|
5
|
+
- Consider adding pagination if your list of items is around 15 single line text rows in height or more.
|
|
6
|
+
- When a data set is split across multiple pages and the user needs to step forward or backward through them
|
|
7
|
+
- When the list or table has a fixed page size and the total count is large enough that showing all records at once is impractical
|
|
8
|
+
|
|
9
|
+
## When Not to Use
|
|
10
|
+
|
|
11
|
+
- If there is a large data set and the user needs to be able quickly pick out a single item. If you are using this pattern consider including a search.
|
|
12
|
+
- When records load continuously as the user scrolls — use infinite scroll instead
|
|
13
|
+
- When there is only ever one page of results — hide or omit the controls entirely rather than rendering them in a permanently disabled state
|
|
14
|
+
|
|
15
|
+
## Usage
|
|
16
|
+
|
|
17
|
+
- Place PaginationControls at the bottom of the paginated list or table, aligned to the trailing edge or centered depending on the layout.
|
|
18
|
+
- Both buttons are always rendered; disable `hasPrevious` on the first page and `hasNext` on the last page to communicate the boundary rather than hiding the buttons.
|
|
19
|
+
- Always keep both buttons visible. Hiding one button when it is unavailable causes the layout to shift and removes the affordance that pagination exists.
|
|
20
|
+
- Label the surrounding context clearly — PaginationControls provides no page count or position indicator. If the user needs to know "page 3 of 10", add that text adjacent to the controls.
|
|
21
|
+
- PaginationControls allow for keyboard navigation using the keys: (`J` / `K`)
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
<!-- AUTO-GENERATED by scripts/build-llms-guidelines.js. Do not edit manually. Run `yarn build-llms-guidelines` to regenerate. -->
|
|
2
|
+
|
|
3
|
+
## When to Use
|
|
4
|
+
|
|
5
|
+
- When an entire page is locked because it belongs to a higher plan tier
|
|
6
|
+
- When a section or component within a page is locked behind a paid add-on
|
|
7
|
+
- When the user has access to the product but not to this specific feature
|
|
8
|
+
|
|
9
|
+
## When Not to Use
|
|
10
|
+
|
|
11
|
+
- When content is empty for any reason other than a subscription gate — use `EmptyState` instead
|
|
12
|
+
- When the user has the right plan but hasn't set up the feature yet — use `EmptyState` instead
|
|
13
|
+
- When content is loading or erroring
|
|
14
|
+
|
|
15
|
+
## Usage
|
|
16
|
+
|
|
17
|
+
### Small
|
|
18
|
+
|
|
19
|
+
Small should be used either when only a portion of the content on a page is paywalled or when a sub-feature on a page is paywalled.
|
|
20
|
+
|
|
21
|
+
### Medium
|
|
22
|
+
|
|
23
|
+
Also known as horizontal empty states. Used inline either when only a portion of the content on a page is paywalled or when a sub-feature on a page is paywalled. They differ from Small in that they provide the user more context to the empty state and they have some kind of call-to-action.
|
|
24
|
+
|
|
25
|
+
### Large
|
|
26
|
+
|
|
27
|
+
Also known as the Full Page Paywalls. Used when an entire page is paywalled.
|
|
28
|
+
|
|
29
|
+
### As a Card
|
|
30
|
+
|
|
31
|
+
Use `as="card"` with `size="medium"` when the Paywall needs to sit within a card container. Pass `onClose` to let the user dismiss it.
|
|
32
|
+
|
|
33
|
+
### Images
|
|
34
|
+
|
|
35
|
+
- The image should use our Bento image format.
|
|
36
|
+
- Large empty states can use either a single frame bento, or a multi-frame collage
|
|
37
|
+
- Medium and small empty states should use a single frame bento
|
|
38
|
+
- Bentos frames can contain an Inking illustration, a lifestyle photo or UI mockup
|
|
39
|
+
|
|
40
|
+
### Copy Best Practices
|
|
41
|
+
|
|
42
|
+
- Write in sentence case, with the usual exceptions of proper nouns such as a person, feature name, location, etc., being title case
|
|
43
|
+
- Use as few words as possible in the title and description. Be direct and clear.
|
|
44
|
+
- Avoid repeating content from the title in the body. Say things once with intent
|
|
45
|
+
- Avoid technical terms or jargon. Communicate using common words
|
|
46
|
+
- Always choose a simpler shorter words over longer fancier words
|
|
47
|
+
- The copy should explain what feature is behind a paywall and what value it can provide to the user if they add the feature to their plan.
|
|
48
|
+
- The title should communicate the message fully if possible, users are more likely to read this
|
|
49
|
+
- The body/description should be used to provide further important details or next steps
|
|
50
|
+
- caption appears below the action buttons — use it for secondary guidance or legal-style caveats, not as a substitute for body text.
|
|
51
|
+
|
|
52
|
+
## Additional Rules
|
|
53
|
+
|
|
54
|
+
- `Paywall` passes `isPaywall={true}` to `EmptyStateContainer` internally — do not use `EmptyState` with any manual paywall flag. Always use the `Paywall` component so the visual treatment is applied correctly and consistently.
|
|
55
|
+
- `title` is required. All other props are optional but `actions.primary` should always be provided.
|
|
56
|
+
- `as`, `size`, `onClose`, `header`, `caption`, `mediaUrl`, and `actions` behave identically to `EmptyState` — refer to the EmptyState guidelines for usage details on those props.
|
|
57
|
+
- `onClose` is only valid when `as="card"`. Passing it in banner mode has no effect.
|