@retailcrm/embed-ui-v1-components 0.9.14 → 0.9.16

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 (78) hide show
  1. package/AGENTS.md +126 -0
  2. package/README.md +24 -0
  3. package/assets/sprites/map-and-places/navigate.svg +3 -0
  4. package/assets/stylesheets/palette.less +11 -6
  5. package/bin/embed-ui-v1-components.mjs +209 -0
  6. package/bin/postinstall.mjs +37 -0
  7. package/dist/host.cjs +2443 -657
  8. package/dist/host.css +920 -6
  9. package/dist/host.d.ts +2440 -6
  10. package/dist/host.js +2444 -658
  11. package/dist/remote.cjs +1009 -46
  12. package/dist/remote.d.ts +1240 -67
  13. package/dist/remote.js +1011 -48
  14. package/docs/AI.md +106 -0
  15. package/docs/COMPONENTS.md +99 -0
  16. package/docs/FORMAT.md +267 -0
  17. package/docs/PROFILES.md +66 -0
  18. package/docs/README.md +65 -0
  19. package/docs/STYLING.md +156 -0
  20. package/docs/profiles/UiAddButton.yml +57 -0
  21. package/docs/profiles/UiAlert.yml +48 -0
  22. package/docs/profiles/UiAvatar.yml +48 -0
  23. package/docs/profiles/UiAvatarList.yml +42 -0
  24. package/docs/profiles/UiButton.yml +229 -0
  25. package/docs/profiles/UiCalendar.yml +48 -0
  26. package/docs/profiles/UiCheckbox.yml +53 -0
  27. package/docs/profiles/UiCollapse.yml +40 -0
  28. package/docs/profiles/UiCollapseBox.yml +51 -0
  29. package/docs/profiles/UiCollapseGroup.yml +39 -0
  30. package/docs/profiles/UiCopyButton.yml +52 -0
  31. package/docs/profiles/UiDate.yml +38 -0
  32. package/docs/profiles/UiDatePicker.yml +59 -0
  33. package/docs/profiles/UiError.yml +32 -0
  34. package/docs/profiles/UiField.yml +233 -0
  35. package/docs/profiles/UiImage.yml +39 -0
  36. package/docs/profiles/UiInfobox.yml +45 -0
  37. package/docs/profiles/UiLink.yml +51 -0
  38. package/docs/profiles/UiLoader.yml +38 -0
  39. package/docs/profiles/UiMenuItem.yml +57 -0
  40. package/docs/profiles/UiMenuItemGroup.yml +50 -0
  41. package/docs/profiles/UiModalSidebar.yml +46 -0
  42. package/docs/profiles/UiModalWindow.yml +44 -0
  43. package/docs/profiles/UiModalWindowSurface.yml +41 -0
  44. package/docs/profiles/UiNumberStepper.yml +52 -0
  45. package/docs/profiles/UiPageHeader.yml +244 -0
  46. package/docs/profiles/UiPopper.yml +201 -0
  47. package/docs/profiles/UiPopperConnector.yml +115 -0
  48. package/docs/profiles/UiPopperTarget.yml +118 -0
  49. package/docs/profiles/UiRadio.yml +38 -0
  50. package/docs/profiles/UiRadioSwitch.yml +231 -0
  51. package/docs/profiles/UiRadioSwitchOption.yml +121 -0
  52. package/docs/profiles/UiScrollBox.yml +31 -0
  53. package/docs/profiles/UiSelect.yml +327 -0
  54. package/docs/profiles/UiSelectOption.yml +44 -0
  55. package/docs/profiles/UiSelectOptionGroup.yml +38 -0
  56. package/docs/profiles/UiSlider.yml +38 -0
  57. package/docs/profiles/UiSwitch.yml +37 -0
  58. package/docs/profiles/UiTab.yml +119 -0
  59. package/docs/profiles/UiTabGroup.yml +238 -0
  60. package/docs/profiles/UiTable.yml +152 -0
  61. package/docs/profiles/UiTableBodyCell.yml +47 -0
  62. package/docs/profiles/UiTableColumn.yml +50 -0
  63. package/docs/profiles/UiTableFooterButton.yml +44 -0
  64. package/docs/profiles/UiTableFooterSection.yml +38 -0
  65. package/docs/profiles/UiTableHeadCell.yml +44 -0
  66. package/docs/profiles/UiTableSorter.yml +45 -0
  67. package/docs/profiles/UiTag.yml +41 -0
  68. package/docs/profiles/UiTextbox.yml +392 -0
  69. package/docs/profiles/UiTimePicker.yml +46 -0
  70. package/docs/profiles/UiToggleButton.yml +211 -0
  71. package/docs/profiles/UiToggleGroup.yml +211 -0
  72. package/docs/profiles/UiToggleGroupOption.yml +116 -0
  73. package/docs/profiles/UiToolbarButton.yml +37 -0
  74. package/docs/profiles/UiToolbarLink.yml +32 -0
  75. package/docs/profiles/UiTooltip.yml +43 -0
  76. package/docs/profiles/UiTransition.yml +27 -0
  77. package/docs/profiles/UiYandexMap.yml +29 -0
  78. package/package.json +8 -3
