@ankhorage/zora 4.3.0 → 4.4.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/CHANGELOG.md +6 -0
- package/dist/components/radio/RadioGroup.d.ts.map +1 -1
- package/dist/components/radio/RadioGroup.js +27 -7
- package/dist/components/radio/RadioGroup.js.map +1 -1
- package/dist/components/radio/meta.d.ts +203 -4
- package/dist/components/radio/meta.d.ts.map +1 -1
- package/dist/components/radio/meta.js +168 -4
- package/dist/components/radio/meta.js.map +1 -1
- package/dist/components/radio/resolveRadioGroupThemeRecipe.d.ts +20 -0
- package/dist/components/radio/resolveRadioGroupThemeRecipe.d.ts.map +1 -0
- package/dist/components/radio/resolveRadioGroupThemeRecipe.js +34 -0
- package/dist/components/radio/resolveRadioGroupThemeRecipe.js.map +1 -0
- package/dist/components/radio/themeRecipeMeta.d.ts +26 -0
- package/dist/components/radio/themeRecipeMeta.d.ts.map +1 -0
- package/dist/components/radio/themeRecipeMeta.js +27 -0
- package/dist/components/radio/themeRecipeMeta.js.map +1 -0
- package/dist/components/radio/types.d.ts +1 -0
- package/dist/components/radio/types.d.ts.map +1 -1
- package/dist/components/radio/types.js.map +1 -1
- package/dist/metadata/themeRecipeMeta.d.ts.map +1 -1
- package/dist/metadata/themeRecipeMeta.js +2 -0
- package/dist/metadata/themeRecipeMeta.js.map +1 -1
- package/package.json +1 -1
- package/src/components/radio/RadioGroup.test.ts +31 -0
- package/src/components/radio/RadioGroup.tsx +45 -8
- package/src/components/radio/meta.ts +170 -4
- package/src/components/radio/resolveRadioGroupThemeRecipe.ts +45 -0
- package/src/components/radio/themeRecipeMeta.ts +28 -0
- package/src/components/radio/types.ts +1 -0
- package/src/metadata/componentMeta.test.ts +21 -0
- package/src/metadata/themeRecipeMeta.test.ts +4 -0
- package/src/metadata/themeRecipeMeta.ts +2 -0
package/CHANGELOG.md
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RadioGroup.d.ts","sourceRoot":"","sources":["../../../src/components/radio/RadioGroup.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"RadioGroup.d.ts","sourceRoot":"","sources":["../../../src/components/radio/RadioGroup.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAQ1B,OAAO,KAAK,EAAoB,eAAe,EAAE,MAAM,SAAS,CAAC;AA6DjE;;GAEG;AACH,eAAO,MAAM,UAAU,GA3DE,MAAM,SAAS,MAAM,8DA2De,CAAC"}
|
|
@@ -1,17 +1,24 @@
|
|
|
1
|
-
import { Radio } from '@ankhorage/surface';
|
|
1
|
+
import { Radio, useTheme } from '@ankhorage/surface';
|
|
2
2
|
import React from 'react';
|
|
3
3
|
import { View } from 'react-native';
|
|
4
4
|
import { Stack } from '../../foundation';
|
|
5
|
+
import { useZoraThemeRecipe } from '../../theme/useZoraThemeRecipe';
|
|
5
6
|
import { withZoraThemeScope } from '../../theme/withZoraThemeScope';
|
|
6
7
|
import { Text } from '../text';
|
|
7
|
-
|
|
8
|
+
import { resolveRadioGroupThemeRecipe } from './resolveRadioGroupThemeRecipe';
|
|
9
|
+
/***
|
|
10
|
+
* Resolves the themed radio-group presentation within the active ZORA scope.
|
|
11
|
+
*/
|
|
12
|
+
function RadioGroupInner({ themeId: _themeId, mode: _mode, value, onValueChange, options, orientation = 'vertical', gap, presentation = 'inline', color, size, invalid = false, readOnly = false, disabled = false, testID, interactionPolicy, }) {
|
|
8
13
|
const isHorizontal = orientation === 'horizontal';
|
|
14
|
+
const themeFields = useZoraThemeRecipe('RadioGroup');
|
|
15
|
+
const recipe = resolveRadioGroupThemeRecipe({ gap, color, size, themeFields });
|
|
9
16
|
return (<View testID={testID} accessibilityRole="radiogroup" style={{
|
|
10
17
|
flexDirection: isHorizontal ? 'row' : 'column',
|
|
11
18
|
flexWrap: isHorizontal ? 'wrap' : 'nowrap',
|
|
12
19
|
}}>
|
|
13
|
-
<Stack direction={isHorizontal ? 'row' : 'column'} gap={gap} wrap={isHorizontal ? 'wrap' : 'nowrap'}>
|
|
14
|
-
{options.map((option) => (<RadioGroupItem key={option.value} option={option} checked={value === option.value} disabled={disabled || option.disabled === true} invalid={invalid} readOnly={readOnly} size={size} color={color} onSelect={onValueChange} interactionPolicy={interactionPolicy}/>))}
|
|
20
|
+
<Stack direction={isHorizontal ? 'row' : 'column'} gap={recipe.gap} wrap={isHorizontal ? 'wrap' : 'nowrap'}>
|
|
21
|
+
{options.map((option) => (<RadioGroupItem key={option.value} option={option} checked={value === option.value} disabled={disabled || option.disabled === true} invalid={invalid} readOnly={readOnly} size={recipe.size} color={recipe.color} orientation={orientation} presentation={presentation} onSelect={onValueChange} interactionPolicy={interactionPolicy}/>))}
|
|
15
22
|
</Stack>
|
|
16
23
|
</View>);
|
|
17
24
|
}
|
|
@@ -19,16 +26,29 @@ function RadioGroupInner({ themeId: _themeId, mode: _mode, value, onValueChange,
|
|
|
19
26
|
* Renders a group of radio options for selecting a single value.
|
|
20
27
|
*/
|
|
21
28
|
export const RadioGroup = withZoraThemeScope(RadioGroupInner);
|
|
22
|
-
|
|
29
|
+
/***
|
|
30
|
+
* Renders one option through the single Surface Radio interaction boundary.
|
|
31
|
+
*/
|
|
32
|
+
function RadioGroupItem({ option, checked, disabled, invalid, readOnly, size, color, orientation, presentation, onSelect, interactionPolicy, }) {
|
|
33
|
+
const { theme } = useTheme();
|
|
23
34
|
const passive = interactionPolicy === 'passive';
|
|
24
|
-
|
|
35
|
+
const isCard = presentation === 'card';
|
|
36
|
+
return (<Radio interactionPolicy={interactionPolicy} checked={checked} disabled={disabled} invalid={invalid} readOnly={readOnly} size={size} color={color} testID={option.testID} bg={isCard
|
|
37
|
+
? checked
|
|
38
|
+
? theme.semantics.selection.background
|
|
39
|
+
: theme.semantics.surface.default
|
|
40
|
+
: undefined} borderColor={isCard
|
|
41
|
+
? checked
|
|
42
|
+
? theme.semantics.selection.border
|
|
43
|
+
: theme.semantics.border.default
|
|
44
|
+
: undefined} borderWidth={isCard ? 1 : undefined} p={isCard ? 'm' : undefined} radius={isCard ? 'l' : undefined} width={isCard && orientation === 'vertical' ? '100%' : undefined} onCheckedChange={(nextChecked) => {
|
|
25
45
|
if (passive)
|
|
26
46
|
return;
|
|
27
47
|
if (nextChecked)
|
|
28
48
|
onSelect(option.value);
|
|
29
49
|
}}>
|
|
30
50
|
<Stack gap="xs">
|
|
31
|
-
<Text>{option.label}</Text>
|
|
51
|
+
<Text weight={isCard ? 'semiBold' : undefined}>{option.label}</Text>
|
|
32
52
|
{option.description ? (<Text emphasis="muted" variant="caption">
|
|
33
53
|
{option.description}
|
|
34
54
|
</Text>) : null}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RadioGroup.js","sourceRoot":"","sources":["../../../src/components/radio/RadioGroup.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"RadioGroup.js","sourceRoot":"","sources":["../../../src/components/radio/RadioGroup.tsx"],"names":[],"mappings":"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","sourcesContent":["import { Radio, useTheme } from '@ankhorage/surface';\nimport React from 'react';\nimport { View } from 'react-native';\n\nimport { Stack } from '../../foundation';\nimport { useZoraThemeRecipe } from '../../theme/useZoraThemeRecipe';\nimport { withZoraThemeScope } from '../../theme/withZoraThemeScope';\nimport { Text } from '../text';\nimport { resolveRadioGroupThemeRecipe } from './resolveRadioGroupThemeRecipe';\nimport type { RadioGroupOption, RadioGroupProps } from './types';\n\n/***\n * Resolves the themed radio-group presentation within the active ZORA scope.\n */\nfunction RadioGroupInner<TValue extends string>({\n themeId: _themeId,\n mode: _mode,\n value,\n onValueChange,\n options,\n orientation = 'vertical',\n gap,\n presentation = 'inline',\n color,\n size,\n invalid = false,\n readOnly = false,\n disabled = false,\n testID,\n interactionPolicy,\n}: RadioGroupProps<TValue>) {\n const isHorizontal = orientation === 'horizontal';\n const themeFields = useZoraThemeRecipe('RadioGroup');\n const recipe = resolveRadioGroupThemeRecipe({ gap, color, size, themeFields });\n\n return (\n <View\n testID={testID}\n accessibilityRole=\"radiogroup\"\n style={{\n flexDirection: isHorizontal ? 'row' : 'column',\n flexWrap: isHorizontal ? 'wrap' : 'nowrap',\n }}\n >\n <Stack\n direction={isHorizontal ? 'row' : 'column'}\n gap={recipe.gap}\n wrap={isHorizontal ? 'wrap' : 'nowrap'}\n >\n {options.map((option) => (\n <RadioGroupItem\n key={option.value}\n option={option}\n checked={value === option.value}\n disabled={disabled || option.disabled === true}\n invalid={invalid}\n readOnly={readOnly}\n size={recipe.size}\n color={recipe.color}\n orientation={orientation}\n presentation={presentation}\n onSelect={onValueChange}\n interactionPolicy={interactionPolicy}\n />\n ))}\n </Stack>\n </View>\n );\n}\n\n/***\n * Renders a group of radio options for selecting a single value.\n */\nexport const RadioGroup = withZoraThemeScope(RadioGroupInner);\n\n/***\n * Renders one option through the single Surface Radio interaction boundary.\n */\nfunction RadioGroupItem<TValue extends string>({\n option,\n checked,\n disabled,\n invalid,\n readOnly,\n size,\n color,\n orientation,\n presentation,\n onSelect,\n interactionPolicy,\n}: {\n option: RadioGroupOption<TValue>;\n checked: boolean;\n disabled: boolean;\n invalid: boolean;\n readOnly: boolean;\n size: NonNullable<RadioGroupProps<TValue>['size']>;\n color: NonNullable<RadioGroupProps<TValue>['color']>;\n orientation: NonNullable<RadioGroupProps<TValue>['orientation']>;\n presentation: NonNullable<RadioGroupProps<TValue>['presentation']>;\n onSelect: (value: TValue) => void;\n interactionPolicy: RadioGroupProps<TValue>['interactionPolicy'];\n}) {\n const { theme } = useTheme();\n const passive = interactionPolicy === 'passive';\n const isCard = presentation === 'card';\n\n return (\n <Radio\n interactionPolicy={interactionPolicy}\n checked={checked}\n disabled={disabled}\n invalid={invalid}\n readOnly={readOnly}\n size={size}\n color={color}\n testID={option.testID}\n bg={\n isCard\n ? checked\n ? theme.semantics.selection.background\n : theme.semantics.surface.default\n : undefined\n }\n borderColor={\n isCard\n ? checked\n ? theme.semantics.selection.border\n : theme.semantics.border.default\n : undefined\n }\n borderWidth={isCard ? 1 : undefined}\n p={isCard ? 'm' : undefined}\n radius={isCard ? 'l' : undefined}\n width={isCard && orientation === 'vertical' ? '100%' : undefined}\n onCheckedChange={(nextChecked) => {\n if (passive) return;\n if (nextChecked) onSelect(option.value);\n }}\n >\n <Stack gap=\"xs\">\n <Text weight={isCard ? 'semiBold' : undefined}>{option.label}</Text>\n {option.description ? (\n <Text emphasis=\"muted\" variant=\"caption\">\n {option.description}\n </Text>\n ) : null}\n </Stack>\n </Radio>\n );\n}\n"]}
|
|
@@ -3,15 +3,214 @@ export declare const radioMeta: {
|
|
|
3
3
|
readonly category: "component";
|
|
4
4
|
readonly directManifestNode: false;
|
|
5
5
|
readonly allowedChildren: readonly [];
|
|
6
|
-
readonly note: "
|
|
6
|
+
readonly note: "Composition-level radio control; author repeated single-choice UI through RadioGroup.";
|
|
7
7
|
readonly props: {};
|
|
8
8
|
};
|
|
9
9
|
export declare const radioGroupMeta: {
|
|
10
10
|
readonly name: "RadioGroup";
|
|
11
11
|
readonly category: "component";
|
|
12
|
-
readonly
|
|
12
|
+
readonly description: "Single-choice group with inline or card presentation while preserving radio semantics.";
|
|
13
|
+
readonly directManifestNode: true;
|
|
13
14
|
readonly allowedChildren: readonly [];
|
|
14
|
-
readonly
|
|
15
|
-
|
|
15
|
+
readonly blueprint: {
|
|
16
|
+
readonly label: "Radio group";
|
|
17
|
+
readonly defaultProps: {
|
|
18
|
+
readonly value: "option-b";
|
|
19
|
+
readonly options: readonly [{
|
|
20
|
+
readonly value: "option-a";
|
|
21
|
+
readonly label: "First option";
|
|
22
|
+
readonly description: "Supporting detail";
|
|
23
|
+
}, {
|
|
24
|
+
readonly value: "option-b";
|
|
25
|
+
readonly label: "Second option";
|
|
26
|
+
readonly description: "Supporting detail";
|
|
27
|
+
}, {
|
|
28
|
+
readonly value: "option-c";
|
|
29
|
+
readonly label: "Third option";
|
|
30
|
+
readonly description: "Supporting detail";
|
|
31
|
+
}];
|
|
32
|
+
readonly orientation: "vertical";
|
|
33
|
+
readonly presentation: "inline";
|
|
34
|
+
readonly invalid: false;
|
|
35
|
+
readonly readOnly: false;
|
|
36
|
+
readonly disabled: false;
|
|
37
|
+
};
|
|
38
|
+
};
|
|
39
|
+
readonly bindings: {
|
|
40
|
+
readonly props: {
|
|
41
|
+
readonly value: {
|
|
42
|
+
readonly label: "Value";
|
|
43
|
+
readonly description: "Currently selected option value.";
|
|
44
|
+
readonly value: {
|
|
45
|
+
readonly type: "string";
|
|
46
|
+
};
|
|
47
|
+
readonly acceptsFallback: true;
|
|
48
|
+
readonly acceptsTransforms: true;
|
|
49
|
+
};
|
|
50
|
+
readonly disabled: {
|
|
51
|
+
readonly label: "Disabled";
|
|
52
|
+
readonly description: "Whether the complete radio group is disabled.";
|
|
53
|
+
readonly value: {
|
|
54
|
+
readonly type: "boolean";
|
|
55
|
+
};
|
|
56
|
+
readonly acceptsFallback: true;
|
|
57
|
+
readonly acceptsTransforms: true;
|
|
58
|
+
};
|
|
59
|
+
};
|
|
60
|
+
readonly events: {
|
|
61
|
+
readonly valueChange: {
|
|
62
|
+
readonly label: "Value change";
|
|
63
|
+
readonly description: "Runs when the selected radio value changes.";
|
|
64
|
+
readonly payload: {
|
|
65
|
+
readonly eventType: "radioGroup.valueChange";
|
|
66
|
+
readonly fields: readonly [{
|
|
67
|
+
readonly path: "value";
|
|
68
|
+
readonly type: "string";
|
|
69
|
+
readonly label: "Value";
|
|
70
|
+
}];
|
|
71
|
+
};
|
|
72
|
+
};
|
|
73
|
+
};
|
|
74
|
+
};
|
|
75
|
+
readonly events: {
|
|
76
|
+
readonly valueChange: {
|
|
77
|
+
readonly label: "Value change";
|
|
78
|
+
readonly eventType: "radioGroup.valueChange";
|
|
79
|
+
readonly description: "Emitted when the selected radio value changes.";
|
|
80
|
+
readonly payloadFields: readonly [{
|
|
81
|
+
readonly path: "value";
|
|
82
|
+
readonly type: "string";
|
|
83
|
+
readonly label: "Value";
|
|
84
|
+
}];
|
|
85
|
+
};
|
|
86
|
+
};
|
|
87
|
+
readonly props: {
|
|
88
|
+
readonly value: {
|
|
89
|
+
readonly type: "string";
|
|
90
|
+
readonly category: "State";
|
|
91
|
+
readonly label: "Value";
|
|
92
|
+
readonly authoring: {
|
|
93
|
+
readonly authority: "instance";
|
|
94
|
+
};
|
|
95
|
+
};
|
|
96
|
+
readonly options: {
|
|
97
|
+
readonly type: "array";
|
|
98
|
+
readonly category: "Content";
|
|
99
|
+
readonly label: "Options";
|
|
100
|
+
readonly itemSchema: readonly [{
|
|
101
|
+
readonly key: "value";
|
|
102
|
+
readonly schema: {
|
|
103
|
+
readonly type: "string";
|
|
104
|
+
readonly category: "Content";
|
|
105
|
+
readonly label: "Value";
|
|
106
|
+
};
|
|
107
|
+
}, {
|
|
108
|
+
readonly key: "label";
|
|
109
|
+
readonly schema: {
|
|
110
|
+
readonly type: "string";
|
|
111
|
+
readonly category: "Content";
|
|
112
|
+
readonly label: "Label";
|
|
113
|
+
};
|
|
114
|
+
}, {
|
|
115
|
+
readonly key: "description";
|
|
116
|
+
readonly schema: {
|
|
117
|
+
readonly type: "string";
|
|
118
|
+
readonly category: "Content";
|
|
119
|
+
readonly label: "Description";
|
|
120
|
+
};
|
|
121
|
+
}, {
|
|
122
|
+
readonly key: "disabled";
|
|
123
|
+
readonly schema: {
|
|
124
|
+
readonly type: "boolean";
|
|
125
|
+
readonly category: "State";
|
|
126
|
+
readonly label: "Disabled";
|
|
127
|
+
readonly default: false;
|
|
128
|
+
};
|
|
129
|
+
}];
|
|
130
|
+
readonly authoring: {
|
|
131
|
+
readonly authority: "instance";
|
|
132
|
+
};
|
|
133
|
+
};
|
|
134
|
+
readonly orientation: {
|
|
135
|
+
readonly type: "enum";
|
|
136
|
+
readonly category: "Layout";
|
|
137
|
+
readonly label: "Orientation";
|
|
138
|
+
readonly enum: readonly ["horizontal", "vertical"];
|
|
139
|
+
readonly default: "vertical";
|
|
140
|
+
readonly authoring: {
|
|
141
|
+
readonly authority: "instance";
|
|
142
|
+
};
|
|
143
|
+
};
|
|
144
|
+
readonly gap: {
|
|
145
|
+
readonly type: "enum";
|
|
146
|
+
readonly category: "Layout";
|
|
147
|
+
readonly label: "Gap";
|
|
148
|
+
readonly enum: readonly ["xs", "s", "m", "l"];
|
|
149
|
+
readonly authoring: {
|
|
150
|
+
readonly authority: "theme";
|
|
151
|
+
readonly scope: "component";
|
|
152
|
+
readonly allowInstanceOverride: true;
|
|
153
|
+
};
|
|
154
|
+
};
|
|
155
|
+
readonly presentation: {
|
|
156
|
+
readonly type: "enum";
|
|
157
|
+
readonly category: "Style";
|
|
158
|
+
readonly label: "Presentation";
|
|
159
|
+
readonly enum: readonly ["inline", "card"];
|
|
160
|
+
readonly default: "inline";
|
|
161
|
+
readonly authoring: {
|
|
162
|
+
readonly authority: "instance";
|
|
163
|
+
};
|
|
164
|
+
};
|
|
165
|
+
readonly color: {
|
|
166
|
+
readonly type: "enum";
|
|
167
|
+
readonly category: "Style";
|
|
168
|
+
readonly label: "Color";
|
|
169
|
+
readonly enum: readonly ["primary", "secondary", "tertiary", "quaternary", "neutral", "success", "warning", "error", "info", "danger"];
|
|
170
|
+
readonly authoring: {
|
|
171
|
+
readonly authority: "theme";
|
|
172
|
+
readonly scope: "component";
|
|
173
|
+
readonly allowInstanceOverride: true;
|
|
174
|
+
};
|
|
175
|
+
};
|
|
176
|
+
readonly size: {
|
|
177
|
+
readonly type: "enum";
|
|
178
|
+
readonly category: "Style";
|
|
179
|
+
readonly label: "Size";
|
|
180
|
+
readonly enum: readonly ["s", "m", "l"];
|
|
181
|
+
readonly authoring: {
|
|
182
|
+
readonly authority: "theme";
|
|
183
|
+
readonly scope: "component";
|
|
184
|
+
readonly allowInstanceOverride: true;
|
|
185
|
+
};
|
|
186
|
+
};
|
|
187
|
+
readonly invalid: {
|
|
188
|
+
readonly type: "boolean";
|
|
189
|
+
readonly category: "State";
|
|
190
|
+
readonly label: "Invalid";
|
|
191
|
+
readonly default: false;
|
|
192
|
+
readonly authoring: {
|
|
193
|
+
readonly authority: "instance";
|
|
194
|
+
};
|
|
195
|
+
};
|
|
196
|
+
readonly readOnly: {
|
|
197
|
+
readonly type: "boolean";
|
|
198
|
+
readonly category: "State";
|
|
199
|
+
readonly label: "Read only";
|
|
200
|
+
readonly default: false;
|
|
201
|
+
readonly authoring: {
|
|
202
|
+
readonly authority: "instance";
|
|
203
|
+
};
|
|
204
|
+
};
|
|
205
|
+
readonly disabled: {
|
|
206
|
+
readonly type: "boolean";
|
|
207
|
+
readonly category: "State";
|
|
208
|
+
readonly label: "Disabled";
|
|
209
|
+
readonly default: false;
|
|
210
|
+
readonly authoring: {
|
|
211
|
+
readonly authority: "instance";
|
|
212
|
+
};
|
|
213
|
+
};
|
|
214
|
+
};
|
|
16
215
|
};
|
|
17
216
|
//# sourceMappingURL=meta.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"meta.d.ts","sourceRoot":"","sources":["../../../src/components/radio/meta.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"meta.d.ts","sourceRoot":"","sources":["../../../src/components/radio/meta.ts"],"names":[],"mappings":"AASA,eAAO,MAAM,SAAS;;;;;;;CAOgB,CAAC;AAEvC,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsKW,CAAC"}
|
|
@@ -1,17 +1,181 @@
|
|
|
1
|
+
import { ZORA_COLORS } from '../../internal/colorModel';
|
|
2
|
+
const themeAuthoring = {
|
|
3
|
+
authority: 'theme',
|
|
4
|
+
scope: 'component',
|
|
5
|
+
allowInstanceOverride: true,
|
|
6
|
+
};
|
|
1
7
|
export const radioMeta = {
|
|
2
8
|
name: 'Radio',
|
|
3
9
|
category: 'component',
|
|
4
10
|
directManifestNode: false,
|
|
5
11
|
allowedChildren: [],
|
|
6
|
-
note: '
|
|
12
|
+
note: 'Composition-level radio control; author repeated single-choice UI through RadioGroup.',
|
|
7
13
|
props: {},
|
|
8
14
|
};
|
|
9
15
|
export const radioGroupMeta = {
|
|
10
16
|
name: 'RadioGroup',
|
|
11
17
|
category: 'component',
|
|
12
|
-
|
|
18
|
+
description: 'Single-choice group with inline or card presentation while preserving radio semantics.',
|
|
19
|
+
directManifestNode: true,
|
|
13
20
|
allowedChildren: [],
|
|
14
|
-
|
|
15
|
-
|
|
21
|
+
blueprint: {
|
|
22
|
+
label: 'Radio group',
|
|
23
|
+
defaultProps: {
|
|
24
|
+
value: 'option-b',
|
|
25
|
+
options: [
|
|
26
|
+
{ value: 'option-a', label: 'First option', description: 'Supporting detail' },
|
|
27
|
+
{ value: 'option-b', label: 'Second option', description: 'Supporting detail' },
|
|
28
|
+
{ value: 'option-c', label: 'Third option', description: 'Supporting detail' },
|
|
29
|
+
],
|
|
30
|
+
orientation: 'vertical',
|
|
31
|
+
presentation: 'inline',
|
|
32
|
+
invalid: false,
|
|
33
|
+
readOnly: false,
|
|
34
|
+
disabled: false,
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
bindings: {
|
|
38
|
+
props: {
|
|
39
|
+
value: {
|
|
40
|
+
label: 'Value',
|
|
41
|
+
description: 'Currently selected option value.',
|
|
42
|
+
value: { type: 'string' },
|
|
43
|
+
acceptsFallback: true,
|
|
44
|
+
acceptsTransforms: true,
|
|
45
|
+
},
|
|
46
|
+
disabled: {
|
|
47
|
+
label: 'Disabled',
|
|
48
|
+
description: 'Whether the complete radio group is disabled.',
|
|
49
|
+
value: { type: 'boolean' },
|
|
50
|
+
acceptsFallback: true,
|
|
51
|
+
acceptsTransforms: true,
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
events: {
|
|
55
|
+
valueChange: {
|
|
56
|
+
label: 'Value change',
|
|
57
|
+
description: 'Runs when the selected radio value changes.',
|
|
58
|
+
payload: {
|
|
59
|
+
eventType: 'radioGroup.valueChange',
|
|
60
|
+
fields: [{ path: 'value', type: 'string', label: 'Value' }],
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
events: {
|
|
66
|
+
valueChange: {
|
|
67
|
+
label: 'Value change',
|
|
68
|
+
eventType: 'radioGroup.valueChange',
|
|
69
|
+
description: 'Emitted when the selected radio value changes.',
|
|
70
|
+
payloadFields: [{ path: 'value', type: 'string', label: 'Value' }],
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
props: {
|
|
74
|
+
value: {
|
|
75
|
+
type: 'string',
|
|
76
|
+
category: 'State',
|
|
77
|
+
label: 'Value',
|
|
78
|
+
authoring: { authority: 'instance' },
|
|
79
|
+
},
|
|
80
|
+
options: {
|
|
81
|
+
type: 'array',
|
|
82
|
+
category: 'Content',
|
|
83
|
+
label: 'Options',
|
|
84
|
+
itemSchema: [
|
|
85
|
+
{
|
|
86
|
+
key: 'value',
|
|
87
|
+
schema: {
|
|
88
|
+
type: 'string',
|
|
89
|
+
category: 'Content',
|
|
90
|
+
label: 'Value',
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
key: 'label',
|
|
95
|
+
schema: {
|
|
96
|
+
type: 'string',
|
|
97
|
+
category: 'Content',
|
|
98
|
+
label: 'Label',
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
key: 'description',
|
|
103
|
+
schema: {
|
|
104
|
+
type: 'string',
|
|
105
|
+
category: 'Content',
|
|
106
|
+
label: 'Description',
|
|
107
|
+
},
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
key: 'disabled',
|
|
111
|
+
schema: {
|
|
112
|
+
type: 'boolean',
|
|
113
|
+
category: 'State',
|
|
114
|
+
label: 'Disabled',
|
|
115
|
+
default: false,
|
|
116
|
+
},
|
|
117
|
+
},
|
|
118
|
+
],
|
|
119
|
+
authoring: { authority: 'instance' },
|
|
120
|
+
},
|
|
121
|
+
orientation: {
|
|
122
|
+
type: 'enum',
|
|
123
|
+
category: 'Layout',
|
|
124
|
+
label: 'Orientation',
|
|
125
|
+
enum: ['horizontal', 'vertical'],
|
|
126
|
+
default: 'vertical',
|
|
127
|
+
authoring: { authority: 'instance' },
|
|
128
|
+
},
|
|
129
|
+
gap: {
|
|
130
|
+
type: 'enum',
|
|
131
|
+
category: 'Layout',
|
|
132
|
+
label: 'Gap',
|
|
133
|
+
enum: ['xs', 's', 'm', 'l'],
|
|
134
|
+
authoring: themeAuthoring,
|
|
135
|
+
},
|
|
136
|
+
presentation: {
|
|
137
|
+
type: 'enum',
|
|
138
|
+
category: 'Style',
|
|
139
|
+
label: 'Presentation',
|
|
140
|
+
enum: ['inline', 'card'],
|
|
141
|
+
default: 'inline',
|
|
142
|
+
authoring: { authority: 'instance' },
|
|
143
|
+
},
|
|
144
|
+
color: {
|
|
145
|
+
type: 'enum',
|
|
146
|
+
category: 'Style',
|
|
147
|
+
label: 'Color',
|
|
148
|
+
enum: [...ZORA_COLORS],
|
|
149
|
+
authoring: themeAuthoring,
|
|
150
|
+
},
|
|
151
|
+
size: {
|
|
152
|
+
type: 'enum',
|
|
153
|
+
category: 'Style',
|
|
154
|
+
label: 'Size',
|
|
155
|
+
enum: ['s', 'm', 'l'],
|
|
156
|
+
authoring: themeAuthoring,
|
|
157
|
+
},
|
|
158
|
+
invalid: {
|
|
159
|
+
type: 'boolean',
|
|
160
|
+
category: 'State',
|
|
161
|
+
label: 'Invalid',
|
|
162
|
+
default: false,
|
|
163
|
+
authoring: { authority: 'instance' },
|
|
164
|
+
},
|
|
165
|
+
readOnly: {
|
|
166
|
+
type: 'boolean',
|
|
167
|
+
category: 'State',
|
|
168
|
+
label: 'Read only',
|
|
169
|
+
default: false,
|
|
170
|
+
authoring: { authority: 'instance' },
|
|
171
|
+
},
|
|
172
|
+
disabled: {
|
|
173
|
+
type: 'boolean',
|
|
174
|
+
category: 'State',
|
|
175
|
+
label: 'Disabled',
|
|
176
|
+
default: false,
|
|
177
|
+
authoring: { authority: 'instance' },
|
|
178
|
+
},
|
|
179
|
+
},
|
|
16
180
|
};
|
|
17
181
|
//# sourceMappingURL=meta.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"meta.js","sourceRoot":"","sources":["../../../src/components/radio/meta.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"meta.js","sourceRoot":"","sources":["../../../src/components/radio/meta.ts"],"names":[],"mappings":"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","sourcesContent":["import { ZORA_COLORS } from '../../internal/colorModel';\nimport type { ZoraComponentMeta } from '../../metadata';\n\nconst themeAuthoring = {\n authority: 'theme',\n scope: 'component',\n allowInstanceOverride: true,\n} as const;\n\nexport const radioMeta = {\n name: 'Radio',\n category: 'component',\n directManifestNode: false,\n allowedChildren: [],\n note: 'Composition-level radio control; author repeated single-choice UI through RadioGroup.',\n props: {},\n} as const satisfies ZoraComponentMeta;\n\nexport const radioGroupMeta = {\n name: 'RadioGroup',\n category: 'component',\n description:\n 'Single-choice group with inline or card presentation while preserving radio semantics.',\n directManifestNode: true,\n allowedChildren: [],\n blueprint: {\n label: 'Radio group',\n defaultProps: {\n value: 'option-b',\n options: [\n { value: 'option-a', label: 'First option', description: 'Supporting detail' },\n { value: 'option-b', label: 'Second option', description: 'Supporting detail' },\n { value: 'option-c', label: 'Third option', description: 'Supporting detail' },\n ],\n orientation: 'vertical',\n presentation: 'inline',\n invalid: false,\n readOnly: false,\n disabled: false,\n },\n },\n bindings: {\n props: {\n value: {\n label: 'Value',\n description: 'Currently selected option value.',\n value: { type: 'string' },\n acceptsFallback: true,\n acceptsTransforms: true,\n },\n disabled: {\n label: 'Disabled',\n description: 'Whether the complete radio group is disabled.',\n value: { type: 'boolean' },\n acceptsFallback: true,\n acceptsTransforms: true,\n },\n },\n events: {\n valueChange: {\n label: 'Value change',\n description: 'Runs when the selected radio value changes.',\n payload: {\n eventType: 'radioGroup.valueChange',\n fields: [{ path: 'value', type: 'string', label: 'Value' }],\n },\n },\n },\n },\n events: {\n valueChange: {\n label: 'Value change',\n eventType: 'radioGroup.valueChange',\n description: 'Emitted when the selected radio value changes.',\n payloadFields: [{ path: 'value', type: 'string', label: 'Value' }],\n },\n },\n props: {\n value: {\n type: 'string',\n category: 'State',\n label: 'Value',\n authoring: { authority: 'instance' },\n },\n options: {\n type: 'array',\n category: 'Content',\n label: 'Options',\n itemSchema: [\n {\n key: 'value',\n schema: {\n type: 'string',\n category: 'Content',\n label: 'Value',\n },\n },\n {\n key: 'label',\n schema: {\n type: 'string',\n category: 'Content',\n label: 'Label',\n },\n },\n {\n key: 'description',\n schema: {\n type: 'string',\n category: 'Content',\n label: 'Description',\n },\n },\n {\n key: 'disabled',\n schema: {\n type: 'boolean',\n category: 'State',\n label: 'Disabled',\n default: false,\n },\n },\n ],\n authoring: { authority: 'instance' },\n },\n orientation: {\n type: 'enum',\n category: 'Layout',\n label: 'Orientation',\n enum: ['horizontal', 'vertical'],\n default: 'vertical',\n authoring: { authority: 'instance' },\n },\n gap: {\n type: 'enum',\n category: 'Layout',\n label: 'Gap',\n enum: ['xs', 's', 'm', 'l'],\n authoring: themeAuthoring,\n },\n presentation: {\n type: 'enum',\n category: 'Style',\n label: 'Presentation',\n enum: ['inline', 'card'],\n default: 'inline',\n authoring: { authority: 'instance' },\n },\n color: {\n type: 'enum',\n category: 'Style',\n label: 'Color',\n enum: [...ZORA_COLORS],\n authoring: themeAuthoring,\n },\n size: {\n type: 'enum',\n category: 'Style',\n label: 'Size',\n enum: ['s', 'm', 'l'],\n authoring: themeAuthoring,\n },\n invalid: {\n type: 'boolean',\n category: 'State',\n label: 'Invalid',\n default: false,\n authoring: { authority: 'instance' },\n },\n readOnly: {\n type: 'boolean',\n category: 'State',\n label: 'Read only',\n default: false,\n authoring: { authority: 'instance' },\n },\n disabled: {\n type: 'boolean',\n category: 'State',\n label: 'Disabled',\n default: false,\n authoring: { authority: 'instance' },\n },\n },\n} as const satisfies ZoraComponentMeta;\n"]}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { ThemeRecipeOverrideValue } from '@ankhorage/contracts';
|
|
2
|
+
import type { ZoraColor } from '../../internal/colorModel';
|
|
3
|
+
import type { RadioGroupProps } from './types';
|
|
4
|
+
type RadioGroupGap = NonNullable<RadioGroupProps<string>['gap']>;
|
|
5
|
+
type RadioGroupSize = NonNullable<RadioGroupProps<string>['size']>;
|
|
6
|
+
/***
|
|
7
|
+
* Resolves RadioGroup presentation props from instance overrides and the active theme recipe.
|
|
8
|
+
*/
|
|
9
|
+
export declare function resolveRadioGroupThemeRecipe(input: {
|
|
10
|
+
readonly gap?: RadioGroupGap;
|
|
11
|
+
readonly color?: ZoraColor;
|
|
12
|
+
readonly size?: RadioGroupSize;
|
|
13
|
+
readonly themeFields: Readonly<Record<string, ThemeRecipeOverrideValue>>;
|
|
14
|
+
}): {
|
|
15
|
+
readonly gap: RadioGroupGap;
|
|
16
|
+
readonly color: "primary" | "secondary" | "tertiary" | "quaternary" | "neutral" | "error" | "success" | "warning" | "info" | "danger";
|
|
17
|
+
readonly size: RadioGroupSize;
|
|
18
|
+
};
|
|
19
|
+
export {};
|
|
20
|
+
//# sourceMappingURL=resolveRadioGroupThemeRecipe.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolveRadioGroupThemeRecipe.d.ts","sourceRoot":"","sources":["../../../src/components/radio/resolveRadioGroupThemeRecipe.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AAErE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE/C,KAAK,aAAa,GAAG,WAAW,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;AACjE,KAAK,cAAc,GAAG,WAAW,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;AAEnE;;GAEG;AACH,wBAAgB,4BAA4B,CAAC,KAAK,EAAE;IAClD,QAAQ,CAAC,GAAG,CAAC,EAAE,aAAa,CAAC;IAC7B,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,CAAC;IAC3B,QAAQ,CAAC,IAAI,CAAC,EAAE,cAAc,CAAC;IAC/B,QAAQ,CAAC,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,wBAAwB,CAAC,CAAC,CAAC;CAC1E;;;;EAMA"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/***
|
|
2
|
+
* Resolves RadioGroup presentation props from instance overrides and the active theme recipe.
|
|
3
|
+
*/
|
|
4
|
+
export function resolveRadioGroupThemeRecipe(input) {
|
|
5
|
+
return {
|
|
6
|
+
gap: input.gap ?? readGap(input.themeFields.gap) ?? 's',
|
|
7
|
+
color: input.color ?? readColor(input.themeFields.color) ?? 'primary',
|
|
8
|
+
size: input.size ?? readSize(input.themeFields.size) ?? 'm',
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
/*** Reads a valid RadioGroup gap from a theme recipe value. */
|
|
12
|
+
function readGap(value) {
|
|
13
|
+
if (value === 'xs' || value === 's' || value === 'm' || value === 'l')
|
|
14
|
+
return value;
|
|
15
|
+
return undefined;
|
|
16
|
+
}
|
|
17
|
+
/*** Reads a valid ZORA color from a theme recipe value. */
|
|
18
|
+
function readColor(value) {
|
|
19
|
+
if (value === 'primary' || value === 'secondary' || value === 'tertiary')
|
|
20
|
+
return value;
|
|
21
|
+
if (value === 'quaternary' || value === 'neutral' || value === 'danger')
|
|
22
|
+
return value;
|
|
23
|
+
if (value === 'success' || value === 'warning' || value === 'error' || value === 'info') {
|
|
24
|
+
return value;
|
|
25
|
+
}
|
|
26
|
+
return undefined;
|
|
27
|
+
}
|
|
28
|
+
/*** Reads a valid RadioGroup control size from a theme recipe value. */
|
|
29
|
+
function readSize(value) {
|
|
30
|
+
if (value === 's' || value === 'm' || value === 'l')
|
|
31
|
+
return value;
|
|
32
|
+
return undefined;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=resolveRadioGroupThemeRecipe.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolveRadioGroupThemeRecipe.js","sourceRoot":"","sources":["../../../src/components/radio/resolveRadioGroupThemeRecipe.ts"],"names":[],"mappings":"AAQA;;GAEG;AACH,MAAM,UAAU,4BAA4B,CAAC,KAK5C;IACC,OAAO;QACL,GAAG,EAAE,KAAK,CAAC,GAAG,IAAI,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,GAAG;QACvD,KAAK,EAAE,KAAK,CAAC,KAAK,IAAI,SAAS,CAAC,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,IAAI,SAAS;QACrE,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,QAAQ,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,GAAG;KACnD,CAAC;AACb,CAAC;AAED,+DAA+D;AAC/D,SAAS,OAAO,CAAC,KAA2C;IAC1D,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,GAAG,IAAI,KAAK,KAAK,GAAG,IAAI,KAAK,KAAK,GAAG;QAAE,OAAO,KAAK,CAAC;IACpF,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,2DAA2D;AAC3D,SAAS,SAAS,CAAC,KAA2C;IAC5D,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,WAAW,IAAI,KAAK,KAAK,UAAU;QAAE,OAAO,KAAK,CAAC;IACvF,IAAI,KAAK,KAAK,YAAY,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IACtF,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,OAAO,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;QACxF,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,wEAAwE;AACxE,SAAS,QAAQ,CAAC,KAA2C;IAC3D,IAAI,KAAK,KAAK,GAAG,IAAI,KAAK,KAAK,GAAG,IAAI,KAAK,KAAK,GAAG;QAAE,OAAO,KAAK,CAAC;IAClE,OAAO,SAAS,CAAC;AACnB,CAAC","sourcesContent":["import type { ThemeRecipeOverrideValue } from '@ankhorage/contracts';\n\nimport type { ZoraColor } from '../../internal/colorModel';\nimport type { RadioGroupProps } from './types';\n\ntype RadioGroupGap = NonNullable<RadioGroupProps<string>['gap']>;\ntype RadioGroupSize = NonNullable<RadioGroupProps<string>['size']>;\n\n/***\n * Resolves RadioGroup presentation props from instance overrides and the active theme recipe.\n */\nexport function resolveRadioGroupThemeRecipe(input: {\n readonly gap?: RadioGroupGap;\n readonly color?: ZoraColor;\n readonly size?: RadioGroupSize;\n readonly themeFields: Readonly<Record<string, ThemeRecipeOverrideValue>>;\n}) {\n return {\n gap: input.gap ?? readGap(input.themeFields.gap) ?? 's',\n color: input.color ?? readColor(input.themeFields.color) ?? 'primary',\n size: input.size ?? readSize(input.themeFields.size) ?? 'm',\n } as const;\n}\n\n/*** Reads a valid RadioGroup gap from a theme recipe value. */\nfunction readGap(value: ThemeRecipeOverrideValue | undefined): RadioGroupGap | undefined {\n if (value === 'xs' || value === 's' || value === 'm' || value === 'l') return value;\n return undefined;\n}\n\n/*** Reads a valid ZORA color from a theme recipe value. */\nfunction readColor(value: ThemeRecipeOverrideValue | undefined): ZoraColor | undefined {\n if (value === 'primary' || value === 'secondary' || value === 'tertiary') return value;\n if (value === 'quaternary' || value === 'neutral' || value === 'danger') return value;\n if (value === 'success' || value === 'warning' || value === 'error' || value === 'info') {\n return value;\n }\n return undefined;\n}\n\n/*** Reads a valid RadioGroup control size from a theme recipe value. */\nfunction readSize(value: ThemeRecipeOverrideValue | undefined): RadioGroupSize | undefined {\n if (value === 's' || value === 'm' || value === 'l') return value;\n return undefined;\n}\n"]}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export declare const radioGroupThemeRecipeMeta: {
|
|
2
|
+
readonly name: "RadioGroup";
|
|
3
|
+
readonly kind: "component";
|
|
4
|
+
readonly description: "Maps shared selection-control presentation choices into RadioGroup defaults.";
|
|
5
|
+
readonly fields: {
|
|
6
|
+
readonly gap: {
|
|
7
|
+
readonly type: "choice";
|
|
8
|
+
readonly label: "Gap";
|
|
9
|
+
readonly options: readonly ["xs", "s", "m", "l"];
|
|
10
|
+
readonly default: "s";
|
|
11
|
+
};
|
|
12
|
+
readonly color: {
|
|
13
|
+
readonly type: "choice";
|
|
14
|
+
readonly label: "Color";
|
|
15
|
+
readonly options: readonly ["primary", "secondary", "tertiary", "quaternary", "neutral", "success", "warning", "error", "info", "danger"];
|
|
16
|
+
readonly default: "primary";
|
|
17
|
+
};
|
|
18
|
+
readonly size: {
|
|
19
|
+
readonly type: "choice";
|
|
20
|
+
readonly label: "Size";
|
|
21
|
+
readonly options: readonly ["s", "m", "l"];
|
|
22
|
+
readonly default: "m";
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
//# sourceMappingURL=themeRecipeMeta.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"themeRecipeMeta.d.ts","sourceRoot":"","sources":["../../../src/components/radio/themeRecipeMeta.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;CAwBE,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { ZORA_COLORS } from '../../internal/colorModel';
|
|
2
|
+
export const radioGroupThemeRecipeMeta = {
|
|
3
|
+
name: 'RadioGroup',
|
|
4
|
+
kind: 'component',
|
|
5
|
+
description: 'Maps shared selection-control presentation choices into RadioGroup defaults.',
|
|
6
|
+
fields: {
|
|
7
|
+
gap: {
|
|
8
|
+
type: 'choice',
|
|
9
|
+
label: 'Gap',
|
|
10
|
+
options: ['xs', 's', 'm', 'l'],
|
|
11
|
+
default: 's',
|
|
12
|
+
},
|
|
13
|
+
color: {
|
|
14
|
+
type: 'choice',
|
|
15
|
+
label: 'Color',
|
|
16
|
+
options: ZORA_COLORS,
|
|
17
|
+
default: 'primary',
|
|
18
|
+
},
|
|
19
|
+
size: {
|
|
20
|
+
type: 'choice',
|
|
21
|
+
label: 'Size',
|
|
22
|
+
options: ['s', 'm', 'l'],
|
|
23
|
+
default: 'm',
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
//# sourceMappingURL=themeRecipeMeta.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"themeRecipeMeta.js","sourceRoot":"","sources":["../../../src/components/radio/themeRecipeMeta.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAGxD,MAAM,CAAC,MAAM,yBAAyB,GAAG;IACvC,IAAI,EAAE,YAAY;IAClB,IAAI,EAAE,WAAW;IACjB,WAAW,EAAE,8EAA8E;IAC3F,MAAM,EAAE;QACN,GAAG,EAAE;YACH,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,KAAK;YACZ,OAAO,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;YAC9B,OAAO,EAAE,GAAG;SACb;QACD,KAAK,EAAE;YACL,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,OAAO;YACd,OAAO,EAAE,WAAW;YACpB,OAAO,EAAE,SAAS;SACnB;QACD,IAAI,EAAE;YACJ,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,MAAM;YACb,OAAO,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;YACxB,OAAO,EAAE,GAAG;SACb;KACF;CACqC,CAAC","sourcesContent":["import { ZORA_COLORS } from '../../internal/colorModel';\nimport type { ZoraThemeRecipeMeta } from '../../metadata/themeRecipeTypes';\n\nexport const radioGroupThemeRecipeMeta = {\n name: 'RadioGroup',\n kind: 'component',\n description: 'Maps shared selection-control presentation choices into RadioGroup defaults.',\n fields: {\n gap: {\n type: 'choice',\n label: 'Gap',\n options: ['xs', 's', 'm', 'l'],\n default: 's',\n },\n color: {\n type: 'choice',\n label: 'Color',\n options: ZORA_COLORS,\n default: 'primary',\n },\n size: {\n type: 'choice',\n label: 'Size',\n options: ['s', 'm', 'l'],\n default: 'm',\n },\n },\n} as const satisfies ZoraThemeRecipeMeta;\n"]}
|
|
@@ -16,5 +16,6 @@ export interface RadioGroupProps<TValue extends string> extends ZoraBaseProps, P
|
|
|
16
16
|
options: readonly RadioGroupOption<TValue>[];
|
|
17
17
|
orientation?: 'horizontal' | 'vertical';
|
|
18
18
|
gap?: 'xs' | 's' | 'm' | 'l';
|
|
19
|
+
presentation?: 'inline' | 'card';
|
|
19
20
|
}
|
|
20
21
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/components/radio/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,IAAI,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC1E,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAE/D,MAAM,WAAW,UAAW,SAAQ,aAAa,EAAE,IAAI,CAAC,iBAAiB,EAAE,MAAM,GAAG,SAAS,CAAC;CAAG;AAEjG,MAAM,WAAW,gBAAgB,CAAC,MAAM,SAAS,MAAM;IACrD,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC9B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,eAAe,CAAC,MAAM,SAAS,MAAM,CACpD,SACE,aAAa,EACb,IAAI,CACF,IAAI,CAAC,iBAAiB,EAAE,MAAM,GAAG,SAAS,CAAC,EAC3C,OAAO,GAAG,MAAM,GAAG,SAAS,GAAG,UAAU,GAAG,UAAU,CACvD;IACH,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,OAAO,EAAE,SAAS,gBAAgB,CAAC,MAAM,CAAC,EAAE,CAAC;IAC7C,WAAW,CAAC,EAAE,YAAY,GAAG,UAAU,CAAC;IACxC,GAAG,CAAC,EAAE,IAAI,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/components/radio/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,IAAI,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC1E,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAE/D,MAAM,WAAW,UAAW,SAAQ,aAAa,EAAE,IAAI,CAAC,iBAAiB,EAAE,MAAM,GAAG,SAAS,CAAC;CAAG;AAEjG,MAAM,WAAW,gBAAgB,CAAC,MAAM,SAAS,MAAM;IACrD,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC9B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,eAAe,CAAC,MAAM,SAAS,MAAM,CACpD,SACE,aAAa,EACb,IAAI,CACF,IAAI,CAAC,iBAAiB,EAAE,MAAM,GAAG,SAAS,CAAC,EAC3C,OAAO,GAAG,MAAM,GAAG,SAAS,GAAG,UAAU,GAAG,UAAU,CACvD;IACH,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,OAAO,EAAE,SAAS,gBAAgB,CAAC,MAAM,CAAC,EAAE,CAAC;IAC7C,WAAW,CAAC,EAAE,YAAY,GAAG,UAAU,CAAC;IACxC,GAAG,CAAC,EAAE,IAAI,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;IAC7B,YAAY,CAAC,EAAE,QAAQ,GAAG,MAAM,CAAC;CAClC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/components/radio/types.ts"],"names":[],"mappings":"","sourcesContent":["import type { RadioProps as SurfaceRadioProps } from '@ankhorage/surface';\nimport type React from 'react';\n\nimport type { ZoraBaseProps } from '../../theme/ZoraBaseProps';\n\nexport interface RadioProps extends ZoraBaseProps, Omit<SurfaceRadioProps, 'mode' | 'themeId'> {}\n\nexport interface RadioGroupOption<TValue extends string> {\n value: TValue;\n label: React.ReactNode;\n description?: React.ReactNode;\n disabled?: boolean;\n testID?: string;\n}\n\nexport interface RadioGroupProps<TValue extends string>\n extends\n ZoraBaseProps,\n Pick<\n Omit<SurfaceRadioProps, 'mode' | 'themeId'>,\n 'color' | 'size' | 'invalid' | 'readOnly' | 'disabled'\n > {\n value: TValue;\n onValueChange: (value: TValue) => void;\n options: readonly RadioGroupOption<TValue>[];\n orientation?: 'horizontal' | 'vertical';\n gap?: 'xs' | 's' | 'm' | 'l';\n}\n"]}
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/components/radio/types.ts"],"names":[],"mappings":"","sourcesContent":["import type { RadioProps as SurfaceRadioProps } from '@ankhorage/surface';\nimport type React from 'react';\n\nimport type { ZoraBaseProps } from '../../theme/ZoraBaseProps';\n\nexport interface RadioProps extends ZoraBaseProps, Omit<SurfaceRadioProps, 'mode' | 'themeId'> {}\n\nexport interface RadioGroupOption<TValue extends string> {\n value: TValue;\n label: React.ReactNode;\n description?: React.ReactNode;\n disabled?: boolean;\n testID?: string;\n}\n\nexport interface RadioGroupProps<TValue extends string>\n extends\n ZoraBaseProps,\n Pick<\n Omit<SurfaceRadioProps, 'mode' | 'themeId'>,\n 'color' | 'size' | 'invalid' | 'readOnly' | 'disabled'\n > {\n value: TValue;\n onValueChange: (value: TValue) => void;\n options: readonly RadioGroupOption<TValue>[];\n orientation?: 'horizontal' | 'vertical';\n gap?: 'xs' | 's' | 'm' | 'l';\n presentation?: 'inline' | 'card';\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"themeRecipeMeta.d.ts","sourceRoot":"","sources":["../../src/metadata/themeRecipeMeta.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"themeRecipeMeta.d.ts","sourceRoot":"","sources":["../../src/metadata/themeRecipeMeta.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,oBAAoB,CAAC;AAEtE,eAAO,MAAM,sBAAsB,EAAE,2BAOpC,CAAC"}
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { buttonThemeRecipeMeta } from '../components/button/themeRecipeMeta';
|
|
2
2
|
import { cardThemeRecipeMeta } from '../components/card/themeRecipeMeta';
|
|
3
3
|
import { headingThemeRecipeMeta } from '../components/heading/themeRecipeMeta';
|
|
4
|
+
import { radioGroupThemeRecipeMeta } from '../components/radio/themeRecipeMeta';
|
|
4
5
|
import { textThemeRecipeMeta } from '../components/text/themeRecipeMeta';
|
|
5
6
|
import { panelThemeRecipeMeta } from '../patterns/panel/themeRecipeMeta';
|
|
6
7
|
export const ZORA_THEME_RECIPE_META = {
|
|
7
8
|
Button: buttonThemeRecipeMeta,
|
|
8
9
|
Card: cardThemeRecipeMeta,
|
|
9
10
|
Heading: headingThemeRecipeMeta,
|
|
11
|
+
RadioGroup: radioGroupThemeRecipeMeta,
|
|
10
12
|
Text: textThemeRecipeMeta,
|
|
11
13
|
Panel: panelThemeRecipeMeta,
|
|
12
14
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"themeRecipeMeta.js","sourceRoot":"","sources":["../../src/metadata/themeRecipeMeta.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,sCAAsC,CAAC;AAC7E,OAAO,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AACzE,OAAO,EAAE,sBAAsB,EAAE,MAAM,uCAAuC,CAAC;AAC/E,OAAO,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AACzE,OAAO,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;AAGzE,MAAM,CAAC,MAAM,sBAAsB,GAAgC;IACjE,MAAM,EAAE,qBAAqB;IAC7B,IAAI,EAAE,mBAAmB;IACzB,OAAO,EAAE,sBAAsB;IAC/B,IAAI,EAAE,mBAAmB;IACzB,KAAK,EAAE,oBAAoB;CAC5B,CAAC","sourcesContent":["import { buttonThemeRecipeMeta } from '../components/button/themeRecipeMeta';\nimport { cardThemeRecipeMeta } from '../components/card/themeRecipeMeta';\nimport { headingThemeRecipeMeta } from '../components/heading/themeRecipeMeta';\nimport { textThemeRecipeMeta } from '../components/text/themeRecipeMeta';\nimport { panelThemeRecipeMeta } from '../patterns/panel/themeRecipeMeta';\nimport type { ZoraThemeRecipeMetaRegistry } from './themeRecipeTypes';\n\nexport const ZORA_THEME_RECIPE_META: ZoraThemeRecipeMetaRegistry = {\n Button: buttonThemeRecipeMeta,\n Card: cardThemeRecipeMeta,\n Heading: headingThemeRecipeMeta,\n Text: textThemeRecipeMeta,\n Panel: panelThemeRecipeMeta,\n};\n"]}
|
|
1
|
+
{"version":3,"file":"themeRecipeMeta.js","sourceRoot":"","sources":["../../src/metadata/themeRecipeMeta.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,sCAAsC,CAAC;AAC7E,OAAO,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AACzE,OAAO,EAAE,sBAAsB,EAAE,MAAM,uCAAuC,CAAC;AAC/E,OAAO,EAAE,yBAAyB,EAAE,MAAM,qCAAqC,CAAC;AAChF,OAAO,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AACzE,OAAO,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;AAGzE,MAAM,CAAC,MAAM,sBAAsB,GAAgC;IACjE,MAAM,EAAE,qBAAqB;IAC7B,IAAI,EAAE,mBAAmB;IACzB,OAAO,EAAE,sBAAsB;IAC/B,UAAU,EAAE,yBAAyB;IACrC,IAAI,EAAE,mBAAmB;IACzB,KAAK,EAAE,oBAAoB;CAC5B,CAAC","sourcesContent":["import { buttonThemeRecipeMeta } from '../components/button/themeRecipeMeta';\nimport { cardThemeRecipeMeta } from '../components/card/themeRecipeMeta';\nimport { headingThemeRecipeMeta } from '../components/heading/themeRecipeMeta';\nimport { radioGroupThemeRecipeMeta } from '../components/radio/themeRecipeMeta';\nimport { textThemeRecipeMeta } from '../components/text/themeRecipeMeta';\nimport { panelThemeRecipeMeta } from '../patterns/panel/themeRecipeMeta';\nimport type { ZoraThemeRecipeMetaRegistry } from './themeRecipeTypes';\n\nexport const ZORA_THEME_RECIPE_META: ZoraThemeRecipeMetaRegistry = {\n Button: buttonThemeRecipeMeta,\n Card: cardThemeRecipeMeta,\n Heading: headingThemeRecipeMeta,\n RadioGroup: radioGroupThemeRecipeMeta,\n Text: textThemeRecipeMeta,\n Panel: panelThemeRecipeMeta,\n};\n"]}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ankhorage/zora",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "4.
|
|
4
|
+
"version": "4.4.0",
|
|
5
5
|
"description": "Opinionated React Native and React Native Web UI kit built on @ankhorage/surface.",
|
|
6
6
|
"homepage": "https://github.com/ankhorage/zora#readme",
|
|
7
7
|
"bugs": {
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { expect, test } from 'bun:test';
|
|
2
|
+
|
|
3
|
+
import { resolveRadioGroupThemeRecipe } from './resolveRadioGroupThemeRecipe';
|
|
4
|
+
|
|
5
|
+
test('resolves RadioGroup theme defaults while preserving instance overrides', () => {
|
|
6
|
+
expect(resolveRadioGroupThemeRecipe({ themeFields: {} })).toEqual({
|
|
7
|
+
gap: 's',
|
|
8
|
+
color: 'primary',
|
|
9
|
+
size: 'm',
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
expect(
|
|
13
|
+
resolveRadioGroupThemeRecipe({
|
|
14
|
+
gap: 'l',
|
|
15
|
+
color: 'danger',
|
|
16
|
+
size: 's',
|
|
17
|
+
themeFields: { gap: 'xs', color: 'secondary', size: 'l' },
|
|
18
|
+
}),
|
|
19
|
+
).toEqual({ gap: 'l', color: 'danger', size: 's' });
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
test('card presentation stays on the RadioGroup and Surface Radio semantic path', async () => {
|
|
23
|
+
const source = await Bun.file('src/components/radio/RadioGroup.tsx').text();
|
|
24
|
+
|
|
25
|
+
expect(source).toContain('accessibilityRole="radiogroup"');
|
|
26
|
+
expect(source).toContain('checked={value === option.value}');
|
|
27
|
+
expect(source).toContain('<Radio');
|
|
28
|
+
expect(source).toContain("const isCard = presentation === 'card';");
|
|
29
|
+
expect(source).not.toContain('<Button');
|
|
30
|
+
expect(source).not.toContain('SelectableItem');
|
|
31
|
+
});
|
|
@@ -1,12 +1,17 @@
|
|
|
1
|
-
import { Radio } from '@ankhorage/surface';
|
|
1
|
+
import { Radio, useTheme } from '@ankhorage/surface';
|
|
2
2
|
import React from 'react';
|
|
3
3
|
import { View } from 'react-native';
|
|
4
4
|
|
|
5
5
|
import { Stack } from '../../foundation';
|
|
6
|
+
import { useZoraThemeRecipe } from '../../theme/useZoraThemeRecipe';
|
|
6
7
|
import { withZoraThemeScope } from '../../theme/withZoraThemeScope';
|
|
7
8
|
import { Text } from '../text';
|
|
9
|
+
import { resolveRadioGroupThemeRecipe } from './resolveRadioGroupThemeRecipe';
|
|
8
10
|
import type { RadioGroupOption, RadioGroupProps } from './types';
|
|
9
11
|
|
|
12
|
+
/***
|
|
13
|
+
* Resolves the themed radio-group presentation within the active ZORA scope.
|
|
14
|
+
*/
|
|
10
15
|
function RadioGroupInner<TValue extends string>({
|
|
11
16
|
themeId: _themeId,
|
|
12
17
|
mode: _mode,
|
|
@@ -14,9 +19,10 @@ function RadioGroupInner<TValue extends string>({
|
|
|
14
19
|
onValueChange,
|
|
15
20
|
options,
|
|
16
21
|
orientation = 'vertical',
|
|
17
|
-
gap
|
|
18
|
-
|
|
19
|
-
|
|
22
|
+
gap,
|
|
23
|
+
presentation = 'inline',
|
|
24
|
+
color,
|
|
25
|
+
size,
|
|
20
26
|
invalid = false,
|
|
21
27
|
readOnly = false,
|
|
22
28
|
disabled = false,
|
|
@@ -24,6 +30,8 @@ function RadioGroupInner<TValue extends string>({
|
|
|
24
30
|
interactionPolicy,
|
|
25
31
|
}: RadioGroupProps<TValue>) {
|
|
26
32
|
const isHorizontal = orientation === 'horizontal';
|
|
33
|
+
const themeFields = useZoraThemeRecipe('RadioGroup');
|
|
34
|
+
const recipe = resolveRadioGroupThemeRecipe({ gap, color, size, themeFields });
|
|
27
35
|
|
|
28
36
|
return (
|
|
29
37
|
<View
|
|
@@ -36,7 +44,7 @@ function RadioGroupInner<TValue extends string>({
|
|
|
36
44
|
>
|
|
37
45
|
<Stack
|
|
38
46
|
direction={isHorizontal ? 'row' : 'column'}
|
|
39
|
-
gap={gap}
|
|
47
|
+
gap={recipe.gap}
|
|
40
48
|
wrap={isHorizontal ? 'wrap' : 'nowrap'}
|
|
41
49
|
>
|
|
42
50
|
{options.map((option) => (
|
|
@@ -47,8 +55,10 @@ function RadioGroupInner<TValue extends string>({
|
|
|
47
55
|
disabled={disabled || option.disabled === true}
|
|
48
56
|
invalid={invalid}
|
|
49
57
|
readOnly={readOnly}
|
|
50
|
-
size={size}
|
|
51
|
-
color={color}
|
|
58
|
+
size={recipe.size}
|
|
59
|
+
color={recipe.color}
|
|
60
|
+
orientation={orientation}
|
|
61
|
+
presentation={presentation}
|
|
52
62
|
onSelect={onValueChange}
|
|
53
63
|
interactionPolicy={interactionPolicy}
|
|
54
64
|
/>
|
|
@@ -63,6 +73,9 @@ function RadioGroupInner<TValue extends string>({
|
|
|
63
73
|
*/
|
|
64
74
|
export const RadioGroup = withZoraThemeScope(RadioGroupInner);
|
|
65
75
|
|
|
76
|
+
/***
|
|
77
|
+
* Renders one option through the single Surface Radio interaction boundary.
|
|
78
|
+
*/
|
|
66
79
|
function RadioGroupItem<TValue extends string>({
|
|
67
80
|
option,
|
|
68
81
|
checked,
|
|
@@ -71,6 +84,8 @@ function RadioGroupItem<TValue extends string>({
|
|
|
71
84
|
readOnly,
|
|
72
85
|
size,
|
|
73
86
|
color,
|
|
87
|
+
orientation,
|
|
88
|
+
presentation,
|
|
74
89
|
onSelect,
|
|
75
90
|
interactionPolicy,
|
|
76
91
|
}: {
|
|
@@ -81,10 +96,14 @@ function RadioGroupItem<TValue extends string>({
|
|
|
81
96
|
readOnly: boolean;
|
|
82
97
|
size: NonNullable<RadioGroupProps<TValue>['size']>;
|
|
83
98
|
color: NonNullable<RadioGroupProps<TValue>['color']>;
|
|
99
|
+
orientation: NonNullable<RadioGroupProps<TValue>['orientation']>;
|
|
100
|
+
presentation: NonNullable<RadioGroupProps<TValue>['presentation']>;
|
|
84
101
|
onSelect: (value: TValue) => void;
|
|
85
102
|
interactionPolicy: RadioGroupProps<TValue>['interactionPolicy'];
|
|
86
103
|
}) {
|
|
104
|
+
const { theme } = useTheme();
|
|
87
105
|
const passive = interactionPolicy === 'passive';
|
|
106
|
+
const isCard = presentation === 'card';
|
|
88
107
|
|
|
89
108
|
return (
|
|
90
109
|
<Radio
|
|
@@ -96,13 +115,31 @@ function RadioGroupItem<TValue extends string>({
|
|
|
96
115
|
size={size}
|
|
97
116
|
color={color}
|
|
98
117
|
testID={option.testID}
|
|
118
|
+
bg={
|
|
119
|
+
isCard
|
|
120
|
+
? checked
|
|
121
|
+
? theme.semantics.selection.background
|
|
122
|
+
: theme.semantics.surface.default
|
|
123
|
+
: undefined
|
|
124
|
+
}
|
|
125
|
+
borderColor={
|
|
126
|
+
isCard
|
|
127
|
+
? checked
|
|
128
|
+
? theme.semantics.selection.border
|
|
129
|
+
: theme.semantics.border.default
|
|
130
|
+
: undefined
|
|
131
|
+
}
|
|
132
|
+
borderWidth={isCard ? 1 : undefined}
|
|
133
|
+
p={isCard ? 'm' : undefined}
|
|
134
|
+
radius={isCard ? 'l' : undefined}
|
|
135
|
+
width={isCard && orientation === 'vertical' ? '100%' : undefined}
|
|
99
136
|
onCheckedChange={(nextChecked) => {
|
|
100
137
|
if (passive) return;
|
|
101
138
|
if (nextChecked) onSelect(option.value);
|
|
102
139
|
}}
|
|
103
140
|
>
|
|
104
141
|
<Stack gap="xs">
|
|
105
|
-
<Text>{option.label}</Text>
|
|
142
|
+
<Text weight={isCard ? 'semiBold' : undefined}>{option.label}</Text>
|
|
106
143
|
{option.description ? (
|
|
107
144
|
<Text emphasis="muted" variant="caption">
|
|
108
145
|
{option.description}
|
|
@@ -1,19 +1,185 @@
|
|
|
1
|
+
import { ZORA_COLORS } from '../../internal/colorModel';
|
|
1
2
|
import type { ZoraComponentMeta } from '../../metadata';
|
|
2
3
|
|
|
4
|
+
const themeAuthoring = {
|
|
5
|
+
authority: 'theme',
|
|
6
|
+
scope: 'component',
|
|
7
|
+
allowInstanceOverride: true,
|
|
8
|
+
} as const;
|
|
9
|
+
|
|
3
10
|
export const radioMeta = {
|
|
4
11
|
name: 'Radio',
|
|
5
12
|
category: 'component',
|
|
6
13
|
directManifestNode: false,
|
|
7
14
|
allowedChildren: [],
|
|
8
|
-
note: '
|
|
15
|
+
note: 'Composition-level radio control; author repeated single-choice UI through RadioGroup.',
|
|
9
16
|
props: {},
|
|
10
17
|
} as const satisfies ZoraComponentMeta;
|
|
11
18
|
|
|
12
19
|
export const radioGroupMeta = {
|
|
13
20
|
name: 'RadioGroup',
|
|
14
21
|
category: 'component',
|
|
15
|
-
|
|
22
|
+
description:
|
|
23
|
+
'Single-choice group with inline or card presentation while preserving radio semantics.',
|
|
24
|
+
directManifestNode: true,
|
|
16
25
|
allowedChildren: [],
|
|
17
|
-
|
|
18
|
-
|
|
26
|
+
blueprint: {
|
|
27
|
+
label: 'Radio group',
|
|
28
|
+
defaultProps: {
|
|
29
|
+
value: 'option-b',
|
|
30
|
+
options: [
|
|
31
|
+
{ value: 'option-a', label: 'First option', description: 'Supporting detail' },
|
|
32
|
+
{ value: 'option-b', label: 'Second option', description: 'Supporting detail' },
|
|
33
|
+
{ value: 'option-c', label: 'Third option', description: 'Supporting detail' },
|
|
34
|
+
],
|
|
35
|
+
orientation: 'vertical',
|
|
36
|
+
presentation: 'inline',
|
|
37
|
+
invalid: false,
|
|
38
|
+
readOnly: false,
|
|
39
|
+
disabled: false,
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
bindings: {
|
|
43
|
+
props: {
|
|
44
|
+
value: {
|
|
45
|
+
label: 'Value',
|
|
46
|
+
description: 'Currently selected option value.',
|
|
47
|
+
value: { type: 'string' },
|
|
48
|
+
acceptsFallback: true,
|
|
49
|
+
acceptsTransforms: true,
|
|
50
|
+
},
|
|
51
|
+
disabled: {
|
|
52
|
+
label: 'Disabled',
|
|
53
|
+
description: 'Whether the complete radio group is disabled.',
|
|
54
|
+
value: { type: 'boolean' },
|
|
55
|
+
acceptsFallback: true,
|
|
56
|
+
acceptsTransforms: true,
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
events: {
|
|
60
|
+
valueChange: {
|
|
61
|
+
label: 'Value change',
|
|
62
|
+
description: 'Runs when the selected radio value changes.',
|
|
63
|
+
payload: {
|
|
64
|
+
eventType: 'radioGroup.valueChange',
|
|
65
|
+
fields: [{ path: 'value', type: 'string', label: 'Value' }],
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
events: {
|
|
71
|
+
valueChange: {
|
|
72
|
+
label: 'Value change',
|
|
73
|
+
eventType: 'radioGroup.valueChange',
|
|
74
|
+
description: 'Emitted when the selected radio value changes.',
|
|
75
|
+
payloadFields: [{ path: 'value', type: 'string', label: 'Value' }],
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
props: {
|
|
79
|
+
value: {
|
|
80
|
+
type: 'string',
|
|
81
|
+
category: 'State',
|
|
82
|
+
label: 'Value',
|
|
83
|
+
authoring: { authority: 'instance' },
|
|
84
|
+
},
|
|
85
|
+
options: {
|
|
86
|
+
type: 'array',
|
|
87
|
+
category: 'Content',
|
|
88
|
+
label: 'Options',
|
|
89
|
+
itemSchema: [
|
|
90
|
+
{
|
|
91
|
+
key: 'value',
|
|
92
|
+
schema: {
|
|
93
|
+
type: 'string',
|
|
94
|
+
category: 'Content',
|
|
95
|
+
label: 'Value',
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
key: 'label',
|
|
100
|
+
schema: {
|
|
101
|
+
type: 'string',
|
|
102
|
+
category: 'Content',
|
|
103
|
+
label: 'Label',
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
key: 'description',
|
|
108
|
+
schema: {
|
|
109
|
+
type: 'string',
|
|
110
|
+
category: 'Content',
|
|
111
|
+
label: 'Description',
|
|
112
|
+
},
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
key: 'disabled',
|
|
116
|
+
schema: {
|
|
117
|
+
type: 'boolean',
|
|
118
|
+
category: 'State',
|
|
119
|
+
label: 'Disabled',
|
|
120
|
+
default: false,
|
|
121
|
+
},
|
|
122
|
+
},
|
|
123
|
+
],
|
|
124
|
+
authoring: { authority: 'instance' },
|
|
125
|
+
},
|
|
126
|
+
orientation: {
|
|
127
|
+
type: 'enum',
|
|
128
|
+
category: 'Layout',
|
|
129
|
+
label: 'Orientation',
|
|
130
|
+
enum: ['horizontal', 'vertical'],
|
|
131
|
+
default: 'vertical',
|
|
132
|
+
authoring: { authority: 'instance' },
|
|
133
|
+
},
|
|
134
|
+
gap: {
|
|
135
|
+
type: 'enum',
|
|
136
|
+
category: 'Layout',
|
|
137
|
+
label: 'Gap',
|
|
138
|
+
enum: ['xs', 's', 'm', 'l'],
|
|
139
|
+
authoring: themeAuthoring,
|
|
140
|
+
},
|
|
141
|
+
presentation: {
|
|
142
|
+
type: 'enum',
|
|
143
|
+
category: 'Style',
|
|
144
|
+
label: 'Presentation',
|
|
145
|
+
enum: ['inline', 'card'],
|
|
146
|
+
default: 'inline',
|
|
147
|
+
authoring: { authority: 'instance' },
|
|
148
|
+
},
|
|
149
|
+
color: {
|
|
150
|
+
type: 'enum',
|
|
151
|
+
category: 'Style',
|
|
152
|
+
label: 'Color',
|
|
153
|
+
enum: [...ZORA_COLORS],
|
|
154
|
+
authoring: themeAuthoring,
|
|
155
|
+
},
|
|
156
|
+
size: {
|
|
157
|
+
type: 'enum',
|
|
158
|
+
category: 'Style',
|
|
159
|
+
label: 'Size',
|
|
160
|
+
enum: ['s', 'm', 'l'],
|
|
161
|
+
authoring: themeAuthoring,
|
|
162
|
+
},
|
|
163
|
+
invalid: {
|
|
164
|
+
type: 'boolean',
|
|
165
|
+
category: 'State',
|
|
166
|
+
label: 'Invalid',
|
|
167
|
+
default: false,
|
|
168
|
+
authoring: { authority: 'instance' },
|
|
169
|
+
},
|
|
170
|
+
readOnly: {
|
|
171
|
+
type: 'boolean',
|
|
172
|
+
category: 'State',
|
|
173
|
+
label: 'Read only',
|
|
174
|
+
default: false,
|
|
175
|
+
authoring: { authority: 'instance' },
|
|
176
|
+
},
|
|
177
|
+
disabled: {
|
|
178
|
+
type: 'boolean',
|
|
179
|
+
category: 'State',
|
|
180
|
+
label: 'Disabled',
|
|
181
|
+
default: false,
|
|
182
|
+
authoring: { authority: 'instance' },
|
|
183
|
+
},
|
|
184
|
+
},
|
|
19
185
|
} as const satisfies ZoraComponentMeta;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { ThemeRecipeOverrideValue } from '@ankhorage/contracts';
|
|
2
|
+
|
|
3
|
+
import type { ZoraColor } from '../../internal/colorModel';
|
|
4
|
+
import type { RadioGroupProps } from './types';
|
|
5
|
+
|
|
6
|
+
type RadioGroupGap = NonNullable<RadioGroupProps<string>['gap']>;
|
|
7
|
+
type RadioGroupSize = NonNullable<RadioGroupProps<string>['size']>;
|
|
8
|
+
|
|
9
|
+
/***
|
|
10
|
+
* Resolves RadioGroup presentation props from instance overrides and the active theme recipe.
|
|
11
|
+
*/
|
|
12
|
+
export function resolveRadioGroupThemeRecipe(input: {
|
|
13
|
+
readonly gap?: RadioGroupGap;
|
|
14
|
+
readonly color?: ZoraColor;
|
|
15
|
+
readonly size?: RadioGroupSize;
|
|
16
|
+
readonly themeFields: Readonly<Record<string, ThemeRecipeOverrideValue>>;
|
|
17
|
+
}) {
|
|
18
|
+
return {
|
|
19
|
+
gap: input.gap ?? readGap(input.themeFields.gap) ?? 's',
|
|
20
|
+
color: input.color ?? readColor(input.themeFields.color) ?? 'primary',
|
|
21
|
+
size: input.size ?? readSize(input.themeFields.size) ?? 'm',
|
|
22
|
+
} as const;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/*** Reads a valid RadioGroup gap from a theme recipe value. */
|
|
26
|
+
function readGap(value: ThemeRecipeOverrideValue | undefined): RadioGroupGap | undefined {
|
|
27
|
+
if (value === 'xs' || value === 's' || value === 'm' || value === 'l') return value;
|
|
28
|
+
return undefined;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/*** Reads a valid ZORA color from a theme recipe value. */
|
|
32
|
+
function readColor(value: ThemeRecipeOverrideValue | undefined): ZoraColor | undefined {
|
|
33
|
+
if (value === 'primary' || value === 'secondary' || value === 'tertiary') return value;
|
|
34
|
+
if (value === 'quaternary' || value === 'neutral' || value === 'danger') return value;
|
|
35
|
+
if (value === 'success' || value === 'warning' || value === 'error' || value === 'info') {
|
|
36
|
+
return value;
|
|
37
|
+
}
|
|
38
|
+
return undefined;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/*** Reads a valid RadioGroup control size from a theme recipe value. */
|
|
42
|
+
function readSize(value: ThemeRecipeOverrideValue | undefined): RadioGroupSize | undefined {
|
|
43
|
+
if (value === 's' || value === 'm' || value === 'l') return value;
|
|
44
|
+
return undefined;
|
|
45
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { ZORA_COLORS } from '../../internal/colorModel';
|
|
2
|
+
import type { ZoraThemeRecipeMeta } from '../../metadata/themeRecipeTypes';
|
|
3
|
+
|
|
4
|
+
export const radioGroupThemeRecipeMeta = {
|
|
5
|
+
name: 'RadioGroup',
|
|
6
|
+
kind: 'component',
|
|
7
|
+
description: 'Maps shared selection-control presentation choices into RadioGroup defaults.',
|
|
8
|
+
fields: {
|
|
9
|
+
gap: {
|
|
10
|
+
type: 'choice',
|
|
11
|
+
label: 'Gap',
|
|
12
|
+
options: ['xs', 's', 'm', 'l'],
|
|
13
|
+
default: 's',
|
|
14
|
+
},
|
|
15
|
+
color: {
|
|
16
|
+
type: 'choice',
|
|
17
|
+
label: 'Color',
|
|
18
|
+
options: ZORA_COLORS,
|
|
19
|
+
default: 'primary',
|
|
20
|
+
},
|
|
21
|
+
size: {
|
|
22
|
+
type: 'choice',
|
|
23
|
+
label: 'Size',
|
|
24
|
+
options: ['s', 'm', 'l'],
|
|
25
|
+
default: 'm',
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
} as const satisfies ZoraThemeRecipeMeta;
|
|
@@ -126,6 +126,7 @@ describe('ZORA_COMPONENT_META invariants', () => {
|
|
|
126
126
|
'EmptyState',
|
|
127
127
|
'Hero',
|
|
128
128
|
'Button',
|
|
129
|
+
'RadioGroup',
|
|
129
130
|
'ThemeModeToggle',
|
|
130
131
|
'Input',
|
|
131
132
|
'Textarea',
|
|
@@ -198,6 +199,26 @@ describe('ZORA_COMPONENT_META invariants', () => {
|
|
|
198
199
|
expect(ZORA_COMPONENT_META.Image.props.alt?.authoring).toEqual({ authority: 'instance' });
|
|
199
200
|
});
|
|
200
201
|
|
|
202
|
+
test('RadioGroup is a direct manifest leaf with card presentation and normalized value events', () => {
|
|
203
|
+
const radioGroup = ZORA_COMPONENT_META.RadioGroup;
|
|
204
|
+
|
|
205
|
+
expect(radioGroup.directManifestNode).toBe(true);
|
|
206
|
+
expect(radioGroup.allowedChildren).toEqual([]);
|
|
207
|
+
expect(radioGroup.props.presentation?.enum).toEqual(['inline', 'card']);
|
|
208
|
+
expect(radioGroup.props.options?.type).toBe('array');
|
|
209
|
+
expect(radioGroup.props.options?.itemSchema?.map((item) => item.key)).toEqual([
|
|
210
|
+
'value',
|
|
211
|
+
'label',
|
|
212
|
+
'description',
|
|
213
|
+
'disabled',
|
|
214
|
+
]);
|
|
215
|
+
expect(radioGroup.bindings?.props?.value?.value).toEqual({ type: 'string' });
|
|
216
|
+
expect(radioGroup.events?.valueChange?.eventType).toBe('radioGroup.valueChange');
|
|
217
|
+
expect(radioGroup.events?.valueChange?.payloadFields).toEqual([
|
|
218
|
+
{ path: 'value', type: 'string', label: 'Value' },
|
|
219
|
+
]);
|
|
220
|
+
});
|
|
221
|
+
|
|
201
222
|
test('ThemeModeToggle is a direct manifest leaf with serializable defaults', () => {
|
|
202
223
|
expect(ZORA_COMPONENT_META.ThemeModeToggle.directManifestNode).toBe(true);
|
|
203
224
|
expect(ZORA_COMPONENT_META.ThemeModeToggle.allowedChildren).toEqual([]);
|
|
@@ -11,6 +11,7 @@ describe('ZORA_THEME_RECIPE_META', () => {
|
|
|
11
11
|
'Button',
|
|
12
12
|
'Card',
|
|
13
13
|
'Heading',
|
|
14
|
+
'RadioGroup',
|
|
14
15
|
'Text',
|
|
15
16
|
'Panel',
|
|
16
17
|
]);
|
|
@@ -50,6 +51,9 @@ describe('ZORA_THEME_RECIPE_META', () => {
|
|
|
50
51
|
test('keeps recipe defaults aligned with existing runtime behavior', () => {
|
|
51
52
|
expect(ZORA_THEME_RECIPE_META.Button?.fields.size?.default).toBe('l');
|
|
52
53
|
expect(ZORA_THEME_RECIPE_META.Card?.fields.padding?.default).toBeUndefined();
|
|
54
|
+
expect(ZORA_THEME_RECIPE_META.RadioGroup?.fields.gap?.default).toBe('s');
|
|
55
|
+
expect(ZORA_THEME_RECIPE_META.RadioGroup?.fields.color?.default).toBe('primary');
|
|
56
|
+
expect(ZORA_THEME_RECIPE_META.RadioGroup?.fields.size?.default).toBe('m');
|
|
53
57
|
expect(ZORA_THEME_RECIPE_META.Text?.fields.weight?.default).toBeUndefined();
|
|
54
58
|
expect(ZORA_THEME_RECIPE_META.Heading?.fields.size?.default).toBeUndefined();
|
|
55
59
|
});
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { buttonThemeRecipeMeta } from '../components/button/themeRecipeMeta';
|
|
2
2
|
import { cardThemeRecipeMeta } from '../components/card/themeRecipeMeta';
|
|
3
3
|
import { headingThemeRecipeMeta } from '../components/heading/themeRecipeMeta';
|
|
4
|
+
import { radioGroupThemeRecipeMeta } from '../components/radio/themeRecipeMeta';
|
|
4
5
|
import { textThemeRecipeMeta } from '../components/text/themeRecipeMeta';
|
|
5
6
|
import { panelThemeRecipeMeta } from '../patterns/panel/themeRecipeMeta';
|
|
6
7
|
import type { ZoraThemeRecipeMetaRegistry } from './themeRecipeTypes';
|
|
@@ -9,6 +10,7 @@ export const ZORA_THEME_RECIPE_META: ZoraThemeRecipeMetaRegistry = {
|
|
|
9
10
|
Button: buttonThemeRecipeMeta,
|
|
10
11
|
Card: cardThemeRecipeMeta,
|
|
11
12
|
Heading: headingThemeRecipeMeta,
|
|
13
|
+
RadioGroup: radioGroupThemeRecipeMeta,
|
|
12
14
|
Text: textThemeRecipeMeta,
|
|
13
15
|
Panel: panelThemeRecipeMeta,
|
|
14
16
|
};
|