@ankhorage/zora 2.7.1 → 2.7.3

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 CHANGED
@@ -1,5 +1,17 @@
1
1
  # Changelog
2
2
 
3
+ ## 2.7.3
4
+
5
+ ### Patch Changes
6
+
7
+ - 3155142: Update CONTRACTS
8
+
9
+ ## 2.7.2
10
+
11
+ ### Patch Changes
12
+
13
+ - d84eb54: Fix `DisclosureSection` header interaction and long-description layout so the main header area toggles open/closed, long text wraps, and the trailing chevron remains visible.
14
+
3
15
  ## 2.7.1
4
16
 
5
17
  ### Patch Changes
package/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
 
4
4
  # ZORA
5
5
 
6
- ![license: MIT](././paradox/badges/license.svg) ![npm: v2.7.0](././paradox/badges/npm.svg) ![runtime: bun](././paradox/badges/runtime.svg) ![typescript: strict](././paradox/badges/typescript.svg) ![eslint: checked](././paradox/badges/eslint.svg) ![prettier: checked](././paradox/badges/prettier.svg) ![build: checked](././paradox/badges/build.svg) ![tests: checked](././paradox/badges/tests.svg) ![docs: paradox](././paradox/badges/docs.svg)
6
+ ![license: MIT](././paradox/badges/license.svg) ![npm: v2.7.2](././paradox/badges/npm.svg) ![runtime: bun](././paradox/badges/runtime.svg) ![typescript: strict](././paradox/badges/typescript.svg) ![eslint: checked](././paradox/badges/eslint.svg) ![prettier: checked](././paradox/badges/prettier.svg) ![build: checked](././paradox/badges/build.svg) ![tests: checked](././paradox/badges/tests.svg) ![docs: paradox](././paradox/badges/docs.svg)
7
7
 
8
8
  Opinionated React Native and React Native Web UI kit built on @ankhorage/surface.
9
9
 
@@ -3,7 +3,7 @@ import type { DisclosureSectionProps } from './types';
3
3
  /***
4
4
  * Expandable section pattern with a summary header and collapsible content.
5
5
  *
6
-
6
+
7
7
  */
8
8
  export declare const DisclosureSection: (props: DisclosureSectionProps) => React.ReactElement | null;
9
9
  //# sourceMappingURL=DisclosureSection.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"DisclosureSection.d.ts","sourceRoot":"","sources":["../../../src/patterns/disclosure-section/DisclosureSection.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAM1B,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAC;AA2DtD;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,8DAA6C,CAAC"}
