@ankhorage/zora 17.0.0 → 18.0.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.
Files changed (145) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/README.md +1 -1
  3. package/dist/constants.d.ts +1 -1
  4. package/dist/constants.js +1 -1
  5. package/dist/constants.js.map +1 -1
  6. package/dist/features/auth/adapters/inbound/AuthFormField.js +3 -3
  7. package/dist/features/auth/adapters/inbound/AuthFormField.js.map +1 -1
  8. package/dist/features/form/field/adapters/inbound/Field.d.ts +5 -0
  9. package/dist/features/form/field/adapters/inbound/Field.d.ts.map +1 -0
  10. package/dist/features/form/field/adapters/inbound/Field.js +20 -0
  11. package/dist/features/form/field/adapters/inbound/Field.js.map +1 -0
  12. package/dist/features/form/{formFieldMeta.d.ts → field/meta.d.ts} +4 -4
  13. package/dist/features/form/field/meta.d.ts.map +1 -0
  14. package/dist/features/form/{formFieldMeta.js → field/meta.js} +4 -4
  15. package/dist/features/form/field/meta.js.map +1 -0
  16. package/dist/features/form/field/public.d.ts +2 -0
  17. package/dist/features/form/field/public.d.ts.map +1 -0
  18. package/dist/features/form/field/public.js +2 -0
  19. package/dist/features/form/field/public.js.map +1 -0
  20. package/dist/features/form/formMeta.d.ts +1 -1
  21. package/dist/features/form/formMeta.js +1 -1
  22. package/dist/features/form/formMeta.js.map +1 -1
  23. package/dist/features/form/public.d.ts +2 -2
  24. package/dist/features/form/public.d.ts.map +1 -1
  25. package/dist/features/form/public.js +1 -1
  26. package/dist/features/form/public.js.map +1 -1
  27. package/dist/features/list/adapters/inbound/List.d.ts +5 -0
  28. package/dist/features/list/adapters/inbound/List.d.ts.map +1 -0
  29. package/dist/features/list/adapters/inbound/List.js +34 -0
  30. package/dist/features/list/adapters/inbound/List.js.map +1 -0
  31. package/dist/features/list/adapters/inbound/ListItem.d.ts +5 -0
  32. package/dist/features/list/adapters/inbound/ListItem.d.ts.map +1 -0
  33. package/dist/features/list/adapters/inbound/ListItem.js +43 -0
  34. package/dist/features/list/adapters/inbound/ListItem.js.map +1 -0
  35. package/dist/features/list/adapters/inbound/ListSection.d.ts +5 -0
  36. package/dist/features/list/adapters/inbound/ListSection.d.ts.map +1 -0
  37. package/dist/{patterns/list → features/list/adapters/inbound}/ListSection.js +4 -8
  38. package/dist/features/list/adapters/inbound/ListSection.js.map +1 -0
  39. package/dist/{patterns → features}/list/meta.d.ts +6 -6
  40. package/dist/features/list/meta.d.ts.map +1 -0
  41. package/dist/{patterns → features}/list/meta.js +6 -14
  42. package/dist/features/list/meta.js.map +1 -0
  43. package/dist/features/list/public.d.ts +4 -0
  44. package/dist/features/list/public.d.ts.map +1 -1
  45. package/dist/features/list/public.js +3 -0
  46. package/dist/features/list/public.js.map +1 -1
  47. package/dist/features/list/utils/resolveListSeparator.d.ts +5 -0
  48. package/dist/features/list/utils/resolveListSeparator.d.ts.map +1 -0
  49. package/dist/{patterns/list → features/list/utils}/resolveListSeparator.js +1 -0
  50. package/dist/features/list/utils/resolveListSeparator.js.map +1 -0
  51. package/dist/features/skeleton/adapters/inbound/SkeletonList.d.ts.map +1 -1
  52. package/dist/features/skeleton/adapters/inbound/SkeletonList.js +2 -2
  53. package/dist/features/skeleton/adapters/inbound/SkeletonList.js.map +1 -1
  54. package/dist/features/uploader/adapters/inbound/Uploader.js +3 -3
  55. package/dist/features/uploader/adapters/inbound/Uploader.js.map +1 -1
  56. package/dist/index.d.ts +4 -4
  57. package/dist/index.d.ts.map +1 -1
  58. package/dist/index.js +2 -2
  59. package/dist/index.js.map +1 -1
  60. package/dist/metadata/bindableComponentMeta.d.ts +1 -1
  61. package/dist/metadata/bindableComponentMeta.js +1 -1
  62. package/dist/metadata/bindableComponentMeta.js.map +1 -1
  63. package/dist/metadata/componentMeta.js +4 -4
  64. package/dist/metadata/componentMeta.js.map +1 -1
  65. package/dist/patterns/inspector-field/InspectorField.js +3 -3
  66. package/dist/patterns/inspector-field/InspectorField.js.map +1 -1
  67. package/dist/patterns/switch-field/SwitchField.d.ts +1 -2
  68. package/dist/patterns/switch-field/SwitchField.d.ts.map +1 -1
  69. package/dist/patterns/switch-field/SwitchField.js +3 -4
  70. package/dist/patterns/switch-field/SwitchField.js.map +1 -1
  71. package/dist/patterns/tree-view/TreeItem.d.ts.map +1 -1
  72. package/dist/patterns/tree-view/TreeItem.js +2 -2
  73. package/dist/patterns/tree-view/TreeItem.js.map +1 -1
  74. package/dist/registry.js +4 -4
  75. package/dist/registry.js.map +1 -1
  76. package/dist/types/form.d.ts +1 -1
  77. package/dist/types/form.d.ts.map +1 -1
  78. package/dist/types/form.js.map +1 -1
  79. package/dist/{patterns/list/types.d.ts → types/list.d.ts} +14 -18
  80. package/dist/types/list.d.ts.map +1 -0
  81. package/dist/types/list.js +2 -0
  82. package/dist/types/list.js.map +1 -0
  83. package/package.json +2 -2
  84. package/src/constants.ts +1 -1
  85. package/src/features/auth/adapters/inbound/AuthFormField.tsx +3 -3
  86. package/src/features/bottom-sheet/public.test.ts +1 -1
  87. package/src/features/form/{adapters/inbound/FormField.tsx → field/adapters/inbound/Field.tsx} +10 -10
  88. package/src/features/form/{formFieldMeta.ts → field/meta.ts} +5 -4
  89. package/src/features/form/field/public.ts +1 -0
  90. package/src/features/form/formMeta.ts +1 -1
  91. package/src/features/form/public.ts +2 -2
  92. package/src/features/list/adapters/inbound/List.tsx +77 -0
  93. package/src/features/list/adapters/inbound/ListItem.tsx +89 -0
  94. package/src/{patterns/list → features/list/adapters/inbound}/ListSection.tsx +5 -10
  95. package/src/{patterns → features}/list/meta.ts +7 -14
  96. package/src/features/list/public.ts +11 -0
  97. package/src/features/list/utils/resolveListSeparator.ts +9 -0
  98. package/src/features/skeleton/adapters/inbound/SkeletonList.tsx +3 -3
  99. package/src/features/uploader/adapters/inbound/Uploader.tsx +3 -3
  100. package/src/index.ts +11 -10
  101. package/src/metadata/bindableComponentMeta.ts +1 -1
  102. package/src/metadata/componentMeta.test.ts +5 -5
  103. package/src/metadata/componentMeta.ts +4 -4
  104. package/src/patterns/inspector-field/InspectorField.tsx +3 -3
  105. package/src/patterns/switch-field/SwitchField.tsx +8 -8
  106. package/src/patterns/tree-view/TreeItem.tsx +2 -2
  107. package/src/registry.ts +4 -4
  108. package/src/showcaseCoverage.test.ts +2 -2
  109. package/src/theme/themeScopeStructure.test.ts +5 -5
  110. package/src/types/form.ts +1 -1
  111. package/src/{patterns/list/types.ts → types/list.ts} +17 -18
  112. package/dist/features/form/adapters/inbound/FormField.d.ts +0 -5
  113. package/dist/features/form/adapters/inbound/FormField.d.ts.map +0 -1
  114. package/dist/features/form/adapters/inbound/FormField.js +0 -20
  115. package/dist/features/form/adapters/inbound/FormField.js.map +0 -1
  116. package/dist/features/form/formFieldMeta.d.ts.map +0 -1
  117. package/dist/features/form/formFieldMeta.js.map +0 -1
  118. package/dist/patterns/list/List.d.ts +0 -9
  119. package/dist/patterns/list/List.d.ts.map +0 -1
  120. package/dist/patterns/list/List.js +0 -40
  121. package/dist/patterns/list/List.js.map +0 -1
  122. package/dist/patterns/list/ListRow.d.ts +0 -9
  123. package/dist/patterns/list/ListRow.d.ts.map +0 -1
  124. package/dist/patterns/list/ListRow.js +0 -113
  125. package/dist/patterns/list/ListRow.js.map +0 -1
  126. package/dist/patterns/list/ListSection.d.ts +0 -9
  127. package/dist/patterns/list/ListSection.d.ts.map +0 -1
  128. package/dist/patterns/list/ListSection.js.map +0 -1
  129. package/dist/patterns/list/index.d.ts +0 -5
  130. package/dist/patterns/list/index.d.ts.map +0 -1
  131. package/dist/patterns/list/index.js +0 -4
  132. package/dist/patterns/list/index.js.map +0 -1
  133. package/dist/patterns/list/meta.d.ts.map +0 -1
  134. package/dist/patterns/list/meta.js.map +0 -1
  135. package/dist/patterns/list/resolveListSeparator.d.ts +0 -5
  136. package/dist/patterns/list/resolveListSeparator.d.ts.map +0 -1
  137. package/dist/patterns/list/resolveListSeparator.js.map +0 -1
  138. package/dist/patterns/list/types.d.ts.map +0 -1
  139. package/dist/patterns/list/types.js +0 -2
  140. package/dist/patterns/list/types.js.map +0 -1
  141. package/src/patterns/list/List.tsx +0 -77
  142. package/src/patterns/list/ListRow.tsx +0 -198
  143. package/src/patterns/list/index.ts +0 -10
  144. package/src/patterns/list/resolveListSeparator.test.ts +0 -18
  145. package/src/patterns/list/resolveListSeparator.ts +0 -8
