Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 18 additions & 1 deletion packages/v1-components/docs/AI.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,13 @@ When building a basic form or settings screen, start from patterns like:
```ts
import {
UiButton,
UiCheckbox,
UiField,
UiNumberStepper,
UiPageFooter,
UiPageHeader,
UiSelect,
UiSwitch,
UiTextbox,
} from '@retailcrm/embed-ui-v1-components/remote'
```
Expand All @@ -75,6 +78,9 @@ Typical compositions:

- `UiField` + `UiTextbox`
- `UiField` + `UiSelect`
- `UiField` + `UiNumberStepper`
- `UiSwitch` + visible label + hint row
- `UiCheckbox` + visible label row or checkbox group
- `UiPageHeader` + `UiButton`
- `UiSelect` + `UiSelectOption`

Expand All @@ -91,15 +97,20 @@ Default screen rules:
- use `UiPageFooter` for page-level save/cancel/delete actions instead of recreating a local footer;
- use one `Success Primary` button for the strongest save/apply/create action that commits a result; use `Default Primary`
only for another important action with a different meaning;
- use `Secondary` buttons for real neighboring commands that should still look like buttons;
- use `Tertiary` buttons for lower-emphasis edit, open, configure, cancel, close, and optional commands near headers,
cards, tables, and inline content;
- apply the 24px top and 32px side/bottom padding rule to white content surfaces, not to the page root wrapper;
- keep filters and controls near the content they affect;
- use `UiField` around labeled form controls;
- use `UiField` around labeled textbox, select, number, date, and time controls;
- use `UiTable` for structured result lists;
- use `UiLink` for navigation and inline links, `UiButton` for commands;
- use `UiLoader` with `overlay: true` when loading should dim the covered page or module content;
- keep public imports on `@retailcrm/embed-ui-v1-components/remote`;
- when a component uses only the default slot, prefer `v-slot` on the component instead of `<template #default>`;
- avoid custom markup that recreates textbox, select, button, link, or table chrome.
- before passing enum-like prop values, check the component profile or public type; omit optional props instead of
inventing neutral values such as `"none"` when they are not listed.

## Default Recommendation For Table Screens

Expand Down Expand Up @@ -142,10 +153,16 @@ When building forms with remote controls:
- use `UiField` for labeled text, select, date, and number controls;
- forward `UiField` slot props into the actual child control when it accepts `id`, especially
`UiTextbox`, `UiSelect`, and `UiNumberStepper`;
- put validation errors inside the relevant field composition, not as unrelated sibling blocks;
- when a component uses only the default slot, prefer `v-slot` on the component instead of
`<template #default>`;
- do not wrap `UiSwitch` in `UiField`; place the switch next to a visible label and optional hint,
and connect `UiSwitch :id` with `label :for`.
- do not wrap simple `UiCheckbox` rows in `UiField`; place the checkbox next to a visible label and optional hint.
- use `UiSwitch` for compact immediate boolean settings, feature toggles, and enable/disable flags.
- use `UiCheckbox` for checkbox groups, table row selection, "select all", acknowledgements, and checkbox-shaped choices.
- use `UiNumberStepper` for bounded numeric settings, quantities, durations, limits, and values with meaningful increments.
- use `UiTextbox` for numeric-looking text such as phone numbers, codes, identifiers, and free-form numeric strings.

## Default Recommendation For Widgets

Expand Down
22 changes: 22 additions & 0 deletions packages/v1-components/docs/STYLING.md
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,28 @@ For style-sensitive generation:
4. avoid relying on internal descendant selectors unless the profile says that is safe;
5. state which styling source is being followed when the change was requested by design feedback.

## Remote Page Styles

For Vue remote pages and page-like components, prefer local CSS Modules:

```vue
<style module lang="less">
```

Apply classes through `$style[...]` in the template. Use `@import (reference)` from
`@retailcrm/embed-ui-v1-components/assets/stylesheets/*` for shared LESS tokens and typography
mixins.

Remote page styles should normally:

- use package spacing, palette, geometry, and typography tokens instead of local hardcoded colors,
font sizes, weights, and spacing;
- keep styles local to the page or component through CSS Modules;
- avoid shared global files such as `admin.less` as the default strategy;
- avoid duplicating CRM host layout padding on the page root;
- put documented 24px top and 32px side/bottom padding on white content surfaces when such a
surface exists.