1
+ {"version":3,"file":"DisclosureSection.d.ts","sourceRoot":"","sources":["../../../src/patterns/disclosure-section/DisclosureSection.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAS1B,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAC;AAsGtD;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,8DAA6C,CAAC"}
@@ -1,12 +1,35 @@
1
1
  import React from 'react';
2
+ import { Platform, Pressable } from 'react-native';
3
+ import { Heading } from '../../components/heading';
2
4
  import { IconButton } from '../../components/icon-button';
5
+ import { Text } from '../../components/text';
3
6
  import { Box, Stack } from '../../foundation';
4
7
  import { withZoraThemeScope } from '../../theme/withZoraThemeScope';
5
8
  import { Panel } from '../panel';
9
+ const triggerTextStyle = {
10
+ flex: 1,
11
+ minWidth: 0,
12
+ };
13
+ const trailingStyle = {
14
+ flexShrink: 0,
15
+ };
16
+ const getTriggerStyle = (disabled) => ({
17
+ alignSelf: 'stretch',
18
+ flex: 1,
19
+ justifyContent: 'center',
20
+ minWidth: 0,
21
+ ...(Platform.OS === 'web'
22
+ ? {
23
+ cursor: disabled ? 'default' : 'pointer',
24
+ }
25
+ : null),
26
+ });
6
27
  function DisclosureSectionInner({ themeId: _themeId, mode: _mode, title, description, icon, defaultOpen = true, open: controlledOpen, onOpenChange, actions, children, disabled, testID, }) {
7
28
  const [internalOpen, setInternalOpen] = React.useState(defaultOpen);
8
29
  const isControlled = controlledOpen !== undefined;
9
30
  const isOpen = isControlled ? controlledOpen : internalOpen;
31
+ const titleLabel = typeof title === 'string' || typeof title === 'number' ? `: ${title}` : '';
32
+ const toggleLabel = `${isOpen ? 'Collapse' : 'Expand'} section${titleLabel}`;
10
33
  const toggleOpen = () => {
11
34
  if (disabled)
12
35
  return;
@@ -18,17 +41,36 @@ function DisclosureSectionInner({ themeId: _themeId, mode: _mode, title, descrip
18
41
  onOpenChange?.(!internalOpen);
19
42
  }
20
43
  };
21
- return (<Panel compact description={description} testID={testID} title={title} eyebrow={icon ? <Box pb="xs">{/* Surface icon spec would go here */}</Box> : null} actions={<Stack direction="row" gap="xs" align="center">
22
- {actions}
23
- <IconButton icon={{ name: isOpen ? 'chevron-up-outline' : 'chevron-down-outline' }} label={isOpen ? 'Collapse' : 'Expand'} variant="ghost" color="neutral" size="s" disabled={disabled} onPress={toggleOpen}/>
24
- </Stack>}>
25
- {isOpen ? <Box pt="m">{children}</Box> : null}
44
+ return (<Panel compact testID={testID}>
45
+ <Stack gap="s">
46
+ <Stack direction="row" gap="m" align="center">
47
+ <Pressable accessibilityLabel={toggleLabel} accessibilityRole="button" accessibilityState={{ disabled, expanded: isOpen }} disabled={disabled} onPress={toggleOpen} style={getTriggerStyle(disabled)}>
48
+ <Box style={triggerTextStyle}>
49
+ <Stack gap="xs">
50
+ {icon ? <Box pb="xs">{/* Surface icon spec would go here */}</Box> : null}
51
+ <Heading level={4}>{title}</Heading>
52
+ {description ? (<Text emphasis="muted" variant="bodySmall">
53
+ {description}
54
+ </Text>) : null}
55
+ </Stack>
56
+ </Box>
57
+ </Pressable>
58
+
59
+ {actions ? <Box style={trailingStyle}>{actions}</Box> : null}
60
+
61
+ <Box style={trailingStyle}>
62
+ <IconButton icon={{ name: isOpen ? 'chevron-up-outline' : 'chevron-down-outline' }} label={isOpen ? 'Collapse' : 'Expand'} variant="ghost" color="neutral" size="s" disabled={disabled} onPress={toggleOpen}/>
63
+ </Box>
64
+ </Stack>
65
+
66
+ {isOpen ? <Box pt="m">{children}</Box> : null}
67
+ </Stack>
26
68
  </Panel>);
27
69
  }
28
70
  /***
29
71
  * Expandable section pattern with a summary header and collapsible content.
30
72
  *
31
-
73
+
32
74
  */
33
75
  export const DisclosureSection = withZoraThemeScope(DisclosureSectionInner);
34
76
  //# sourceMappingURL=DisclosureSection.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"DisclosureSection.js","sourceRoot":"","sources":["../../../src/patterns/disclosure-section/DisclosureSection.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAC1D,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AACpE,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAGjC,SAAS,sBAAsB,CAAC,EAC9B,OAAO,EAAE,QAAQ,EACjB,IAAI,EAAE,KAAK,EACX,KAAK,EACL,WAAW,EACX,IAAI,EACJ,WAAW,GAAG,IAAI,EAClB,IAAI,EAAE,cAAc,EACpB,YAAY,EACZ,OAAO,EACP,QAAQ,EACR,QAAQ,EACR,MAAM,GACiB;IACvB,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;IAEpE,MAAM,YAAY,GAAG,cAAc,KAAK,SAAS,CAAC;IAClD,MAAM,MAAM,GAAG,YAAY,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,YAAY,CAAC;IAE5D,MAAM,UAAU,GAAG,GAAG,EAAE;QACtB,IAAI,QAAQ;YAAE,OAAO;QAErB,IAAI,YAAY,EAAE,CAAC;YACjB,YAAY,EAAE,CAAC,CAAC,cAAc,CAAC,CAAC;QAClC,CAAC;aAAM,CAAC;YACN,eAAe,CAAC,CAAC,YAAY,CAAC,CAAC;YAC/B,YAAY,EAAE,CAAC,CAAC,YAAY,CAAC,CAAC;QAChC,CAAC;IACH,CAAC,CAAC;IAEF,OAAO,CACL,CAAC,KAAK,CACJ,OAAO,CACP,WAAW,CAAC,CAAC,WAAW,CAAC,CACzB,MAAM,CAAC,CAAC,MAAM,CAAC,CACf,KAAK,CAAC,CAAC,KAAK,CAAC,CACb,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,qCAAqC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAClF,OAAO,CAAC,CACN,CAAC,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAC5C;UAAA,CAAC,OAAO,CACR;UAAA,CAAC,UAAU,CACT,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,sBAAsB,EAAE,CAAC,CACvE,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CACtC,OAAO,CAAC,OAAO,CACf,KAAK,CAAC,SAAS,CACf,IAAI,CAAC,GAAG,CACR,QAAQ,CAAC,CAAC,QAAQ,CAAC,CACnB,OAAO,CAAC,CAAC,UAAU,CAAC,EAExB;QAAA,EAAE,KAAK,CACT,CAAC,CAED;MAAA,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAC/C;IAAA,EAAE,KAAK,CAAC,CACT,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,kBAAkB,CAAC,sBAAsB,CAAC,CAAC","sourcesContent":["import React from 'react';\n\nimport { IconButton } from '../../components/icon-button';\nimport { Box, Stack } from '../../foundation';\nimport { withZoraThemeScope } from '../../theme/withZoraThemeScope';\nimport { Panel } from '../panel';\nimport type { DisclosureSectionProps } from './types';\n\nfunction DisclosureSectionInner({\n themeId: _themeId,\n mode: _mode,\n title,\n description,\n icon,\n defaultOpen = true,\n open: controlledOpen,\n onOpenChange,\n actions,\n children,\n disabled,\n testID,\n}: DisclosureSectionProps) {\n const [internalOpen, setInternalOpen] = React.useState(defaultOpen);\n\n const isControlled = controlledOpen !== undefined;\n const isOpen = isControlled ? controlledOpen : internalOpen;\n\n const toggleOpen = () => {\n if (disabled) return;\n\n if (isControlled) {\n onOpenChange?.(!controlledOpen);\n } else {\n setInternalOpen(!internalOpen);\n onOpenChange?.(!internalOpen);\n }\n };\n\n return (\n <Panel\n compact\n description={description}\n testID={testID}\n title={title}\n eyebrow={icon ? <Box pb=\"xs\">{/* Surface icon spec would go here */}</Box> : null}\n actions={\n <Stack direction=\"row\" gap=\"xs\" align=\"center\">\n {actions}\n <IconButton\n icon={{ name: isOpen ? 'chevron-up-outline' : 'chevron-down-outline' }}\n label={isOpen ? 'Collapse' : 'Expand'}\n variant=\"ghost\"\n color=\"neutral\"\n size=\"s\"\n disabled={disabled}\n onPress={toggleOpen}\n />\n </Stack>\n }\n >\n {isOpen ? <Box pt=\"m\">{children}</Box> : null}\n </Panel>\n );\n}\n\n/***\n * Expandable section pattern with a summary header and collapsible content.\n *\n \n */\nexport const DisclosureSection = withZoraThemeScope(DisclosureSectionInner);\n"]}
1
+ {"version":3,"file":"DisclosureSection.js","sourceRoot":"","sources":["../../../src/patterns/disclosure-section/DisclosureSection.tsx"],"names":[],"mappings":"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","sourcesContent":["import React from 'react';\nimport { Platform, Pressable, type ViewStyle } from 'react-native';\n\nimport { Heading } from '../../components/heading';\nimport { IconButton } from '../../components/icon-button';\nimport { Text } from '../../components/text';\nimport { Box, Stack } from '../../foundation';\nimport { withZoraThemeScope } from '../../theme/withZoraThemeScope';\nimport { Panel } from '../panel';\nimport type { DisclosureSectionProps } from './types';\n\nconst triggerTextStyle: ViewStyle = {\n flex: 1,\n minWidth: 0,\n};\n\nconst trailingStyle: ViewStyle = {\n flexShrink: 0,\n};\n\nconst getTriggerStyle = (disabled?: boolean): ViewStyle =>\n ({\n alignSelf: 'stretch',\n flex: 1,\n justifyContent: 'center',\n minWidth: 0,\n ...(Platform.OS === 'web'\n ? {\n cursor: disabled ? 'default' : 'pointer',\n }\n : null),\n }) as ViewStyle;\n\nfunction DisclosureSectionInner({\n themeId: _themeId,\n mode: _mode,\n title,\n description,\n icon,\n defaultOpen = true,\n open: controlledOpen,\n onOpenChange,\n actions,\n children,\n disabled,\n testID,\n}: DisclosureSectionProps) {\n const [internalOpen, setInternalOpen] = React.useState(defaultOpen);\n\n const isControlled = controlledOpen !== undefined;\n const isOpen = isControlled ? controlledOpen : internalOpen;\n const titleLabel = typeof title === 'string' || typeof title === 'number' ? `: ${title}` : '';\n const toggleLabel = `${isOpen ? 'Collapse' : 'Expand'} section${titleLabel}`;\n\n const toggleOpen = () => {\n if (disabled) return;\n\n if (isControlled) {\n onOpenChange?.(!controlledOpen);\n } else {\n setInternalOpen(!internalOpen);\n onOpenChange?.(!internalOpen);\n }\n };\n\n return (\n <Panel compact testID={testID}>\n <Stack gap=\"s\">\n <Stack direction=\"row\" gap=\"m\" align=\"center\">\n <Pressable\n accessibilityLabel={toggleLabel}\n accessibilityRole=\"button\"\n accessibilityState={{ disabled, expanded: isOpen }}\n disabled={disabled}\n onPress={toggleOpen}\n style={getTriggerStyle(disabled)}\n >\n <Box style={triggerTextStyle}>\n <Stack gap=\"xs\">\n {icon ? <Box pb=\"xs\">{/* Surface icon spec would go here */}</Box> : null}\n <Heading level={4}>{title}</Heading>\n {description ? (\n <Text emphasis=\"muted\" variant=\"bodySmall\">\n {description}\n </Text>\n ) : null}\n </Stack>\n </Box>\n </Pressable>\n\n {actions ? <Box style={trailingStyle}>{actions}</Box> : null}\n\n <Box style={trailingStyle}>\n <IconButton\n icon={{ name: isOpen ? 'chevron-up-outline' : 'chevron-down-outline' }}\n label={isOpen ? 'Collapse' : 'Expand'}\n variant=\"ghost\"\n color=\"neutral\"\n size=\"s\"\n disabled={disabled}\n onPress={toggleOpen}\n />\n </Box>\n </Stack>\n\n {isOpen ? <Box pt=\"m\">{children}</Box> : null}\n </Stack>\n </Panel>\n );\n}\n\n/***\n * Expandable section pattern with a summary header and collapsible content.\n *\n\n */\nexport const DisclosureSection = withZoraThemeScope(DisclosureSectionInner);\n"]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@ankhorage/zora",
3
3
  "type": "module",
4
- "version": "2.7.1",
4
+ "version": "2.7.3",
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": {
@@ -48,7 +48,7 @@
48
48
  },
49
49
  "dependencies": {
50
50
  "@ankhorage/color-theory": "^0.0.7",
51
- "@ankhorage/contracts": "^1.17.0",
51
+ "@ankhorage/contracts": "^1.18.0",
52
52
  "@ankhorage/surface": "^2.0.2"
53
53
  },
54
54
  "files": [
@@ -1,11 +1,36 @@
1
1
  import React from 'react';
2
+ import { Platform, Pressable, type ViewStyle } from 'react-native';
2
3
 
4
+ import { Heading } from '../../components/heading';
3
5
  import { IconButton } from '../../components/icon-button';
6
+ import { Text } from '../../components/text';
4
7
  import { Box, Stack } from '../../foundation';
5
8
  import { withZoraThemeScope } from '../../theme/withZoraThemeScope';
6
9
  import { Panel } from '../panel';
7
10
  import type { DisclosureSectionProps } from './types';
8
11
 
12
+ const triggerTextStyle: ViewStyle = {
13
+ flex: 1,
14
+ minWidth: 0,
15
+ };
16
+
17
+ const trailingStyle: ViewStyle = {
18
+ flexShrink: 0,
19
+ };
20
+
21
+ const getTriggerStyle = (disabled?: boolean): ViewStyle =>
22
+ ({
23
+ alignSelf: 'stretch',
24
+ flex: 1,
25
+ justifyContent: 'center',
26
+ minWidth: 0,
27
+ ...(Platform.OS === 'web'
28
+ ? {
29
+ cursor: disabled ? 'default' : 'pointer',
30
+ }
31
+ : null),
32
+ }) as ViewStyle;
33
+
9
34
  function DisclosureSectionInner({
10
35
  themeId: _themeId,
11
36
  mode: _mode,
@@ -24,6 +49,8 @@ function DisclosureSectionInner({
24
49
 
25
50
  const isControlled = controlledOpen !== undefined;
26
51
  const isOpen = isControlled ? controlledOpen : internalOpen;
52
+ const titleLabel = typeof title === 'string' || typeof title === 'number' ? `: ${title}` : '';
53
+ const toggleLabel = `${isOpen ? 'Collapse' : 'Expand'} section${titleLabel}`;
27
54
 
28
55
  const toggleOpen = () => {
29
56
  if (disabled) return;
@@ -37,28 +64,47 @@ function DisclosureSectionInner({
37
64
  };
38
65
 
39
66
  return (
40
- <Panel
41
- compact
42
- description={description}
43
- testID={testID}
44
- title={title}
45
- eyebrow={icon ? <Box pb="xs">{/* Surface icon spec would go here */}</Box> : null}
46
- actions={
47
- <Stack direction="row" gap="xs" align="center">
48
- {actions}
49
- <IconButton
50
- icon={{ name: isOpen ? 'chevron-up-outline' : 'chevron-down-outline' }}
51
- label={isOpen ? 'Collapse' : 'Expand'}
52
- variant="ghost"
53
- color="neutral"
54
- size="s"
67
+ <Panel compact testID={testID}>
68
+ <Stack gap="s">
69
+ <Stack direction="row" gap="m" align="center">
70
+ <Pressable
71
+ accessibilityLabel={toggleLabel}
72
+ accessibilityRole="button"
73
+ accessibilityState={{ disabled, expanded: isOpen }}
55
74
  disabled={disabled}
56
75
  onPress={toggleOpen}
57
- />
76
+ style={getTriggerStyle(disabled)}
77
+ >
78
+ <Box style={triggerTextStyle}>
79
+ <Stack gap="xs">
80
+ {icon ? <Box pb="xs">{/* Surface icon spec would go here */}</Box> : null}
81
+ <Heading level={4}>{title}</Heading>
82
+ {description ? (
83
+ <Text emphasis="muted" variant="bodySmall">
84
+ {description}
85
+ </Text>
86
+ ) : null}
87
+ </Stack>
88
+ </Box>
89
+ </Pressable>
90
+
91
+ {actions ? <Box style={trailingStyle}>{actions}</Box> : null}
92
+
93
+ <Box style={trailingStyle}>
94
+ <IconButton
95
+ icon={{ name: isOpen ? 'chevron-up-outline' : 'chevron-down-outline' }}
96
+ label={isOpen ? 'Collapse' : 'Expand'}
97
+ variant="ghost"
98
+ color="neutral"
99
+ size="s"
100
+ disabled={disabled}
101
+ onPress={toggleOpen}
102
+ />
103
+ </Box>
58
104
  </Stack>
59
- }
60
- >
61
- {isOpen ? <Box pt="m">{children}</Box> : null}
105
+
106
+ {isOpen ? <Box pt="m">{children}</Box> : null}
107
+ </Stack>
62
108
  </Panel>
63
109
  );
64
110
  }
@@ -66,6 +112,6 @@ function DisclosureSectionInner({
66
112
  /***
67
113
  * Expandable section pattern with a summary header and collapsible content.
68
114
  *
69
-
115
+
70
116
  */
71
117
  export const DisclosureSection = withZoraThemeScope(DisclosureSectionInner);