@ankhorage/zora 2.4.8 → 2.5.1

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.
@@ -1 +1 @@
1
- {"version":3,"file":"ResponsivePanel.js","sourceRoot":"","sources":["../../../src/patterns/responsive-panel/ResponsivePanel.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AACjD,OAAO,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAC;AAC/C,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AACpE,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAGjC,SAAS,oBAAoB,CAAC,EAC5B,OAAO,EAAE,QAAQ,EACjB,IAAI,EAAE,KAAK,EACX,KAAK,EACL,WAAW,EACX,OAAO,EACP,MAAM,EACN,QAAQ,EACR,IAAI,EACJ,YAAY,EACZ,IAAI,GAAG,OAAO,EACd,WAAW,GAAG,QAAQ,EACtB,UAAU,GAAG,QAAQ,EACrB,OAAO,GAAG,IAAI,EACd,MAAM,GACe;IACrB,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IAEvB,2DAA2D;IAC3D,kDAAkD;IAClD,IAAI,WAAW,KAAK,UAAU,EAAE,CAAC;QAC/B,IAAI,UAAU,KAAK,OAAO,EAAE,CAAC;YAC3B,OAAO,CACL,CAAC,KAAK,CACJ,WAAW,CAAC,CAAC,WAAW,CAAC,CACzB,MAAM,CAAC,CAAC,MAAM,CAAC,CACf,SAAS,CAAC,CAAC,GAAG,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CACrC,MAAM,CAAC,CAAC,MAAM,CAAC,CACf,KAAK,CAAC,CAAC,KAAK,CAAC,CACb,OAAO,CAAC,CAAC,IAAI,CAAC,CAEd;UAAA,CAAC,QAAQ,CACX;QAAA,EAAE,KAAK,CAAC,CACT,CAAC;QACJ,CAAC;QAED,OAAO,CACL,CAAC,MAAM,CACL,WAAW,CAAC,CAAC,WAAW,CAAC,CACzB,MAAM,CAAC,CAAC,MAAM,CAAC,CACf,SAAS,CAAC,CAAC,GAAG,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CACrC,QAAQ,CAAC,CAAC,IAAI,CAAC,CACf,MAAM,CAAC,CAAC,MAAM,CAAC,CACf,KAAK,CAAC,CAAC,KAAK,CAAC,CACb,OAAO,CAAC,CAAC,IAAI,CAAC,CAEd;QAAA,CAAC,QAAQ,CACX;MAAA,EAAE,MAAM,CAAC,CACV,CAAC;IACJ,CAAC;IAED,2BAA2B;IAC3B,OAAO,CACL,CAAC,KAAK,CACJ,OAAO,CAAC,CAAC,OAAO,CAAC,CACjB,OAAO,CAAC,CAAC,OAAO,CAAC,CACjB,WAAW,CAAC,CAAC,WAAW,CAAC,CACzB,MAAM,CAAC,CAAC,MAAM,CAAC,CACf,MAAM,CAAC,CAAC,MAAM,CAAC,CACf,KAAK,CAAC,CAAC,KAAK,CAAC,CAEb;MAAA,CAAC,QAAQ,CACX;IAAA,EAAE,KAAK,CAAC,CACT,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,eAAe,GAAG,kBAAkB,CAAC,oBAAoB,CAAC,CAAC","sourcesContent":["import React from 'react';\n\nimport { Drawer } from '../../components/drawer';\nimport { Modal } from '../../components/modal';\nimport { withZoraThemeScope } from '../../theme/withZoraThemeScope';\nimport { Panel } from '../panel';\nimport type { ResponsivePanelProps } from './types';\n\nfunction ResponsivePanelInner({\n themeId: _themeId,\n mode: _mode,\n title,\n description,\n actions,\n footer,\n children,\n open,\n onOpenChange,\n side = 'right',\n desktopMode = 'inline',\n mobileMode = 'drawer',\n compact = true,\n testID,\n}: ResponsivePanelProps) {\n if (!open) return null;\n\n // For now, we assume desktopMode determines the rendering.\n // In a real app, this would react to window size.\n if (desktopMode === 'floating') {\n if (mobileMode === 'modal') {\n return (\n <Modal\n description={description}\n footer={footer}\n onDismiss={() => onOpenChange(false)}\n testID={testID}\n title={title}\n visible={open}\n >\n {children}\n </Modal>\n );\n }\n\n return (\n <Drawer\n description={description}\n footer={footer}\n onDismiss={() => onOpenChange(false)}\n position={side}\n testID={testID}\n title={title}\n visible={open}\n >\n {children}\n </Drawer>\n );\n }\n\n // default: inline -> Panel\n return (\n <Panel\n actions={actions}\n compact={compact}\n description={description}\n footer={footer}\n testID={testID}\n title={title}\n >\n {children}\n </Panel>\n );\n}\n\nexport const ResponsivePanel = withZoraThemeScope(ResponsivePanelInner);\n"]}
1
+ {"version":3,"file":"ResponsivePanel.js","sourceRoot":"","sources":["../../../src/patterns/responsive-panel/ResponsivePanel.tsx"],"names":[],"mappings":"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","sourcesContent":["import React from 'react';\nimport { ScrollView, StyleSheet, View } from 'react-native';\n\nimport { Drawer } from '../../components/drawer';\nimport { Modal } from '../../components/modal';\nimport type { ZoraContentWidth } from '../../internal/recipes';\nimport { withZoraThemeScope } from '../../theme/withZoraThemeScope';\nimport { Panel } from '../panel';\nimport type { ResponsivePanelProps, ResponsivePanelScroll, ResponsivePanelSize } from './types';\n\nfunction resolvePanelWidth(size: ResponsivePanelSize): number {\n switch (size) {\n case 'compact':\n return 300;\n case 'wide':\n return 420;\n case 'extraWide':\n return 560;\n case 'default':\n default:\n return 360;\n }\n}\n\nfunction resolveModalWidth(size: ResponsivePanelSize | undefined): ZoraContentWidth | undefined {\n switch (size) {\n case 'compact':\n return 'narrow';\n case 'wide':\n case 'extraWide':\n return 'wide';\n case 'default':\n return 'default';\n default:\n return undefined;\n }\n}\n\nfunction renderPanelBody(children: React.ReactNode, scroll: ResponsivePanelScroll) {\n if (children == null) return null;\n\n if (scroll === 'content') {\n return (\n <ScrollView\n contentContainerStyle={styles.scrollContent}\n keyboardShouldPersistTaps=\"handled\"\n showsVerticalScrollIndicator\n style={styles.scrollBody}\n >\n {children}\n </ScrollView>\n );\n }\n\n return children;\n}\n\nfunction ResponsivePanelInner({\n themeId: _themeId,\n mode: _mode,\n title,\n description,\n actions,\n footer,\n children,\n open,\n onOpenChange,\n side = 'right',\n desktopMode = 'inline',\n mobileMode = 'drawer',\n compact = true,\n size,\n scroll = 'none',\n testID,\n}: ResponsivePanelProps) {\n if (!open) return null;\n\n const body = renderPanelBody(children, scroll);\n\n // For now, we assume desktopMode determines the rendering.\n // In a real app, this would react to window size.\n if (desktopMode === 'floating') {\n if (mobileMode === 'modal') {\n const modalWidth = resolveModalWidth(size);\n\n return (\n <Modal\n description={description}\n footer={footer}\n onDismiss={() => onOpenChange(false)}\n testID={testID}\n title={title}\n visible={open}\n width={modalWidth}\n >\n {body}\n </Modal>\n );\n }\n\n return (\n <Drawer\n description={description}\n footer={footer}\n onDismiss={() => onOpenChange(false)}\n position={side}\n testID={testID}\n title={title}\n visible={open}\n >\n {body}\n </Drawer>\n );\n }\n\n const panel = (\n <Panel\n actions={actions}\n compact={compact}\n description={description}\n footer={footer}\n testID={testID}\n title={title}\n >\n {body}\n </Panel>\n );\n\n if (size === undefined) return panel;\n\n return <View style={[styles.inlineSizedPanel, { width: resolvePanelWidth(size) }]}>{panel}</View>;\n}\n\nconst styles = StyleSheet.create({\n inlineSizedPanel: {\n maxWidth: '100%',\n },\n scrollBody: {\n flexGrow: 0,\n maxHeight: '100%',\n },\n scrollContent: {\n flexGrow: 1,\n },\n});\n\nexport const ResponsivePanel = withZoraThemeScope(ResponsivePanelInner);\n"]}
@@ -3,6 +3,8 @@ import type { ZoraBaseProps } from '../../theme/ZoraBaseProps';
3
3
  export type ResponsivePanelSide = 'left' | 'right';
4
4
  export type ResponsivePanelDesktopMode = 'inline' | 'floating';
5
5
  export type ResponsivePanelMobileMode = 'drawer' | 'modal';
6
+ export type ResponsivePanelSize = 'compact' | 'default' | 'wide' | 'extraWide';
7
+ export type ResponsivePanelScroll = 'none' | 'content';
6
8
  export interface ResponsivePanelProps extends ZoraBaseProps {
7
9
  title?: React.ReactNode;
8
10
  description?: React.ReactNode;
@@ -15,5 +17,7 @@ export interface ResponsivePanelProps extends ZoraBaseProps {
15
17
  desktopMode?: ResponsivePanelDesktopMode;
16
18
  mobileMode?: ResponsivePanelMobileMode;
17
19
  compact?: boolean;
20
+ size?: ResponsivePanelSize;
21
+ scroll?: ResponsivePanelScroll;
18
22
  }
19
23
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/patterns/responsive-panel/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAE/D,MAAM,MAAM,mBAAmB,GAAG,MAAM,GAAG,OAAO,CAAC;AACnD,MAAM,MAAM,0BAA0B,GAAG,QAAQ,GAAG,UAAU,CAAC;AAC/D,MAAM,MAAM,yBAAyB,GAAG,QAAQ,GAAG,OAAO,CAAC;AAE3D,MAAM,WAAW,oBAAqB,SAAQ,aAAa;IACzD,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC9B,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACtC,IAAI,CAAC,EAAE,mBAAmB,CAAC;IAC3B,WAAW,CAAC,EAAE,0BAA0B,CAAC;IACzC,UAAU,CAAC,EAAE,yBAAyB,CAAC;IACvC,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/patterns/responsive-panel/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAE/D,MAAM,MAAM,mBAAmB,GAAG,MAAM,GAAG,OAAO,CAAC;AACnD,MAAM,MAAM,0BAA0B,GAAG,QAAQ,GAAG,UAAU,CAAC;AAC/D,MAAM,MAAM,yBAAyB,GAAG,QAAQ,GAAG,OAAO,CAAC;AAC3D,MAAM,MAAM,mBAAmB,GAAG,SAAS,GAAG,SAAS,GAAG,MAAM,GAAG,WAAW,CAAC;AAC/E,MAAM,MAAM,qBAAqB,GAAG,MAAM,GAAG,SAAS,CAAC;AAEvD,MAAM,WAAW,oBAAqB,SAAQ,aAAa;IACzD,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC9B,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACtC,IAAI,CAAC,EAAE,mBAAmB,CAAC;IAC3B,WAAW,CAAC,EAAE,0BAA0B,CAAC;IACzC,UAAU,CAAC,EAAE,yBAAyB,CAAC;IACvC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,IAAI,CAAC,EAAE,mBAAmB,CAAC;IAC3B,MAAM,CAAC,EAAE,qBAAqB,CAAC;CAChC"}
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/patterns/responsive-panel/types.ts"],"names":[],"mappings":"","sourcesContent":["import type React from 'react';\n\nimport type { ZoraBaseProps } from '../../theme/ZoraBaseProps';\n\nexport type ResponsivePanelSide = 'left' | 'right';\nexport type ResponsivePanelDesktopMode = 'inline' | 'floating';\nexport type ResponsivePanelMobileMode = 'drawer' | 'modal';\n\nexport interface ResponsivePanelProps extends ZoraBaseProps {\n title?: React.ReactNode;\n description?: React.ReactNode;\n actions?: React.ReactNode;\n footer?: React.ReactNode;\n children?: React.ReactNode;\n open: boolean;\n onOpenChange: (open: boolean) => void;\n side?: ResponsivePanelSide;\n desktopMode?: ResponsivePanelDesktopMode;\n mobileMode?: ResponsivePanelMobileMode;\n compact?: boolean;\n}\n"]}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/patterns/responsive-panel/types.ts"],"names":[],"mappings":"","sourcesContent":["import type React from 'react';\n\nimport type { ZoraBaseProps } from '../../theme/ZoraBaseProps';\n\nexport type ResponsivePanelSide = 'left' | 'right';\nexport type ResponsivePanelDesktopMode = 'inline' | 'floating';\nexport type ResponsivePanelMobileMode = 'drawer' | 'modal';\nexport type ResponsivePanelSize = 'compact' | 'default' | 'wide' | 'extraWide';\nexport type ResponsivePanelScroll = 'none' | 'content';\n\nexport interface ResponsivePanelProps extends ZoraBaseProps {\n title?: React.ReactNode;\n description?: React.ReactNode;\n actions?: React.ReactNode;\n footer?: React.ReactNode;\n children?: React.ReactNode;\n open: boolean;\n onOpenChange: (open: boolean) => void;\n side?: ResponsivePanelSide;\n desktopMode?: ResponsivePanelDesktopMode;\n mobileMode?: ResponsivePanelMobileMode;\n compact?: boolean;\n size?: ResponsivePanelSize;\n scroll?: ResponsivePanelScroll;\n}\n"]}
@@ -1,7 +1,7 @@
1
1
  export declare function useZoraTheme(): {
2
2
  theme: import("@ankhorage/surface").SurfaceTheme;
3
3
  mode: "light" | "dark";
4
- setThemeConfig: (config: Partial<import("@ankhorage/contracts").ThemeConfig>) => void;
4
+ setThemeConfig: (config: Partial<import("@ankhorage/surface").ThemeConfig>) => void;
5
5
  setMode: (mode: "light" | "dark") => void;
6
6
  _hasProvider?: boolean;
7
7
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@ankhorage/zora",
3
3
  "type": "module",
4
- "version": "2.4.8",
4
+ "version": "2.5.1",
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": {
@@ -44,7 +44,7 @@
44
44
  },