@@ -1,12 +1,12 @@
1
- import { Field } from '@ankhorage/surface';
1
+ import { Field as SurfaceField } from '@ankhorage/surface';
2
2
  import React from 'react';
3
3
 
4
- import { withZoraThemeScope } from '../../../../theme/withZoraThemeScope';
5
- import type { FormFieldProps } from '../../../../types/form';
6
- import { View } from '../../../layout/public';
7
- import { Text } from '../../../typography/public';
4
+ import { withZoraThemeScope } from '../../../../../theme/withZoraThemeScope';
5
+ import type { FieldProps } from '../../../../../types/form';
6
+ import { View } from '../../../../layout/public';
7
+ import { Text } from '../../../../typography/public';
8
8
 
9
- function FormFieldInner({
9
+ function FieldInner({
10
10
  themeId: _themeId,
11
11
  mode: _mode,
12
12
  label,
@@ -15,9 +15,9 @@ function FormFieldInner({
15
15
  children,
16
16
  interactionPolicy: _interactionPolicy,
17
17
  ...props
18
- }: FormFieldProps) {
18
+ }: FieldProps) {
19
19
  return (
20
- <Field
20
+ <SurfaceField
21
21
  {...props}
22
22
  helperText={helperText}
23
23
  label={
@@ -34,9 +34,9 @@ function FormFieldInner({
34
34
  }
35
35
  >
36
36
  {children}
37
- </Field>
37
+ </SurfaceField>
38
38
  );
39
39
  }
40
40
 
41
41
  /*** Groups one form control with its label, description, helper text, and field error. */
42
- export const FormField = withZoraThemeScope(FormFieldInner);
42
+ export const Field = withZoraThemeScope(FieldInner);
@@ -1,6 +1,7 @@
1
- import type { ZoraComponentMeta } from '../../metadata';
2
- export const formFieldMeta = {
3
- name: 'FormField',
1
+ import type { ZoraComponentMeta } from '../../../metadata';
2
+
3
+ export const fieldMeta = {
4
+ name: 'Field',
4
5
  category: 'component',
5
6
  directManifestNode: true,
6
7
  allowedChildren: [
@@ -11,7 +12,7 @@ export const formFieldMeta = {
11
12
  'Select',
12
13
  'TextInput',
13
14
  ],
14
- blueprint: { label: 'Form field', defaultProps: { label: 'Label' } },
15
+ blueprint: { label: 'Field', defaultProps: { label: 'Label' } },
15
16
  bindings: {
16
17
  props: {
17
18
  errorText: {
@@ -0,0 +1 @@
1
+ export { Field } from './adapters/inbound/Field';
@@ -3,7 +3,7 @@ export const formMeta = {
3
3
  name: 'Form',
4
4
  category: 'component',
5
5
  directManifestNode: true,
6
- allowedChildren: ['FormError', 'FormField'],
6
+ allowedChildren: ['FormError', 'Field'],
7
7
  blueprint: {
8
8
  label: 'Form',
9
9
  defaultProps: { submitLabel: 'Submit', loading: false, disabled: false },
@@ -1,10 +1,10 @@
1
1
  export type {
2
+ FieldProps,
2
3
  FormActionsProps,
3
4
  FormErrorProps,
4
5
  FormErrors,
5
6
  FormFieldConfig,
6
7
  FormFieldInputType,
7
- FormFieldProps,
8
8
  FormProps,
9
9
  FormValidationErrors,
10
10
  FormValidationResult,
@@ -16,6 +16,6 @@ export type {
16
16
  export { Form } from './adapters/inbound/Form';
17
17
  export { FormActions } from './adapters/inbound/FormActions';
18
18
  export { FormError } from './adapters/inbound/FormError';
19
- export { FormField } from './adapters/inbound/FormField';
19
+ export { Field } from './field/public';
20
20
  export { useFormController } from './useFormController';
21
21
  export { hasRequiredRule, validateField, validateFields, validateValue } from './utils/validation';
@@ -0,0 +1,77 @@
1
+ import { List as SurfaceList } from '@ankhorage/surface';
2
+ import React from 'react';
3
+
4
+ import { withZoraThemeScope } from '../../../../theme/withZoraThemeScope';
5
+ import type {
6
+ ListItemProps,
7
+ ListItemsProps,
8
+ ListItemVariant,
9
+ ListProps,
10
+ } from '../../../../types/list';
11
+ import { Divider, View } from '../../../layout/public';
12
+ import { resolveListSeparator } from '../../utils/resolveListSeparator';
13
+ import { ListItem } from './ListItem';
14
+
15
+ function resolveItemVariant({
16
+ item,
17
+ defaultVariant,
18
+ }: {
19
+ item: ListItemProps;
20
+ defaultVariant: ListItemVariant;
21
+ }): ListItemVariant {
22
+ return item.variant ?? defaultVariant;
23
+ }
24
+
25
+ function resolveItemCompact({
26
+ item,
27
+ compact,
28
+ }: {
29
+ item: ListItemProps;
30
+ compact: boolean | undefined;
31
+ }): boolean {
32
+ return item.compact ?? compact ?? false;
33
+ }
34
+
35
+ function ListItemsInner({
36
+ themeId: _themeId,
37
+ mode: _mode,
38
+ testID,
39
+ items,
40
+ itemVariant = 'divider',
41
+ compact,
42
+ }: ListItemsProps) {
43
+ return (
44
+ <SurfaceList testID={testID}>
45
+ {items.map((item, index) => {
46
+ const effectiveVariant = resolveItemVariant({ item, defaultVariant: itemVariant });
47
+ const separator = resolveListSeparator(effectiveVariant, index);
48
+ return (
49
+ <React.Fragment key={String(index)}>
50
+ {separator === 'divider' ? <Divider /> : null}
51
+ {separator === 'spacer' ? <View height="s" /> : null}
52
+ <ListItem
53
+ {...item}
54
+ compact={resolveItemCompact({ item, compact })}
55
+ variant={effectiveVariant}
56
+ />
57
+ </React.Fragment>
58
+ );
59
+ })}
60
+ </SurfaceList>
61
+ );
62
+ }
63
+
64
+ function ListInner(props: ListProps) {
65
+ if ('items' in props) return <ListItemsInner {...props} />;
66
+ const {
67
+ themeId: _themeId,
68
+ mode: _mode,
69
+ interactionPolicy: _interactionPolicy,
70
+ children,
71
+ testID,
72
+ } = props;
73
+ return <SurfaceList testID={testID}>{children}</SurfaceList>;
74
+ }
75
+
76
+ /*** List composition built on the Surface list boundary with ZORA item/separator policy. */
77
+ export const List = withZoraThemeScope(ListInner);
@@ -0,0 +1,89 @@
1
+ import { ListItem as SurfaceListItem } from '@ankhorage/surface';
2
+ import React from 'react';
3
+
4
+ import { useZoraTheme } from '../../../../theme/useZoraTheme';
5
+ import { withZoraThemeScope } from '../../../../theme/withZoraThemeScope';
6
+ import type { ListItemProps, ListItemVariant } from '../../../../types/list';
7
+ import { View } from '../../../layout/public';
8
+ import { Text } from '../../../typography/public';
9
+
10
+ function ListItemInner({
11
+ themeId: _themeId,
12
+ mode: _mode,
13
+ testID,
14
+ interactionPolicy,
15
+ title,
16
+ description,
17
+ meta,
18
+ leading,
19
+ trailing,
20
+ action,
21
+ onPress,
22
+ selected = false,
23
+ disabled = false,
24
+ compact = false,
25
+ variant = 'divider',
26
+ }: ListItemProps) {
27
+ const { theme } = useZoraTheme();
28
+ const trailingContent = renderTrailing(trailing, action);
29
+
30
+ return (
31
+ <View
32
+ bg={variant === 'card' ? theme.semantics.surface.raised : 'transparent'}
33
+ borderColor={
34
+ selected
35
+ ? theme.semantics.border.focus
36
+ : variant === 'card'
37
+ ? theme.semantics.border.default
38
+ : 'transparent'
39
+ }
40
+ borderWidth={variant === 'card' || selected ? 1 : 0}
41
+ overflow="hidden"
42
+ radius={resolveRadius(variant)}
43
+ >
44
+ <SurfaceListItem
45
+ compact={compact}
46
+ disabled={disabled}
47
+ interactionPolicy={interactionPolicy}
48
+ leading={leading}
49
+ onPress={action ? undefined : onPress}
50
+ selected={selected}
51
+ testID={testID}
52
+ trailing={trailingContent}
53
+ >
54
+ <View gap="xxs">
55
+ <Text variant="body" weight={selected ? 'semiBold' : 'medium'}>
56
+ {title}
57
+ </Text>
58
+ {description ? (
59
+ <Text emphasis="muted" variant="bodySmall">
60
+ {description}
61
+ </Text>
62
+ ) : null}
63
+ {meta ? (
64
+ <Text emphasis="subtle" variant="caption">
65
+ {meta}
66
+ </Text>
67
+ ) : null}
68
+ </View>
69
+ </SurfaceListItem>
70
+ </View>
71
+ );
72
+ }
73
+
74
+ function resolveRadius(variant: ListItemVariant) {
75
+ return variant === 'card' ? ('l' as const) : ('m' as const);
76
+ }
77
+
78
+ function renderTrailing(trailing: React.ReactNode, action: React.ReactNode) {
79
+ if (!trailing && !action) return undefined;
80
+ return (
81
+ <View align="center" direction="row" gap="s" wrap="nowrap">
82
+ {trailing}
83
+ {action}
84
+ </View>
85
+ );
86
+ }
87
+
88
+ /*** Opinionated list item built on the Surface list-item interaction and geometry boundary. */
89
+ export const ListItem = withZoraThemeScope(ListItemInner);
@@ -1,10 +1,10 @@
1
1
  import React from 'react';
2
2
 
3
- import { View } from '../../features/layout/public';
4
- import { withZoraThemeScope } from '../../theme/withZoraThemeScope';
5
- import { SectionHeader } from '../section-header';
3
+ import { SectionHeader } from '../../../../patterns/section-header';
4
+ import { withZoraThemeScope } from '../../../../theme/withZoraThemeScope';
5
+ import type { ListSectionProps } from '../../../../types/list';
6
+ import { View } from '../../../layout/public';
6
7
  import { List } from './List';
7
- import type { ListSectionProps } from './types';
8
8
 
9
9
  function ListSectionInner({
10
10
  themeId: _themeId,
@@ -17,7 +17,6 @@ function ListSectionInner({
17
17
  ...props
18
18
  }: ListSectionProps) {
19
19
  const hasHeader = title !== undefined;
20
-
21
20
  return (
22
21
  <View gap="s" testID={testID}>
23
22
  {hasHeader ? (
@@ -33,9 +32,5 @@ function ListSectionInner({
33
32
  );
34
33
  }
35
34
 
36
- /***
37
- * Section wrapper for lists with optional title and description.
38
- *
39
-
40
- */
35
+ /*** Section wrapper for lists with optional ZORA section-heading semantics. */
41
36
  export const ListSection = withZoraThemeScope(ListSectionInner);
@@ -1,6 +1,7 @@
1
1
  import type { ZoraComponentMeta } from '../../metadata';
2
2
 
3
- const LIST_NOTE = 'List pattern component; not represented as a manifest node in v1.';
3
+ const LIST_NOTE =
4
+ 'List feature component; collection authoring is represented through List metadata.';
4
5
 
5
6
  export const listMeta = {
6
7
  name: 'List',
@@ -11,8 +12,8 @@ export const listMeta = {
11
12
  props: {},
12
13
  } as const satisfies ZoraComponentMeta;
13
14
 
14
- export const listRowMeta = {
15
- name: 'ListRow',
15
+ export const listItemMeta = {
16
+ name: 'ListItem',
16
17
  category: 'pattern',
17
18
  directManifestNode: false,
18
19
  allowedChildren: [],
@@ -21,18 +22,10 @@ export const listRowMeta = {
21
22
  itemPress: {
22
23
  label: 'Item press',
23
24
  eventType: 'collection.itemPress',
24
- description: 'Emitted when a collection item row is selected.',
25
+ description: 'Emitted when a collection item is selected.',
25
26
  payloadFields: [
26
- {
27
- path: 'payload.itemId',
28
- type: 'string',
29
- label: 'Item ID',
30
- },
31
- {
32
- path: 'payload.item',
33
- type: 'record',
34
- label: 'Item',
35
- },
27
+ { path: 'payload.itemId', type: 'string', label: 'Item ID' },
28
+ { path: 'payload.item', type: 'record', label: 'Item' },
36
29
  ],
37
30
  },
38
31
  },
@@ -1,7 +1,18 @@
1
+ export type {
2
+ ListChildrenProps,
3
+ ListItemProps,
4
+ ListItemsProps,
5
+ ListItemVariant,
6
+ ListProps,
7
+ ListSectionProps,
8
+ } from '../../types/list';
1
9
  export type {
2
10
  ManifestListProps,
3
11
  ManifestListSection,
4
12
  ManifestSectionListProps,
5
13
  } from '../../types/manifest-list';
6
14
  export { FlatList } from './adapters/inbound/FlatList';
15
+ export { List } from './adapters/inbound/List';
16
+ export { ListItem } from './adapters/inbound/ListItem';
17
+ export { ListSection } from './adapters/inbound/ListSection';
7
18
  export { SectionList } from './adapters/inbound/SectionList';
@@ -0,0 +1,9 @@
1
+ import type { ListItemVariant } from '../../../types/list';
2
+
3
+ export type ListSeparatorKind = 'none' | 'divider' | 'spacer';
4
+
5
+ /*** Resolves the separator preceding an item for the active list presentation. */
6
+ export function resolveListSeparator(variant: ListItemVariant, index: number): ListSeparatorKind {
7
+ if (index === 0) return 'none';
8
+ return variant === 'divider' ? 'divider' : 'spacer';
9
+ }
@@ -1,8 +1,8 @@
1
1
  import React from 'react';
2
2
 
3
- import { List, type ListRowProps } from '../../../../patterns/list';
4
3
  import { withZoraThemeScope } from '../../../../theme/withZoraThemeScope';
5
4
  import type { SkeletonListProps } from '../../../../types/skeleton';
5
+ import { List, type ListItemProps } from '../../../list/public';
6
6
  import { Skeleton } from './Skeleton';
7
7
  import { SkeletonText } from './SkeletonText';
8
8
 
@@ -38,7 +38,7 @@ function SkeletonListInner({
38
38
  compact = false,
39
39
  }: SkeletonListProps) {
40
40
  const rowCount = clampRows(rows);
41
- const items: ListRowProps[] = Array.from({ length: rowCount }).map(() => ({
41
+ const items: ListItemProps[] = Array.from({ length: rowCount }).map(() => ({
42
42
  compact,
43
43
  description: <SkeletonText lines={lines} />,
44
44
  leading: renderLeading({ avatar, media }),
@@ -46,7 +46,7 @@ function SkeletonListInner({
46
46
  variant,
47
47
  }));
48
48
 
49
- return <List compact={compact} items={items} rowVariant={variant} testID={testID} />;
49
+ return <List compact={compact} items={items} itemVariant={variant} testID={testID} />;
50
50
  }
51
51
 
52
52
  /***
@@ -4,7 +4,7 @@ import { withZoraThemeScope } from '../../../../theme/withZoraThemeScope';
4
4
  import type { UploadAsset, UploaderProps, UploadType } from '../../../../types/upload';
5
5
  import { Button } from '../../../button/public';
6
6
  import { Dialog } from '../../../dialog/public';
7
- import { FormField } from '../../../form/public';
7
+ import { Field } from '../../../form/public';
8
8
  import { Icon } from '../../../icon/public';
9
9
  import { Image } from '../../../image/public';
10
10
  import { View } from '../../../layout/public';
@@ -206,7 +206,7 @@ function UploaderInner({
206
206
 
207
207
  return (
208
208
  <>
209
- <FormField
209
+ <Field
210
210
  description={description}
211
211
  disabled={disabled}
212
212
  errorText={effectiveError}
@@ -285,7 +285,7 @@ function UploaderInner({
285
285
  ) : null}
286
286
  </View>
287
287
  </View>
288
- </FormField>
288
+ </Field>
289
289
 
290
290
  {canPreviewImage ? (
291
291
  <Dialog
package/src/index.ts CHANGED
@@ -128,12 +128,12 @@ export {
128
128
  type CheckboxProps,
129
129
  } from './features/form/checkbox/public';
130
130
  export type {
131
+ FieldProps,
131
132
  FormActionsProps,
132
133
  FormErrorProps,
133
134
  FormErrors,
134
135
  FormFieldConfig,
135
136
  FormFieldInputType,
136
- FormFieldProps,
137
137
  FormProps,
138
138
  FormValidationErrors,
139
139
  FormValidationResult,
@@ -143,10 +143,10 @@ export type {
143
143
  ValidationRule,
144
144
  } from './features/form/public';
145
145
  export {
146
+ Field,
146
147
  Form,
147
148
  FormActions,
148
149
  FormError,
149
- FormField,
150
150
  hasRequiredRule,
151
151
  useFormController,
152
152
  validateField,
@@ -218,7 +218,16 @@ export type {
218
218
  ManifestListSection,
219
219
  ManifestSectionListProps,
220
220
  } from './features/list/public';
221
+ export type {
222
+ ListChildrenProps,
223
+ ListItemProps,
224
+ ListItemsProps,
225
+ ListItemVariant,
226
+ ListProps,
227
+ ListSectionProps,
228
+ } from './features/list/public';
221
229
  export { FlatList, SectionList } from './features/list/public';
230
+ export { List, ListItem, ListSection } from './features/list/public';
222
231
  export { MissingElement, type MissingElementProps } from './features/missing-element/public';
223
232
  export { Pagination, type PaginationProps } from './features/pagination/public';
224
233
  export type { PaletteItemProps } from './features/palette-item/public';
@@ -361,14 +370,6 @@ export type { FilterBarProps } from './patterns/filter-bar';
361
370
  export { FilterBar } from './patterns/filter-bar';
362
371
  export type { InspectorFieldProps } from './patterns/inspector-field';
363
372
  export { InspectorField } from './patterns/inspector-field';
364
- export type {
365
- ListChildrenProps,
366
- ListItemsProps,
367
- ListProps,
368
- ListRowProps,
369
- ListRowVariant,
370
- } from './patterns/list';
371
- export { List, ListRow, ListSection } from './patterns/list';
372
373
  export type {
373
374
  MessageBubbleAuthor,
374
375
  MessageBubbleAvatar,
@@ -356,7 +356,7 @@ export const ZORA_BINDABLE_COMPONENT_META = {
356
356
  category: 'pattern',
357
357
  description: 'Renders a collection of list items.',
358
358
  directManifestNode: true,
359
- allowedChildren: ['ListSection', 'ListRow'],
359
+ allowedChildren: ['ListSection', 'ListItem'],
360
360
  bindings: {
361
361
  props: {
362
362
  items: {
@@ -63,7 +63,7 @@ describe('ZORA_COMPONENT_META event metadata', () => {
63
63
  });
64
64
 
65
65
  test('declares collection item metadata for list rows', () => {
66
- const event = ZORA_COMPONENT_META.ListRow.events?.itemPress;
66
+ const event = ZORA_COMPONENT_META.ListItem.events?.itemPress;
67
67
  const eventType: ZoraComponentEventPayloadKind = event?.eventType ?? 'collection.itemPress';
68
68
 
69
69
  expect(eventType).toBe('collection.itemPress');
@@ -101,8 +101,8 @@ describe('ZORA_COMPONENT_META requirement metadata', () => {
101
101
 
102
102
  describe('ZORA_COMPONENT_META invariants', () => {
103
103
  test('keeps form nodes in their canonical hierarchy', () => {
104
- expect(ZORA_COMPONENT_META.Form.allowedChildren).toEqual(['FormError', 'FormField']);
105
- expect(ZORA_COMPONENT_META.FormField.allowedChildren).toEqual([
104
+ expect(ZORA_COMPONENT_META.Form.allowedChildren).toEqual(['FormError', 'Field']);
105
+ expect(ZORA_COMPONENT_META.Field.allowedChildren).toEqual([
106
106
  'Checkbox',
107
107
  'CheckboxGroup',
108
108
  'RadioGroup',
@@ -113,7 +113,7 @@ describe('ZORA_COMPONENT_META invariants', () => {
113
113
  for (const [name, meta] of Object.entries(ZORA_COMPONENT_META)) {
114
114
  if (name === 'Form') continue;
115
115
  expect(meta.allowedChildren).not.toContain('FormError');
116
- expect(meta.allowedChildren).not.toContain('FormField');
116
+ expect(meta.allowedChildren).not.toContain('Field');
117
117
  }
118
118
  });
119
119
 
@@ -204,7 +204,7 @@ describe('ZORA_COMPONENT_META invariants', () => {
204
204
  'SectionList',
205
205
  'BottomSheet',
206
206
  'KeyboardAvoidingView',
207
- 'FormField',
207
+ 'Field',
208
208
  'ButtonGroup',
209
209
  'Screen',
210
210
  'ScreenSection',
@@ -29,9 +29,9 @@ import { datePickerMeta } from '../features/date-picker/datePickerMeta';
29
29
  import { dialogMeta } from '../features/dialog/dialogMeta';
30
30
  import { emptyStateMeta } from '../features/empty-state/emptyStateMeta';
31
31
  import { checkboxGroupMeta, checkboxMeta } from '../features/form/checkbox/checkboxMeta';
32
+ import { fieldMeta } from '../features/form/field/meta';
32
33
  import { formActionsMeta } from '../features/form/formActionsMeta';
33
34
  import { formErrorMeta } from '../features/form/formErrorMeta';
34
- import { formFieldMeta } from '../features/form/formFieldMeta';
35
35
  import { formMeta } from '../features/form/formMeta';
36
36
  import { radioGroupMeta, radioMeta } from '../features/form/radio/radioMeta';
37
37
  import { searchInputMeta } from '../features/form/search-input/searchInputMeta';
@@ -50,6 +50,7 @@ import { screenSectionMeta } from '../features/layout/screenSectionMeta';
50
50
  import { scrollViewMeta } from '../features/layout/scrollViewMeta';
51
51
  import { viewMeta } from '../features/layout/viewMeta';
52
52
  import { flatListMeta } from '../features/list/flatListMeta';
53
+ import { listItemMeta, listMeta, listSectionMeta } from '../features/list/meta';
53
54
  import { sectionListMeta } from '../features/list/sectionListMeta';
54
55
  import { missingElementMeta } from '../features/missing-element/missingElementMeta';
55
56
  import { paginationMeta } from '../features/pagination/paginationMeta';
@@ -80,7 +81,6 @@ import { collectionEditorMeta } from '../patterns/collection-editor/meta';
80
81
  import { confirmDialogMeta } from '../patterns/confirm-dialog/meta';
81
82
  import { filterBarMeta } from '../patterns/filter-bar/meta';
82
83
  import { inspectorFieldMeta } from '../patterns/inspector-field/meta';
83
- import { listMeta, listRowMeta, listSectionMeta } from '../patterns/list/meta';
84
84
  import { messageBubbleMeta } from '../patterns/message-bubble/meta';
85
85
  import { noticeMeta } from '../patterns/notice/meta';
86
86
  import { panelMeta } from '../patterns/panel/meta';
@@ -127,7 +127,7 @@ export const ZORA_COMPONENT_META: ZoraComponentMetaRegistry = finalizeFeatureMet
127
127
  Form: formMeta,
128
128
  FormActions: formActionsMeta,
129
129
  FormError: formErrorMeta,
130
- FormField: formFieldMeta,
130
+ Field: fieldMeta,
131
131
  Gradient: gradientMeta,
132
132
  Heading: headingMeta,
133
133
  Icon: iconMeta,
@@ -182,7 +182,7 @@ export const ZORA_COMPONENT_META: ZoraComponentMetaRegistry = finalizeFeatureMet
182
182
  Hero: heroMeta,
183
183
  InspectorField: inspectorFieldMeta,
184
184
  List: listMeta,
185
- ListRow: listRowMeta,
185
+ ListItem: listItemMeta,
186
186
  ListSection: listSectionMeta,
187
187
  MessageBubble: messageBubbleMeta,
188
188
  MissingElement: missingElementMeta,
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
 
3
- import { FormField } from '../../features/form/public';
3
+ import { Field } from '../../features/form/public';
4
4
  import { View } from '../../features/layout/public';
5
5
  import { withZoraThemeScope } from '../../theme/withZoraThemeScope';
6
6
  import type { InspectorFieldProps } from './types';
@@ -15,12 +15,12 @@ function InspectorFieldInner({
15
15
  ...props
16
16
  }: InspectorFieldProps) {
17
17
  return (
18
- <FormField {...props} label={label}>
18
+ <Field {...props} label={label}>
19
19
  <View direction="row" gap="s" align="center">
20
20
  <View flex={1}>{children}</View>
21
21
  {control ? <View>{control}</View> : null}
22
22
  </View>
23
- </FormField>
23
+ </Field>
24
24
  );
25
25
  }
26
26
 
@@ -1,8 +1,8 @@
1
1
  import { Switch } from '@ankhorage/surface';
2
2
  import React from 'react';
3
3
 
4
+ import { ListItem } from '../../features/list/public';
4
5
  import { withZoraThemeScope } from '../../theme/withZoraThemeScope';
5
- import { ListRow } from '../list';
6
6
  import type { SwitchFieldProps } from './types';
7
7
 
8
8
  function SwitchFieldInner({
@@ -17,11 +17,7 @@ function SwitchFieldInner({
17
17
  interactionPolicy,
18
18
  }: SwitchFieldProps) {
19
19
  return (
20
- <ListRow
21
- title={label}
22
- description={description}
23
- disabled={disabled}
24
- testID={testID}
20
+ <ListItem
25
21
  action={
26
22
  <Switch
27
23
  checked={value}
@@ -30,13 +26,17 @@ function SwitchFieldInner({
30
26
  onCheckedChange={onValueChange}
31
27
  />
32
28
  }
29
+ description={description}
30
+ disabled={disabled}
31
+ testID={testID}
32
+ title={label}
33
+ variant="card"
33
34
  />
34
35
  );
35
36
  }
36
37
 
37
38
  /***
38
- * Labeled switch field pattern built on `ListRow`.
39
+ * Labeled switch field pattern built on the card-style `ListItem` presentation.
39
40
  *
40
-
41
41
  */
42
42
  export const SwitchField = withZoraThemeScope(SwitchFieldInner);
@@ -2,9 +2,9 @@ import React from 'react';
2
2
 
3
3
  import { IconButton } from '../../features/button/public';
4
4
  import { View } from '../../features/layout/public';
5
+ import { ListItem } from '../../features/list/public';
5
6
  import { withZoraThemeScope } from '../../theme/withZoraThemeScope';
6
7
  import type { ZoraBaseProps } from '../../theme/ZoraBaseProps';
7
- import { ListRow } from '../list';
8
8
  import type { TreeItemNode, TreeItemRenderProps } from './types';
9
9
 
10
10
  interface TreeItemProps<TId extends string = string> extends ZoraBaseProps {
@@ -46,7 +46,7 @@ function TreeItemInner<TId extends string = string>({
46
46
  }
47
47
 
48
48
  return (
49
- <ListRow
49
+ <ListItem
50
50
  title={node.label}
51
51
  action={
52
52
  <View direction="row" gap="xs" align="center">