## Design Feedback Triage

When design feedback does not match the current implementation, resolve the source before editing:
Expand Down
13 changes: 12 additions & 1 deletion packages/v1-components/docs/profiles/components/UiAvatar.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ examples:
name="Anna Smith"
src="https://example.com/avatar.jpg"
size="sm"
status="none"
/>
</template>

Expand All @@ -37,7 +36,17 @@ api:
- name: src
- name: name
- name: status
values:
- busy
- break
- dinner
- free
notes: Omit status when no indicator should be shown; do not pass "none".
- name: size
values:
- xs
- sm
- lg
- name: href

rendered_structure:
Expand All @@ -61,8 +70,10 @@ ai_notes:
do:
- Use UiAvatar for identity display, not for general media.
- Provide name whenever possible so fallback identity stays meaningful.
- Omit optional enum-like props when no listed value applies.
avoid:
- Do not use it for generic content images or large media blocks.
- Do not pass unsupported neutral values such as status="none"; check listed values first.

composition:
works_well_with:
Expand Down
6 changes: 5 additions & 1 deletion packages/v1-components/docs/profiles/components/UiButton.yml
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,8 @@ behavior:
notes: Enables the separate locked state.
notes:
- If href is present, the component becomes a link-shaped action.
- appearance="secondary" is for neighboring commands that should still read as real buttons.
- appearance="tertiary" is for lower-emphasis actions near headers, cards, tables, and inline content.

accessibility:
notes:
Expand All @@ -231,7 +233,9 @@ ai_notes:
- Start with appearance=primary for the main CTA, then choose variant by meaning.
- Use variant="success" for the strongest create/save/apply action when it commits a result, and keep only one Success Primary on a page.
- Use the default variant for an important primary action that is not the strongest commit action.
- Use secondary or tertiary for neighboring actions near titles.
- Use secondary for a real neighboring command that should still look like a button.
- Use tertiary for lower-emphasis edit, open, configure, cancel, close, and optional commands that should not compete with the main flow.
avoid:
- Do not replace UiButton with UiLink when the action should read as a button.
- Do not use UiButton for regular inline text navigation.
- Do not default every non-primary action to secondary; choose tertiary when the action is only supportive.
24 changes: 16 additions & 8 deletions packages/v1-components/docs/profiles/components/UiCheckbox.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
component: UiCheckbox
summary: >
UiCheckbox is a boolean or set-membership control. It supports single boolean-like usage
as well as model-plus-value patterns for checkbox groups.
UiCheckbox is a checkbox or set-membership control. It supports single acknowledgement-like
choices, table row selection, "select all" states, and model-plus-value patterns for checkbox groups.

public_import:
from: '@retailcrm/embed-ui-v1-components/remote'
Expand Down Expand Up @@ -37,12 +37,14 @@ examples:
const channels = ref<string[]>([])
</script>
use_when:
- You need a yes or no control.
- You need a checkbox-shaped boolean choice such as an acknowledgement or confirmation.
- You need one value inside a checkbox group model.
- You need row selection, mass selection, or an indeterminate "select all" control.

avoid_when:
- You need exclusive single choice, use UiRadio instead.
- You need a more compact toggle-like control, use UiSwitch instead.
- You need a compact immediate on or off setting, use UiSwitch instead.
- You need a settings toggle row where a switch better communicates enable or disable state.

api:
key_props:
Expand Down Expand Up @@ -73,26 +75,32 @@ behavior:
notes:
- model plus value supports group-style selection.
- indeterminate is useful for partial selection states.
- For ordinary settings toggles, UiSwitch is usually the better control even when the value is boolean.

ai_notes:
do:
- Use for boolean choice or checkbox-group membership.
- Use for checkbox-group membership, acknowledgement-like boolean choices, and table row selection.
- Use indeterminate for parent selection such as "select all visible rows".
avoid:
- Do not use for mutually exclusive options.
- Do not replace UiSwitch settings toggles with UiCheckbox just because the value is boolean.