@@ -0,0 +1,201 @@
1
+ component: UiPopper
2
+ summary: >
3
+ UiPopper is the low-level floating layer used for tooltips, dropdowns, and popups.
4
+ It controls visibility, teleport container, positioning, and trigger logic, but is usually
5
+ consumed as part of a higher-level component rather than as a standalone content wrapper.
6
+
7
+ public_import:
8
+ from: '@retailcrm/embed-ui-v1-components/remote'
9
+ named:
10
+ - UiPopper
11
+
12
+ related_components:
13
+ - UiPopperConnector
14
+ - UiPopperTarget
15
+ - UiSelect
16
+ - UiTooltip
17
+
18
+ use_when:
19
+ - You need a floating layer anchored to a target element.
20
+ - You need separate show and hide triggers for target and popper.
21
+ - You need a dropdown, tooltip, or contextual popup with placement control.
22
+
23
+ avoid_when:
24
+ - You need a regular block in normal document flow.
25
+ - You need a high-level dropdown or tooltip and do not need low-level control.
26
+
27
+ api:
28
+ key_props:
29
+ - name: visible
30
+ notes: Controls open state.
31
+ - name: target
32
+ notes: DOM target used for positioning.
33
+ - name: placement
34
+ notes: Controls side and alignment.
35
+ - name: targetTriggers
36
+ notes: Target-side trigger rules.
37
+ - name: popperTriggers
38
+ notes: Popper-side trigger rules.
39
+ - name: globalTriggers
40
+ notes: Global trigger rules such as outside click or escape.
41
+ - name: withArrow
42
+ notes: Adds an arrow element.
43
+ props:
44
+ - name: strategy
45
+ notes: Floating strategy such as absolute or fixed.
46
+ - name: container
47
+ notes: Teleport target, often body.
48
+ - name: disabled
49
+ notes: Disables floating behavior.
50
+ - name: delay
51
+ notes: Show or hide delay.
52
+ - name: detachTimeout
53
+ notes: Delay before detaching the layer.
54
+ - name: offset
55
+ notes: Floating layer offset.
56
+ slots:
57
+ - name: default
58
+ zone: floating content
59
+ creates: The floating content body rendered inside the popper layer.
60
+ accepts:
61
+ recommended:
62
+ - tooltip body
63
+ - menu or list content
64
+ - dropdown surface
65
+ - compact popup layout
66
+ avoid:
67
+ - full page layout
68
+ - content that relies on normal document flow
69
+ - unrelated anchor markup
70
+ layout_effect: Content is teleported into the floating layer and positioned relative to the active anchor.
71
+ notes: Content rendered inside the popper layer.
72
+ emits:
73
+ - name: update:visible
74
+ payload: boolean
75
+ notes: Main open-state update channel.
76
+ - name: show
77
+ payload: undefined
78
+ notes: Fired when the popper starts opening.
79
+ - name: shown
80
+ payload: undefined
81
+ notes: Fired when the popper is open.
82
+ - name: hide
83
+ payload: undefined
84
+ notes: Fired when the popper starts closing.
85
+ - name: hidden
86
+ payload: undefined
87
+ notes: Fired when the popper is closed.
88
+ - name: dispose
89
+ payload: undefined
90
+ notes: Fired when the layer is disposed.
91
+ - name: attached
92
+ payload: undefined
93
+ notes: Fired when the layer is attached to the DOM.
94
+
95
+ rendered_structure:
96
+ descriptive_only: true
97
+ root:
98
+ shape: div.ui-v1-popper
99
+ tag: div
100
+ zones:
101
+ - .ui-v1-popper__arrow when withArrow=true
102
+ - .ui-v1-popper__content
103
+ notes: The popper is teleported into a container and lives outside the original layout tree.
104
+
105
+ geometry:
106
+ layout: floating layer outside normal document flow
107
+ root_display: block
108
+ width_behavior: content-sized by floating content
109
+ notes:
110
+ - Position is calculated relative to the target element.
111
+ - Container controls where the DOM node is teleported.
112
+ - Placement and floating options control side, alignment, and adaptation.
113
+
114
+ styling:
115
+ notes:
116
+ - UiPopper is one of the main CSS-variable-driven primitives in the library.
117
+ - Prefer documented CSS variables over descendant selector overrides.
118
+ - Classes are mostly useful for debugging and understanding the floating surface structure.
119
+ root_classes:
120
+ - .ui-v1-popper
121
+ state_classes:
122
+ - .ui-v1-popper_hidden
123
+ - .ui-v1-popper_shown
124
+ zones:
125
+ - .ui-v1-popper__arrow
126
+ - .ui-v1-popper__content
127
+ css_variables:
128
+ public_theme_variables:
129
+ - name: --ui-v1-popper-background
130
+ effect: Surface and arrow background color.
131
+ - name: --ui-v1-popper-roundings
132
+ effect: Surface corner radius.
133
+ - name: --ui-v1-popper-arrow-roundings
134
+ effect: Arrow corner radius.
135
+ - name: --ui-v1-popper-arrow-size
136
+ effect: Arrow square size before rotation.
137
+ - name: --ui-v1-popper-width
138
+ effect: Content width.
139
+ - name: --ui-v1-popper-width-min
140
+ effect: Minimum content width.
141
+ - name: --ui-v1-popper-width-max
142
+ effect: Maximum content width.
143
+ - name: --ui-v1-popper-height
144
+ effect: Content height.
145
+ - name: --ui-v1-popper-height-min
146
+ effect: Minimum content height.
147
+ - name: --ui-v1-popper-height-max
148
+ effect: Maximum content height.
149
+ - name: --ui-v1-popper-padding
150
+ effect: Inner content padding.
151
+ - name: --ui-v1-popper-z-index
152
+ effect: Layer stacking level.
153
+ typography:
154
+ default:
155
+ mixin: text-small
156
+ size: 14px
157
+ line_height: 20px
158
+ weight: 400
159
+
160
+ behavior:
161
+ notes:
162
+ - Target-side and popper-side triggers are configured separately.
163
+ - The layer may remain open across hover or focus when configured that way.
164
+ - Outside interactions are handled through global trigger rules.
165
+
166
+ accessibility:
167
+ notes:
168
+ - UiPopper itself does not define semantic role for its content.
169
+ - ARIA semantics should come from the higher-level component using it.
170
+
171
+ composition:
172
+ works_well_with:
173
+ - UiPopperConnector
174
+ - UiPopperTarget
175
+ - UiTooltip
176
+ - UiSelect
177
+ patterns:
178
+ - title: Shared target context
179
+ notes: The target ref usually comes through UiPopperConnector and UiPopperTarget.
180
+
181
+ examples:
182
+ - title: Mental model
183
+ goal: Understand the basic target plus floating content pattern.
184
+ code: |
185
+ <UiPopperConnector>
186
+ <UiPopperTarget>
187
+ <button type="button">Open</button>
188
+ </UiPopperTarget>
189
+
190
+ <UiPopper :visible="open">
191
+ Popup content
192
+ </UiPopper>
193
+ </UiPopperConnector>
194
+
195
+ ai_notes:
196
+ do:
197
+ - Use UiPopper as low-level floating mechanics when higher-level components are not enough.
198
+ - Think in terms of target, triggers, and floating content as separate parts.
199
+ avoid:
200
+ - Do not treat UiPopper as a regular inline wrapper.
201
+ - Do not forget that it lives outside normal document flow.
@@ -0,0 +1,115 @@
1
+ component: UiPopperConnector
2
+ summary: >
3
+ UiPopperConnector is a lightweight wrapper that gives target-side and popper-side parts
4
+ a shared target context. It has almost no UI meaning on its own, but is often required
5
+ for correct target-driven floating behavior.
6
+
7
+ public_import:
8
+ from: '@retailcrm/embed-ui-v1-components/remote'
9
+ named:
10
+ - UiPopperConnector
11
+
12
+ related_components:
13
+ - UiPopper
14
+ - UiPopperTarget
15
+ - UiSelect
16
+ - UiTooltip
17
+
18
+ use_when:
19
+ - You need UiPopper and UiPopperTarget to share the same target context.
20
+ - You need the standard target-driven composition for a dropdown or tooltip.
21
+ - Your trigger already exposes its root element into connector context, for example UiButton.
22
+
23
+ avoid_when:
24
+ - You need a generic visual wrapper without popper mechanics.
25
+ - Target is passed manually and the shared connector model is not used.
26
+
27
+ api:
28
+ slots:
29
+ - name: default
30
+ zone: shared popper composition
31
+ creates: Shared target context for target-side and popper-side children.
32
+ accepts:
33
+ recommended:
34
+ - UiPopperTarget plus UiPopper
35
+ - implicit anchor trigger plus UiPopper
36
+ - tooltip-like target and floating content pairs
37
+ avoid:
38
+ - styling-only wrappers
39
+ - unrelated layout content
40
+ - children that do not participate in target or popper flow
41
+ layout_effect: Usually no direct layout effect; mainly establishes shared anchor context.
42
+ notes: Place target and popper-related children here so they share one context.
43
+
44
+ rendered_structure:
45
+ descriptive_only: true
46
+ root:
47
+ shape: no persistent DOM root
48
+ tag: none
49
+ notes: >
50
+ The connector exists mainly to provide target context. It is not a styled layout primitive.
51
+
52
+ geometry:
53
+ layout: no standalone layout of its own
54
+ root_display: none
55
+ width_behavior: defined by slotted children
56
+ notes:
57
+ - It usually has no meaningful layout behavior on its own.
58
+ - Treat it as a context wrapper, not as a visual block.
59
+
60
+ behavior:
61
+ notes:
62
+ - Stores or forwards the shared target element reference.
63
+ - Lets UiPopperTarget and UiPopper use the same anchor context.
64
+ - If a child component already exposes its root element into connector context, explicit UiPopperTarget may be unnecessary.
65
+ - UiButton is a practical example: inside UiPopperConnector it can act as the anchor without an extra UiPopperTarget wrapper.
66
+
67
+ accessibility:
68
+ notes:
69
+ - Does not create ARIA semantics by itself.
70
+
71
+ composition:
72
+ works_well_with:
73
+ - UiPopperTarget
74
+ - UiPopper
75
+ - UiTooltip
76
+ - UiSelect
77
+ patterns:
78
+ - title: Implicit anchor
79
+ notes: Connector alone is enough when the trigger already provides a stable root element.
80
+ - title: Explicit anchor
81
+ notes: Add UiPopperTarget only when the anchor must be limited to a specific wrapper or sub-area.
82
+
83
+ examples:
84
+ - title: Shared target context
85
+ goal: Connect target and popper through one shared wrapper.
86
+ code: |
87
+ <UiPopperConnector>
88
+ <UiPopperTarget>
89
+ <button type="button">Open</button>
90
+ </UiPopperTarget>
91
+
92
+ <UiPopper :visible="open">
93
+ Content
94
+ </UiPopper>
95
+ </UiPopperConnector>
96
+ - title: Connector without explicit target
97
+ goal: Use a button as the implicit anchor.
98
+ code: |
99
+ <UiPopperConnector>
100
+ <UiButton appearance="secondary">
101
+ Open
102
+ </UiButton>
103
+
104
+ <UiPopper :visible="open">
105
+ Content
106
+ </UiPopper>
107
+ </UiPopperConnector>
108
+
109
+ ai_notes:
110
+ do:
111
+ - Use UiPopperConnector when a higher-level component expects shared target context.
112
+ - Prefer connector-only composition when the trigger already exposes the correct root element.
113
+ avoid:
114
+ - Do not use it as a styling wrapper.
115
+ - Do not add UiPopperTarget automatically around every trigger.
@@ -0,0 +1,118 @@
1
+ component: UiPopperTarget
2
+ summary: >
3
+ UiPopperTarget is the target-side wrapper that registers a DOM element in popper context.
4
+ A good mental model is "this node is the anchor", not "this is a visual layout wrapper".
5
+
6
+ public_import:
7
+ from: '@retailcrm/embed-ui-v1-components/remote'
8
+ named:
9
+ - UiPopperTarget
10
+
11
+ related_components:
12
+ - UiPopper
13
+ - UiPopperConnector
14
+ - UiSelect
15
+ - UiTooltip
16
+
17
+ use_when:
18
+ - You need to explicitly mark the anchor element for UiPopper or a tooltip.
19
+ - You need to wrap a trigger and register it as the anchor in shared popper context.
20
+ - You need the floating layer to anchor to only part of a larger layout.
21
+
22
+ avoid_when:
23
+ - You need a styling-only wrapper.
24
+ - Target ref is already passed manually and the connector model is not used.
25
+ - The trigger already exposes a suitable root element through UiPopperConnector, for example UiButton.
26
+
27
+ api:
28
+ props:
29
+ - name: tag
30
+ notes: Wrapper tag name. Default is div.
31
+ slots:
32
+ - name: default
33
+ zone: target content
34
+ creates: The explicit anchor wrapper for the floating layer.
35
+ accepts:
36
+ recommended:
37
+ - one trigger node
38
+ - one title wrapper
39
+ - one compact anchor area
40
+ avoid:
41
+ - large unrelated layout trees
42
+ - content that should not define the anchor bounds
43
+ - multiple disconnected anchor areas
44
+ layout_effect: The wrapper becomes the anchor bounds used by popper positioning.
45
+ notes: Put the trigger or anchor node inside this slot.
46
+
47
+ rendered_structure:
48
+ descriptive_only: true
49
+ root:
50
+ shape: configurable wrapper tag
51
+ tag: configurable, div by default
52
+ notes: >
53
+ The component renders a configurable wrapper tag and stores its element ref in popper context.
54
+ It does not add complex UI logic on its own.
55
+
56
+ geometry:
57
+ layout: wrapper defined by the chosen tag
58
+ root_display: depends on the chosen tag
59
+ width_behavior: follows the chosen tag and its children
60
+ notes:
61
+ - Layout depends on the chosen tag and its children.
62
+ - Its main purpose is to provide the correct anchor ref for the popper.
63
+
64
+ behavior:
65
+ notes:
66
+ - On mount and update, it forwards the current element ref into popper context.
67
+ - It is the target-side part of the UiPopperConnector + UiPopperTarget + UiPopper pattern.
68
+ - It is optional, not mandatory.
69
+ - Use it when you need an explicit wrapper as the anchor; skip it when connector already receives the right element.
70
+
71
+ accessibility:
72
+ notes:
73
+ - It does not create ARIA semantics. Those should come from the inner trigger.
74
+
75
+ composition:
76
+ works_well_with:
77
+ - UiPopperConnector
78
+ - UiPopper
79
+ - UiTooltip
80
+ patterns:
81
+ - title: Dedicated anchor wrapper
82
+ notes: Use a separate target wrapper when the floating layer should anchor to only part of a layout.
83
+ - title: Not always needed
84
+ notes: Connector-only composition is enough when the trigger already exposes its root element.
85
+
86
+ examples:
87
+ - title: Tooltip anchor
88
+ goal: Anchor a floating layer to a specific title or button wrapper.
89
+ code: |
90
+ <UiPopperConnector>
91
+ <UiPopperTarget tag="span">
92
+ <span>Title</span>
93
+ </UiPopperTarget>
94
+
95
+ <UiPopper :visible="open">
96
+ Tooltip
97
+ </UiPopper>
98
+ </UiPopperConnector>
99
+ - title: Explicit title-only anchor
100
+ goal: Bind the floating layer to a title wrapper instead of the whole row.
101
+ code: |
102
+ <UiPopperConnector>
103
+ <UiPopperTarget tag="span">
104
+ <span class="header-title">Title</span>
105
+ </UiPopperTarget>
106
+
107
+ <UiPopper :visible="open">
108
+ Tooltip
109
+ </UiPopper>
110
+ </UiPopperConnector>
111
+
112
+ ai_notes:
113
+ do:
114
+ - Use UiPopperTarget when the anchor should be limited to a specific part of the layout.
115
+ - Use it intentionally, not by default.
116
+ avoid:
117
+ - Do not treat the wrapper as decorative only; it affects what the floating layer anchors to.
118
+ - Do not wrap every UiButton or similar trigger with UiPopperTarget if connector already gives the correct anchor.
@@ -0,0 +1,38 @@
1
+ component: UiRadio
2
+ summary: >
3
+ UiRadio is the single-choice selection control for exclusive option sets.
4
+ It is the radio-style counterpart to UiCheckbox.
5
+
6
+ public_import:
7
+ from: '@retailcrm/embed-ui-v1-components/remote'
8
+ named:
9
+ - UiRadio
10
+
11
+ use_when:
12
+ - You need one selected value from a fixed set.
13
+
14
+ avoid_when:
15
+ - You need multiple independent selections, use UiCheckbox instead.
16
+
17
+ api:
18
+ key_props:
19
+ - name: model
20
+ - name: value
21
+ - name: required
22
+ - name: disabled
23
+ methods:
24
+ - name: click
25
+ - name: focus
26
+ - name: blur
27
+
28
+ rendered_structure:
29
+ descriptive_only: true
30
+ root:
31
+ shape: span.ui-v1-radio
32
+ tag: span
33
+ notes: One inline wrapper around the visual radio control and label content.
34
+
35
+ geometry:
36
+ layout: inline radio control
37
+ root_display: inline-flex
38
+ width_behavior: content-sized by default
@@ -0,0 +1,231 @@
1
+ component: UiRadioSwitch
2
+ summary: >
3
+ UiRadioSwitch is a single-choice segmented control with two practical modes:
4
+ a compact inline switch and a richer section-card layout. It is useful when the
5
+ choice set is small and always visible. For richer per-option content, compose it
6
+ with UiRadioSwitchOption instead of relying only on the options array.
7
+
8
+ public_import:
9
+ from: '@retailcrm/embed-ui-v1-components/remote'
10
+ named:
11
+ - UiRadioSwitch
12
+ - UiRadioSwitchOption
13
+
14
+ related_components:
15
+ - UiRadio
16
+ - UiField
17
+ - UiRadioSwitchOption
18
+
19
+ use_when:
20
+ - You need one selected value from a small fixed set.
21
+ - You want a segmented control instead of classic radio circles.
22
+ - You need a card-like section switch with descriptions.
23
+ - You need object values and must compare them through equalFn.
24
+
25
+ avoid_when:
26
+ - You need multiple independent selections.
27
+ - You need dozens of options or searchable choice, use UiSelect instead.
28
+ - You need free-form content unrelated to a single-choice switch.
29
+
30
+ api:
31
+ key_props:
32
+ - name: value
33
+ notes: Current selected value.
34
+ - name: options
35
+ notes: Quick array-based way to declare simple options.
36
+ - name: equalFn
37
+ notes: Important when option values are objects or other non-primitives.
38
+ - name: appearance
39
+ notes: Switches between default inline mode and section card mode.
40
+ - name: size
41
+ notes: Controls option height and icon sizing in default mode.
42
+ - name: rubber
43
+ notes: Makes the root behave like inline-flex instead of stretching full width.
44
+ props:
45
+ - name: value
46
+ notes: Works as the single selected model value.
47
+ - name: options
48
+ notes: Expects array items shaped as { label, value, disabled }.
49
+ - name: equalFn
50
+ notes: Defaults to strict equality.
51
+ - name: appearance
52
+ notes: Supports default and section.
53
+ - name: size
54
+ notes: Supports sm, md, lg.
55
+ - name: rubber
56
+ notes: Useful when the switch should size to content.
57
+ child_components:
58
+ - name: UiRadioSwitchOption
59
+ key_props:
60
+ - value
61
+ - label
62
+ - description
63
+ - disabled
64
+ notes: >
65
+ Use it when an option needs description, custom icon, custom label, or
66
+ custom checkmark content.
67
+ slots:
68
+ - name: default
69
+ zone: option tree
70
+ creates: Replaces array-based options with manually declared UiRadioSwitchOption nodes.
71
+ accepts:
72
+ recommended:
73
+ - UiRadioSwitchOption
74
+ avoid:
75
+ - arbitrary interactive controls
76
+ - unrelated wrappers
77
+ notes: >
78
+ The simplest path is options for plain labels, and default slot for richer
79
+ option markup.
80
+ - name: icon
81
+ zone: shared option icon in options mode
82
+ notes: >
83
+ Used only when options array mode renders generated options. For per-option
84
+ rich composition, use UiRadioSwitchOption slots instead.
85
+ emits:
86
+ - name: change
87
+ payload: unknown
88
+ notes: Fired when the selected value changes.
89
+ - name: update:value
90
+ payload: unknown
91
+ notes: Main v-model channel.
92
+
93
+ rendered_structure:
94
+ descriptive_only: true
95
+ notes: >
96
+ The component renders as one radiogroup root and a list of option shells with
97
+ radio semantics. This section is for mental modeling and debugging, not as a
98
+ stable styling contract.
99
+ root:
100
+ shape: div.ui-v1-radio-switch
101
+ tag: div
102
+ composition:
103
+ - UiRadioSwitch root with role=radiogroup
104
+ - UiRadioSwitchOption shells with role=radio
105
+ - section mode can add description and selected-state checkmark
106
+ classes:
107
+ - .ui-v1-radio-switch
108
+ - .ui-v1-radio-switch_borderless
109
+ - .ui-v1-radio-switch_rubber
110
+ - .ui-v1-radio-switch-option
111
+ - .ui-v1-radio-switch-option_default
112
+ - .ui-v1-radio-switch-option_standalone
113
+ - .ui-v1-radio-switch-option_active
114
+ - .ui-v1-radio-switch-option_disabled
115
+
116
+ geometry:
117
+ layout: flex row for default mode, wrapping card row for section mode
118
+ root_display:
119
+ default: flex
120
+ rubber: inline-flex
121
+ width_behavior: stretches by default, content-sized with rubber
122
+ notes:
123
+ - Default appearance behaves like a segmented control with adjacent options.
124
+ - Section appearance removes the outer border and lets cards wrap to a new line.
125
+ - rubber makes the root inline-sized instead of full-width.
126
+ - In section mode each option has a large minimum width and card-like padding.
127
+
128
+ styling:
129
+ notes:
130
+ - Current classes describe host DOM structure and states.
131
+ - Prefer appearance, size, and rubber over selector-level customization.
132
+ root_classes:
133
+ - .ui-v1-radio-switch
134
+ - .ui-v1-radio-switch-option
135
+ state_classes:
136
+ - .ui-v1-radio-switch_borderless
137
+ - .ui-v1-radio-switch_rubber
138
+ - .ui-v1-radio-switch-option_default
139
+ - .ui-v1-radio-switch-option_standalone
140
+ - .ui-v1-radio-switch-option_active
141
+ - .ui-v1-radio-switch-option_disabled
142
+ zones:
143
+ - .ui-v1-radio-switch-option__head
144
+ - .ui-v1-radio-switch-option__icon
145
+ - .ui-v1-radio-switch-option__label
146
+ - .ui-v1-radio-switch-option__description
147
+ - .ui-v1-radio-switch-option__done
148
+ typography:
149
+ default:
150
+ notes:
151
+ - Default mode uses regular text sizing.
152
+ - Section mode uses accent heading-like styling for the main label.
153
+
154
+ behavior:
155
+ states:
156
+ - name: appearance=default
157
+ notes: Renders a compact segmented control.
158
+ - name: appearance=section
159
+ notes: Renders standalone cards with optional description and selected checkmark.
160
+ - name: disabled
161
+ notes: Disabled options cannot be selected or focused by keyboard navigation.
162
+ - name: rubber
163
+ notes: Keeps the root content-sized.
164
+ selection_and_matching:
165
+ - The component is always single-select.
166
+ - update:value and change are emitted together on selection change.
167
+ - equalFn should usually be provided when values are objects.
168
+ - In options mode the component generates UiRadioSwitchOption nodes internally.
169
+ keyboard:
170
+ - One tab stop is used for the whole group.
171
+ - ArrowLeft, ArrowRight, ArrowUp, and ArrowDown move focus and selection across enabled options.
172
+ - Home and End jump to the first or last enabled option.
173
+ - Space and Enter select the currently focused option.
174
+
175
+ accessibility:
176
+ notes:
177
+ - The root acts as radiogroup.
178
+ - Each option acts as radio and exposes aria-checked and aria-disabled.
179
+ - The current implementation uses roving tabindex so only one option is tabbable.
180
+
181
+ composition:
182
+ works_well_with:
183
+ - UiField
184
+ - UiRadioSwitchOption
185
+ patterns:
186
+ - title: Simple mode switch
187
+ notes: Use options for a small plain-text set such as view or status mode.
188
+ - title: Section cards
189
+ notes: Use UiRadioSwitchOption when each choice needs icon, description, or custom checkmark.
190
+
191
+ examples:
192
+ - title: Simple options array
193
+ goal: Build a compact single-choice segmented control.
194
+ code: |
195
+ <UiRadioSwitch
196
+ v-model:value="mode"
197
+ :options="[
198
+ { label: 'Auto', value: 'auto' },
199
+ { label: 'Manual', value: 'manual' },
200
+ ]"
201
+ />
202
+ - title: Rich card options
203
+ goal: Render section cards with object values and descriptions.
204
+ code: |
205
+ <UiRadioSwitch
206
+ v-model:value="mode"
207
+ appearance="section"
208
+ rubber
209
+ :equal-fn="(a, b) => a?.key === b?.key"
210
+ >
211
+ <UiRadioSwitchOption
212
+ label="Auto"
213
+ :value="{ key: 'auto' }"
214
+ description="Automatic mode"
215
+ />
216
+
217
+ <UiRadioSwitchOption
218
+ label="Manual"
219
+ :value="{ key: 'manual' }"
220
+ description="Manual setup"
221
+ />
222
+ </UiRadioSwitch>
223
+
224
+ ai_notes:
225
+ do:
226
+ - Use options for simple text-only cases.
227
+ - Switch to UiRadioSwitchOption when a choice needs richer content.
228
+ - Provide equalFn for object values instead of relying on reference equality.
229
+ avoid:
230
+ - Do not use it for multi-select flows.
231
+ - Do not treat internal .ui-v1-* classes as a stable extension styling API.