45
45
  "dependencies": {
46
46
  "@ankhorage/color-theory": "^0.0.7",
47
- "@ankhorage/contracts": "^1.7.0",
47
+ "@ankhorage/contracts": "^1.12.0",
48
48
  "@ankhorage/surface": "^2.0.2"
49
49
  },
50
50
  "files": [
@@ -63,6 +63,13 @@
63
63
  "import": "./dist/index.js",
64
64
  "default": "./dist/index.js"
65
65
  },
66
+ "./metadata": {
67
+ "react-native": "./src/metadata/index.ts",
68
+ "browser": "./src/metadata/index.ts",
69
+ "types": "./dist/metadata/index.d.ts",
70
+ "import": "./dist/metadata/index.js",
71
+ "default": "./dist/metadata/index.js"
72
+ },
66
73
  "./package.json": "./package.json"
67
74
  },
68
75
  "publishConfig": {
package/src/index.ts CHANGED
@@ -194,6 +194,7 @@ export { SidebarLayout } from './layout/sidebar-layout';
194
194
  export type { TopbarLayoutProps } from './layout/topbar-layout';
195
195
  export { TopbarLayout } from './layout/topbar-layout';
196
196
  export type {
197
+ ZoraBindableComponentType,
197
198
  ZoraComponentBlueprint,
198
199
  ZoraComponentCategory,
199
200
  ZoraComponentEventMeta,
@@ -209,7 +210,7 @@ export type {
209
210
  ZoraComponentPropValue,
210
211
  ZoraComponentSlotMeta,
211
212
  } from './metadata';
212
- export { ZORA_COMPONENT_META } from './metadata';
213
+ export { ZORA_BINDABLE_COMPONENT_META, ZORA_COMPONENT_META } from './metadata';
213
214
  export type {
214
215
  AuthFormBaseProps,
215
216
  AuthIdentifierKind,
@@ -287,7 +288,9 @@ export type {
287
288
  ResponsivePanelDesktopMode,
288
289
  ResponsivePanelMobileMode,
289
290
  ResponsivePanelProps,
291
+ ResponsivePanelScroll,
290
292
  ResponsivePanelSide,
293
+ ResponsivePanelSize,
291
294
  } from './patterns/responsive-panel';
292
295
  export { ResponsivePanel } from './patterns/responsive-panel';
293
296
  export type { SectionHeaderProps } from './patterns/section-header';
@@ -0,0 +1,18 @@
1
+ import type { UiComponentMetaRegistry } from '@ankhorage/contracts';
2
+ import { describe, expect, it } from 'bun:test';
3
+
4
+ import { ZORA_BINDABLE_COMPONENT_META } from './bindableComponentMeta';
5
+
6
+ describe('ZORA bindable component metadata', () => {
7
+ it('matches the shared UI metadata registry shape', () => {
8
+ const registry: UiComponentMetaRegistry = ZORA_BINDABLE_COMPONENT_META;
9
+
10
+ expect(registry.Text?.bindings?.props?.text?.value.type).toBe('string');
11
+ expect(registry.Heading?.bindings?.props?.text?.value.type).toBe('string');
12
+ expect(registry.Button?.bindings?.props?.children?.value.type).toBe('string');
13
+ expect(registry.Input?.bindings?.props?.value?.value.type).toBe('string');
14
+ expect(registry.Select?.bindings?.props?.value?.value.type).toBe('string');
15
+ expect(registry.Image?.bindings?.props?.source?.value.type).toBe('imageAsset');
16
+ expect(registry.DataTable?.bindings?.props?.rows?.value.type).toBe('array');
17
+ });
18
+ });
@@ -0,0 +1,476 @@
1
+ import type { UiComponentMetaRegistry } from '@ankhorage/contracts';
2
+
3
+ export const ZORA_BINDABLE_COMPONENT_META = {
4
+ Text: {
5
+ name: 'Text',
6
+ category: 'component',
7
+ description: 'Displays app-facing text content.',
8
+ directManifestNode: true,
9
+ allowedChildren: [],
10
+ bindings: {
11
+ props: {
12
+ text: {
13
+ label: 'Text',
14
+ description: 'Text content rendered by the component.',
15
+ value: { type: 'string' },
16
+ acceptsFallback: true,
17
+ acceptsTransforms: true,
18
+ },
19
+ },
20
+ },
21
+ props: {
22
+ text: {
23
+ type: 'string',
24
+ category: 'Content',
25
+ label: 'Text',
26
+ },
27
+ },
28
+ },
29
+ Heading: {
30
+ name: 'Heading',
31
+ category: 'component',
32
+ description: 'Displays semantic heading text.',
33
+ directManifestNode: true,
34
+ allowedChildren: [],
35
+ bindings: {
36
+ props: {
37
+ text: {
38
+ label: 'Text',
39
+ description: 'Heading text rendered by the component.',
40
+ value: { type: 'string' },
41
+ acceptsFallback: true,
42
+ acceptsTransforms: true,
43
+ },
44
+ },
45
+ },
46
+ props: {
47
+ text: {
48
+ type: 'string',
49
+ category: 'Content',
50
+ label: 'Text',
51
+ },
52
+ },
53
+ },
54
+ Button: {
55
+ name: 'Button',
56
+ category: 'component',
57
+ description: 'Runs an action when pressed.',
58
+ directManifestNode: true,
59
+ allowedChildren: [],
60
+ bindings: {
61
+ props: {
62
+ children: {
63
+ label: 'Label',
64
+ description: 'Button label text.',
65
+ value: { type: 'string' },
66
+ acceptsFallback: true,
67
+ acceptsTransforms: true,
68
+ },
69
+ disabled: {
70
+ label: 'Disabled',
71
+ description: 'Whether the button is disabled.',
72
+ value: { type: 'boolean' },
73
+ acceptsFallback: true,
74
+ acceptsTransforms: true,
75
+ },
76
+ },
77
+ events: {
78
+ press: {
79
+ label: 'Press',
80
+ description: 'Runs when the button is pressed.',
81
+ payload: {
82
+ eventType: 'button.press',
83
+ fields: [],
84
+ },
85
+ },
86
+ },
87
+ },
88
+ events: {
89
+ press: {
90
+ label: 'Press',
91
+ eventType: 'button.press',
92
+ description: 'Emitted when the button action runs.',
93
+ payloadFields: [],
94
+ },
95
+ },
96
+ props: {
97
+ children: {
98
+ type: 'string',
99
+ category: 'Content',
100
+ label: 'Label',
101
+ },
102
+ disabled: {
103
+ type: 'boolean',
104
+ category: 'State',
105
+ label: 'Disabled',
106
+ },
107
+ },
108
+ },
109
+ Image: {
110
+ name: 'Image',
111
+ category: 'component',
112
+ description: 'Displays an image asset or remote image source.',
113
+ directManifestNode: true,
114
+ allowedChildren: [],
115
+ bindings: {
116
+ props: {
117
+ source: {
118
+ label: 'Source',
119
+ description: 'Image source or asset descriptor.',
120
+ value: {
121
+ type: 'imageAsset',
122
+ fields: [
123
+ { path: 'uri', type: 'string', label: 'URI' },
124
+ { path: 'width', type: 'number', label: 'Width' },
125
+ { path: 'height', type: 'number', label: 'Height' },
126
+ { path: 'alt', type: 'string', label: 'Alt text' },
127
+ ],
128
+ },
129
+ acceptsFallback: true,
130
+ acceptsTransforms: true,
131
+ },
132
+ },
133
+ },
134
+ props: {
135
+ source: {
136
+ type: 'imageAsset',
137
+ category: 'Content',
138
+ label: 'Source',
139
+ },
140
+ },
141
+ },
142
+ Input: {
143
+ name: 'Input',
144
+ category: 'component',
145
+ description: 'Captures a single-line string value.',
146
+ directManifestNode: true,
147
+ allowedChildren: [],
148
+ bindings: {
149
+ props: {
150
+ value: {
151
+ label: 'Value',
152
+ description: 'Current input value.',
153
+ value: { type: 'string' },
154
+ acceptsFallback: true,
155
+ acceptsTransforms: true,
156
+ },
157
+ disabled: {
158
+ label: 'Disabled',
159
+ description: 'Whether the input is disabled.',
160
+ value: { type: 'boolean' },
161
+ acceptsFallback: true,
162
+ acceptsTransforms: true,
163
+ },
164
+ },
165
+ events: {
166
+ changeText: {
167
+ label: 'Change text',
168
+ description: 'Runs when the input value changes.',
169
+ payload: {
170
+ eventType: 'input.changeText',
171
+ fields: [{ path: 'value', type: 'string', label: 'Value' }],
172
+ },
173
+ },
174
+ },
175
+ },
176
+ events: {
177
+ changeText: {
178
+ label: 'Change text',
179
+ eventType: 'input.changeText',
180
+ description: 'Emitted when the input value changes.',
181
+ payloadFields: [{ path: 'value', type: 'string', label: 'Value' }],
182
+ },
183
+ },
184
+ props: {
185
+ value: {
186
+ type: 'string',
187
+ category: 'Content',
188
+ label: 'Value',
189
+ },
190
+ disabled: {
191
+ type: 'boolean',
192
+ category: 'State',
193
+ label: 'Disabled',
194
+ },
195
+ },
196
+ },
197
+ Textarea: {
198
+ name: 'Textarea',
199
+ category: 'component',
200
+ description: 'Captures a multiline string value.',
201
+ directManifestNode: true,
202
+ allowedChildren: [],
203
+ bindings: {
204
+ props: {
205
+ value: {
206
+ label: 'Value',
207
+ description: 'Current textarea value.',
208
+ value: { type: 'string' },
209
+ acceptsFallback: true,
210
+ acceptsTransforms: true,
211
+ },
212
+ disabled: {
213
+ label: 'Disabled',
214
+ description: 'Whether the textarea is disabled.',
215
+ value: { type: 'boolean' },
216
+ acceptsFallback: true,
217
+ acceptsTransforms: true,
218
+ },
219
+ },
220
+ events: {
221
+ changeText: {
222
+ label: 'Change text',
223
+ description: 'Runs when the textarea value changes.',
224
+ payload: {
225
+ eventType: 'textarea.changeText',
226
+ fields: [{ path: 'value', type: 'string', label: 'Value' }],
227
+ },
228
+ },
229
+ },
230
+ },
231
+ events: {
232
+ changeText: {
233
+ label: 'Change text',
234
+ eventType: 'textarea.changeText',
235
+ description: 'Emitted when the textarea value changes.',
236
+ payloadFields: [{ path: 'value', type: 'string', label: 'Value' }],
237
+ },
238
+ },
239
+ props: {
240
+ value: {
241
+ type: 'string',
242
+ category: 'Content',
243
+ label: 'Value',
244
+ },
245
+ disabled: {
246
+ type: 'boolean',
247
+ category: 'State',
248
+ label: 'Disabled',
249
+ },
250
+ },
251
+ },
252
+ Select: {
253
+ name: 'Select',
254
+ category: 'component',
255
+ description: 'Captures one selected string value.',
256
+ directManifestNode: false,
257
+ allowedChildren: [],
258
+ bindings: {
259
+ props: {
260
+ value: {
261
+ label: 'Value',
262
+ description: 'Current selected value.',
263
+ value: { type: 'string' },
264
+ acceptsFallback: true,
265
+ acceptsTransforms: true,
266
+ },
267
+ disabled: {
268
+ label: 'Disabled',
269
+ description: 'Whether the select is disabled.',
270
+ value: { type: 'boolean' },
271
+ acceptsFallback: true,
272
+ acceptsTransforms: true,
273
+ },
274
+ },
275
+ events: {
276
+ valueChange: {
277
+ label: 'Value change',
278
+ description: 'Runs when the selected value changes.',
279
+ payload: {
280
+ eventType: 'select.valueChange',
281
+ fields: [{ path: 'value', type: 'string', label: 'Value' }],
282
+ },
283
+ },
284
+ },
285
+ },
286
+ events: {
287
+ valueChange: {
288
+ label: 'Value change',
289
+ eventType: 'select.valueChange',
290
+ description: 'Emitted when the selected value changes.',
291
+ payloadFields: [{ path: 'value', type: 'string', label: 'Value' }],
292
+ },
293
+ },
294
+ note: 'Form control component; not represented as a manifest node in v1.',
295
+ props: {
296
+ value: {
297
+ type: 'string',
298
+ category: 'Content',
299
+ label: 'Value',
300
+ },
301
+ disabled: {
302
+ type: 'boolean',
303
+ category: 'State',
304
+ label: 'Disabled',
305
+ },
306
+ },
307
+ },
308
+ Checkbox: {
309
+ name: 'Checkbox',
310
+ category: 'component',
311
+ description: 'Captures a boolean checked state.',
312
+ directManifestNode: true,
313
+ allowedChildren: [],
314
+ bindings: {
315
+ props: {
316
+ checked: {
317
+ label: 'Checked',
318
+ description: 'Current checked state.',
319
+ value: { type: 'boolean' },
320
+ acceptsFallback: true,
321
+ acceptsTransforms: true,
322
+ },
323
+ disabled: {
324
+ label: 'Disabled',
325
+ description: 'Whether the checkbox is disabled.',
326
+ value: { type: 'boolean' },
327
+ acceptsFallback: true,
328
+ acceptsTransforms: true,
329
+ },
330
+ },
331
+ events: {
332
+ checkedChange: {
333
+ label: 'Checked change',
334
+ description: 'Runs when checked state changes.',
335
+ payload: {
336
+ eventType: 'checkbox.checkedChange',
337
+ fields: [{ path: 'checked', type: 'boolean', label: 'Checked' }],
338
+ },
339
+ },
340
+ },
341
+ },
342
+ events: {
343
+ checkedChange: {
344
+ label: 'Checked change',
345
+ eventType: 'checkbox.checkedChange',
346
+ description: 'Emitted when the checked state changes.',
347
+ payloadFields: [{ path: 'checked', type: 'boolean', label: 'Checked' }],
348
+ },
349
+ },
350
+ props: {
351
+ checked: {
352
+ type: 'boolean',
353
+ category: 'State',
354
+ label: 'Checked',
355
+ },
356
+ disabled: {
357
+ type: 'boolean',
358
+ category: 'State',
359
+ label: 'Disabled',
360
+ },
361
+ },
362
+ },
363
+ SwitchField: {
364
+ name: 'SwitchField',
365
+ category: 'pattern',
366
+ description: 'Captures a boolean switch value with a label.',
367
+ directManifestNode: true,
368
+ allowedChildren: [],
369
+ bindings: {
370
+ props: {
371
+ value: {
372
+ label: 'Value',
373
+ description: 'Current switch value.',
374
+ value: { type: 'boolean' },
375
+ acceptsFallback: true,
376
+ acceptsTransforms: true,
377
+ },
378
+ disabled: {
379
+ label: 'Disabled',
380
+ description: 'Whether the switch is disabled.',
381
+ value: { type: 'boolean' },
382
+ acceptsFallback: true,
383
+ acceptsTransforms: true,
384
+ },
385
+ },
386
+ events: {
387
+ valueChange: {
388
+ label: 'Value change',
389
+ description: 'Runs when the switch value changes.',
390
+ payload: {
391
+ eventType: 'switchField.valueChange',
392
+ fields: [{ path: 'value', type: 'boolean', label: 'Value' }],
393
+ },
394
+ },
395
+ },
396
+ },
397
+ events: {
398
+ valueChange: {
399
+ label: 'Value change',
400
+ eventType: 'switchField.valueChange',
401
+ description: 'Emitted when the switch value changes.',
402
+ payloadFields: [{ path: 'value', type: 'boolean', label: 'Value' }],
403
+ },
404
+ },
405
+ props: {
406
+ value: {
407
+ type: 'boolean',
408
+ category: 'State',
409
+ label: 'Value',
410
+ },
411
+ disabled: {
412
+ type: 'boolean',
413
+ category: 'State',
414
+ label: 'Disabled',
415
+ },
416
+ },
417
+ },
418
+ List: {
419
+ name: 'List',
420
+ category: 'pattern',
421
+ description: 'Renders a collection of list items.',
422
+ directManifestNode: true,
423
+ allowedChildren: ['ListSection', 'ListRow'],
424
+ bindings: {
425
+ props: {
426
+ items: {
427
+ label: 'Items',
428
+ description: 'Collection rendered by the list.',
429
+ value: {
430
+ type: 'array',
431
+ itemType: 'object',
432
+ },
433
+ acceptsFallback: true,
434
+ acceptsTransforms: true,
435
+ },
436
+ },
437
+ },
438
+ props: {
439
+ items: {
440
+ type: 'array',
441
+ category: 'Data',
442
+ label: 'Items',
443
+ },
444
+ },
445
+ },
446
+ DataTable: {
447
+ name: 'DataTable',
448
+ category: 'component',
449
+ description: 'Renders tabular records.',
450
+ directManifestNode: true,
451
+ allowedChildren: [],
452
+ bindings: {
453
+ props: {
454
+ rows: {
455
+ label: 'Rows',
456
+ description: 'Rows rendered by the table.',
457
+ value: {
458
+ type: 'array',
459
+ itemType: 'record',
460
+ },
461
+ acceptsFallback: true,
462
+ acceptsTransforms: true,
463
+ },
464
+ },
465
+ },
466
+ props: {
467
+ rows: {
468
+ type: 'array',
469
+ category: 'Data',
470
+ label: 'Rows',
471
+ },
472
+ },
473
+ },
474
+ } as const satisfies UiComponentMetaRegistry;
475
+
476
+ export type ZoraBindableComponentType = keyof typeof ZORA_BINDABLE_COMPONENT_META;
@@ -1,3 +1,5 @@
1
+ export type { ZoraBindableComponentType } from './bindableComponentMeta';
2
+ export { ZORA_BINDABLE_COMPONENT_META } from './bindableComponentMeta';
1
3
  export { ZORA_COMPONENT_META } from './componentMeta';
2
4
  export type {
3
5
  ZoraComponentBlueprint,