composition:
works_well_with:
- UiField
- visible label
- hint text
- UiTable
- UiTableColumn
patterns:
- title: Form boolean
notes: Wrap in UiField when the checkbox needs a persistent label, hint, or validation text.
- title: Checkbox row
notes: Place UiCheckbox on the left, label and optional hint on the right, similar to a UiSwitch settings row.
- title: Checkbox group
notes: Use several UiCheckbox controls with one array model and visible labels for multi-selection.
- title: Table row selection
notes: Use in the first narrow UiTableColumn for row selection; use indeterminate in the header checkbox for partial selection.
avoid:
- Do not use as a visual switch replacement when the action is an immediate on or off setting.
- Do not wrap simple checkbox rows in UiField; use an explicit row with visible label and optional hint.

accessibility:
notes:
Expand Down
7 changes: 5 additions & 2 deletions packages/v1-components/docs/profiles/components/UiField.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ public_import:
related_components:
- UiTextbox
- UiSelect
- UiCheckbox
- UiNumberStepper
- UiDatePicker

Expand Down Expand Up @@ -162,6 +161,8 @@ api:
- UiDatePicker
avoid:
- several unrelated controls
- UiSwitch setting rows
- UiCheckbox setting rows
- decorative layout only
- raw content without using slot props
layout_effect: The control sits below the headline and inherits field-level semantics through slot props.
Expand Down Expand Up @@ -311,8 +312,10 @@ ai_notes:
- Forward slot props into the actual control in most form scenarios.
- Pass field.id to child controls that accept id, including UiTextbox, UiSelect, and UiNumberStepper.
- Use v-slot on UiField when the field uses only the default slot.
- Use UiField as a semantic wrapper for a single control.
- Use UiField as a semantic wrapper for a single textbox, select, number, date, or time control.
- Place validation errors inside the relevant field composition instead of rendering them as unrelated sibling blocks.
avoid:
- Do not use UiField as a generic visual container without control semantics.
- Do not use UiField for UiSwitch settings rows; pair UiSwitch with a visible label and hint text instead.
- Do not use UiField for simple UiCheckbox rows; pair UiCheckbox with a visible label and optional hint instead.
- Do not ignore id and ariaLabelledby when accessibility matters.
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,11 @@ examples:
use_when:
- You need numeric input with explicit step controls.
- You need range constraints and nullable numeric state.
- You need bounded numeric settings, quantities, durations, limits, delays, or values with meaningful increments.

avoid_when:
- You need plain text or decimal input without stepper controls.
- You need numeric-looking text such as phone numbers, codes, identifiers, or free-form strings.

api:
key_props:
Expand Down Expand Up @@ -82,6 +84,7 @@ ai_notes:
- Prefer nullable when clearing the value is a valid state.
avoid:
- Do not use when the value is an identifier, phone, code, or other numeric-looking text.
- Do not replace with UiTextbox for bounded numeric settings unless a runtime limitation is documented.

accessibility:
notes:
Expand Down
3 changes: 3 additions & 0 deletions packages/v1-components/docs/profiles/components/UiSwitch.yml
Original file line number Diff line number Diff line change
Expand Up @@ -120,10 +120,12 @@ examples:
</style>
use_when:
- You need a compact on or off toggle.
- You need an immediate boolean setting, feature flag, enable or disable control, or settings row.

avoid_when:
- You need checkbox-group semantics.
- You need a UiField-style labeled wrapper; pair UiSwitch with a visible label and hint text instead.
- You need an acknowledgement, legal confirmation, table selection, or multi-select choice; use UiCheckbox instead.

api:
key_props:
Expand Down Expand Up @@ -170,6 +172,7 @@ ai_notes:
- Put helper text below the label in the settings row, not in UiField hint.
avoid:
- Do not use for multi-select lists or legal acknowledgements; use UiCheckbox.
- Do not replace compact settings toggles with UiCheckbox just because the value is boolean.
- Do not use UiField around UiSwitch.

accessibility:
Expand Down
2 changes: 2 additions & 0 deletions packages/v1-components/docs/profiles/components/UiTextbox.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,14 @@ use_when:
- You need a standard text input.
- You need search, email, phone, url, or password input.
- You need decimal or numeric input without a separate stepper.
- You need numeric-looking text such as a phone, code, identifier, article, external id, or free-form numeric string.
- You need a multiline control in the same visual language.
- You need an input that composes well with UiField and inline editing.

avoid_when:
- You need value selection, not free-form input.
- You need explicit increment and decrement UX.
- You need bounded numeric settings, quantities, durations, limits, or values with meaningful increments; use UiNumberStepper instead.
- You need advanced formatting beyond the prefix or suffix model.

api:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ expected_structure:
- The white content surface owns the 24px top and 32px side/bottom padding.
- The page root wrapper should not repeat that padding.
- Content can include text, buttons, fields, checkboxes, radio groups, switches, and other form controls.
- Textbox, select, number, date, and time controls usually live inside UiField.
- UiSwitch and simple UiCheckbox rows should use their own row layout with a visible label and optional hint, not UiField.
- A bottom save panel is optional.
- If a bottom save panel is used, its main save or apply action should be Success Primary.

Expand Down Expand Up @@ -55,9 +57,14 @@ recommended_components:
ai_notes:
do:
- Keep form controls grouped by task or semantic section.
- Use UiField around labelled form controls.
- Use UiField around labeled textbox, select, number, date, and time controls.
- Use UiSwitch for compact enable or disable settings.
- Use UiCheckbox for checkbox groups, table selection, acknowledgements, and checkbox-shaped boolean choices.
- Use tabs only when they reduce visible complexity without hiding required work.
- Keep save/apply as the strongest footer action and move neighboring actions to secondary or tertiary appearances unless their variant has a distinct page-level meaning.
- Prefer tertiary for low-emphasis local actions that should not compete with the settings save flow.
avoid:
- Do not create a decorative landing page for operational settings.
- Do not put content-surface padding on the root page wrapper.
- Do not use UiCheckbox as the default replacement for UiSwitch just because a setting is boolean.
- Do not wrap UiSwitch or simple UiCheckbox rows in UiField.
3 changes: 3 additions & 0 deletions packages/v1-components/docs/profiles/pages/EntityListPage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ expected_structure:
- One or more 48px page buttons on the right side of the header.
- If there are multiple header buttons, one should be primary and the rest can be secondary or tertiary.
- The main Default Primary button usually creates a new entity for the list when there is no stronger Success Primary action on the page.
- Supporting header actions that should not compete with the create action are usually tertiary rather than secondary.
- Filters above the table, built from controls such as select, textbox, and combobox-like selection components.
- Filter controls should run in rows of roughly 4-5 fields, then wrap to the next row.
- Filters can be collapsible.
Expand Down Expand Up @@ -65,8 +66,10 @@ ai_notes:
- Persist filters, sorting, page, and page size in query parameters when routing is available.
- Reset page to 1 when filters or sorting change.
- Use narrow icon-only row action columns with matching aria-label and UiTooltip text.
- Use tertiary for low-emphasis header or row-adjacent commands when a secondary button would be too visually heavy.
avoid:
- Do not hide filters in page header actions.
- Do not put pagination only in local state when the result set is routable.
- Do not place UiTable inside an additional white card or padded content surface.
- Do not use visible text buttons for dense table row actions.
- Do not make every header action secondary when only one action should draw attention.
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ shared_rules:
- Use Default Primary for an important action that is secondary to the Success Primary or does not commit a result.
- Use Danger Primary only for one critical destructive action when the page needs it.
- If several actions compete for attention, choose the main one for Success Primary and move the rest to Default Primary, secondary, tertiary, or dropdown actions by meaning.
- Use secondary for a real neighboring command that should still read as a button.
- Use tertiary for lower-emphasis header, card, inline, configure, edit, open, cancel, and close actions that should not compete with the main flow.
- UiPageHeader actions and UiPageFooter actions belong to the same page-level action scope.
- Treat each UiCollapseBox footer as a separate local action scope with the same rules scoped to that section.
- A page can have several Default Primary buttons when each one belongs to a different UiCollapseBox footer.
Expand Down Expand Up @@ -60,8 +62,10 @@ ai_notes:
- Choose ModalWindow or a full page when content needs wide tables, several sections, or complex controls.
- Keep operational CRM screens dense, scannable, and work-focused.
- Prefer variant="success" for the main save/apply/create action and keep it visually dominant.
- Prefer appearance="tertiary" for supportive actions that sit near content but should stay visually quiet.
avoid:
- Do not turn internal CRM work screens into marketing-style layouts.
- Do not hide filters or primary workflow controls away from the content they affect.
- Do not place multiple Success Primary, Default Primary, or Danger Primary actions with the same variant in the page-level scope or inside one collapse-box scope.
- Do not default every non-primary action to appearance="secondary"; choose by local action importance.
- Do not add page-surface padding to both the page root and the white content surface.
Loading