@xyo-network/react-property 2.23.7
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/LICENSE +165 -0
- package/README.md +69 -0
- package/babel.config.json +5 -0
- package/dist/cjs/components/IdenticonCorner.d.ts +6 -0
- package/dist/cjs/components/IdenticonCorner.js +22 -0
- package/dist/cjs/components/IdenticonCorner.js.map +1 -0
- package/dist/cjs/components/Property.d.ts +3 -0
- package/dist/cjs/components/Property.js +33 -0
- package/dist/cjs/components/Property.js.map +1 -0
- package/dist/cjs/components/PropertyAction.d.ts +7 -0
- package/dist/cjs/components/PropertyAction.js +3 -0
- package/dist/cjs/components/PropertyAction.js.map +1 -0
- package/dist/cjs/components/PropertyActions.d.ts +3 -0
- package/dist/cjs/components/PropertyActions.js +19 -0
- package/dist/cjs/components/PropertyActions.js.map +1 -0
- package/dist/cjs/components/PropertyActionsMenu.d.ts +3 -0
- package/dist/cjs/components/PropertyActionsMenu.js +29 -0
- package/dist/cjs/components/PropertyActionsMenu.js.map +1 -0
- package/dist/cjs/components/PropertyActionsProps.d.ts +6 -0
- package/dist/cjs/components/PropertyActionsProps.js +3 -0
- package/dist/cjs/components/PropertyActionsProps.js.map +1 -0
- package/dist/cjs/components/PropertyProps.d.ts +13 -0
- package/dist/cjs/components/PropertyProps.js +3 -0
- package/dist/cjs/components/PropertyProps.js.map +1 -0
- package/dist/cjs/components/SizeProp.d.ts +1 -0
- package/dist/cjs/components/SizeProp.js +3 -0
- package/dist/cjs/components/SizeProp.js.map +1 -0
- package/dist/cjs/components/Title.d.ts +10 -0
- package/dist/cjs/components/Title.js +19 -0
- package/dist/cjs/components/Title.js.map +1 -0
- package/dist/cjs/components/Value.d.ts +10 -0
- package/dist/cjs/components/Value.js +42 -0
- package/dist/cjs/components/Value.js.map +1 -0
- package/dist/cjs/components/index.d.ts +6 -0
- package/dist/cjs/components/index.js +10 -0
- package/dist/cjs/components/index.js.map +1 -0
- package/dist/cjs/components/usePropertyHeroProps.d.ts +6 -0
- package/dist/cjs/components/usePropertyHeroProps.js +15 -0
- package/dist/cjs/components/usePropertyHeroProps.js.map +1 -0
- package/dist/cjs/index.d.ts +1 -0
- package/dist/cjs/index.js +5 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/docs.json +50403 -0
- package/dist/esm/components/IdenticonCorner.d.ts +6 -0
- package/dist/esm/components/IdenticonCorner.js +15 -0
- package/dist/esm/components/IdenticonCorner.js.map +1 -0
- package/dist/esm/components/Property.d.ts +3 -0
- package/dist/esm/components/Property.js +27 -0
- package/dist/esm/components/Property.js.map +1 -0
- package/dist/esm/components/PropertyAction.d.ts +7 -0
- package/dist/esm/components/PropertyAction.js +2 -0
- package/dist/esm/components/PropertyAction.js.map +1 -0
- package/dist/esm/components/PropertyActions.d.ts +3 -0
- package/dist/esm/components/PropertyActions.js +12 -0
- package/dist/esm/components/PropertyActions.js.map +1 -0
- package/dist/esm/components/PropertyActionsMenu.d.ts +3 -0
- package/dist/esm/components/PropertyActionsMenu.js +22 -0
- package/dist/esm/components/PropertyActionsMenu.js.map +1 -0
- package/dist/esm/components/PropertyActionsProps.d.ts +6 -0
- package/dist/esm/components/PropertyActionsProps.js +2 -0
- package/dist/esm/components/PropertyActionsProps.js.map +1 -0
- package/dist/esm/components/PropertyProps.d.ts +13 -0
- package/dist/esm/components/PropertyProps.js +2 -0
- package/dist/esm/components/PropertyProps.js.map +1 -0
- package/dist/esm/components/SizeProp.d.ts +1 -0
- package/dist/esm/components/SizeProp.js +2 -0
- package/dist/esm/components/SizeProp.js.map +1 -0
- package/dist/esm/components/Title.d.ts +10 -0
- package/dist/esm/components/Title.js +13 -0
- package/dist/esm/components/Title.js.map +1 -0
- package/dist/esm/components/Value.d.ts +10 -0
- package/dist/esm/components/Value.js +36 -0
- package/dist/esm/components/Value.js.map +1 -0
- package/dist/esm/components/index.d.ts +6 -0
- package/dist/esm/components/index.js +7 -0
- package/dist/esm/components/index.js.map +1 -0
- package/dist/esm/components/usePropertyHeroProps.d.ts +6 -0
- package/dist/esm/components/usePropertyHeroProps.js +12 -0
- package/dist/esm/components/usePropertyHeroProps.js.map +1 -0
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.js +2 -0
- package/dist/esm/index.js.map +1 -0
- package/package.json +135 -0
- package/src/components/IdenticonCorner.tsx +29 -0
- package/src/components/Property.stories.tsx +163 -0
- package/src/components/Property.tsx +64 -0
- package/src/components/PropertyAction.ts +8 -0
- package/src/components/PropertyActions.tsx +27 -0
- package/src/components/PropertyActionsMenu.tsx +41 -0
- package/src/components/PropertyActionsProps.ts +8 -0
- package/src/components/PropertyProps.tsx +15 -0
- package/src/components/SizeProp.ts +1 -0
- package/src/components/Title.stories.tsx +32 -0
- package/src/components/Title.tsx +38 -0
- package/src/components/Value.stories.tsx +29 -0
- package/src/components/Value.tsx +55 -0
- package/src/components/index.ts +6 -0
- package/src/components/usePropertyHeroProps.tsx +12 -0
- package/src/index.ts +1 -0
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import ReplayIcon from '@mui/icons-material/Replay'
|
|
2
|
+
import { TextField } from '@mui/material'
|
|
3
|
+
import { ComponentMeta, ComponentStory } from '@storybook/react'
|
|
4
|
+
import { FlexCol, FlexRow } from '@xylabs/sdk-react'
|
|
5
|
+
|
|
6
|
+
import { appThemeDecorator, sampleBlockWithPayloads } from '../.storybook'
|
|
7
|
+
import { Property } from './Property'
|
|
8
|
+
|
|
9
|
+
const StorybookEntry = {
|
|
10
|
+
argTypes: {},
|
|
11
|
+
component: Property,
|
|
12
|
+
parameters: {
|
|
13
|
+
docs: {
|
|
14
|
+
page: null,
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
title: 'Properties/Property',
|
|
18
|
+
} as ComponentMeta<typeof Property>
|
|
19
|
+
|
|
20
|
+
const Template: ComponentStory<typeof Property> = (args) => <Property {...args}></Property>
|
|
21
|
+
|
|
22
|
+
const TemplateWithCompare: ComponentStory<typeof Property> = (args) => (
|
|
23
|
+
<FlexCol alignItems="stretch">
|
|
24
|
+
<FlexRow>
|
|
25
|
+
<TextField size="small" value="Sample text Field" />
|
|
26
|
+
<Property {...args} size="small"></Property>
|
|
27
|
+
</FlexRow>
|
|
28
|
+
<FlexRow>
|
|
29
|
+
<Property {...args} size="small"></Property>
|
|
30
|
+
<Property {...args} size="small"></Property>
|
|
31
|
+
</FlexRow>
|
|
32
|
+
<FlexRow>
|
|
33
|
+
<TextField size="medium" value="Sample text Field" />
|
|
34
|
+
<Property {...args} size="medium"></Property>
|
|
35
|
+
</FlexRow>
|
|
36
|
+
<FlexRow>
|
|
37
|
+
<Property {...args} size="medium"></Property>
|
|
38
|
+
<Property {...args} size="medium"></Property>
|
|
39
|
+
</FlexRow>
|
|
40
|
+
<FlexRow>
|
|
41
|
+
<TextField value="Sample text Field" />
|
|
42
|
+
<Property {...args} size="large"></Property>
|
|
43
|
+
</FlexRow>
|
|
44
|
+
<FlexRow>
|
|
45
|
+
<Property {...args} size="large"></Property>
|
|
46
|
+
<Property {...args} size="large"></Property>
|
|
47
|
+
</FlexRow>
|
|
48
|
+
</FlexCol>
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
const Default = Template.bind({})
|
|
52
|
+
Default.args = {}
|
|
53
|
+
Default.decorators = [appThemeDecorator]
|
|
54
|
+
|
|
55
|
+
const WithTitle = Template.bind({})
|
|
56
|
+
WithTitle.args = { title: 'No Data' }
|
|
57
|
+
WithTitle.decorators = [appThemeDecorator]
|
|
58
|
+
|
|
59
|
+
const WithUndefinedData = Template.bind({})
|
|
60
|
+
WithUndefinedData.args = { title: 'Block Hash' }
|
|
61
|
+
WithUndefinedData.decorators = [appThemeDecorator]
|
|
62
|
+
|
|
63
|
+
const WithData = Template.bind({})
|
|
64
|
+
WithData.args = { title: 'Block Hash', value: sampleBlockWithPayloads._hash }
|
|
65
|
+
WithData.decorators = [appThemeDecorator]
|
|
66
|
+
|
|
67
|
+
const WithDataSmall = Template.bind({})
|
|
68
|
+
WithDataSmall.args = { size: 'small', title: 'Block Hash', value: sampleBlockWithPayloads._hash }
|
|
69
|
+
WithDataSmall.decorators = [appThemeDecorator]
|
|
70
|
+
|
|
71
|
+
const WithDataCompare = TemplateWithCompare.bind({})
|
|
72
|
+
WithDataCompare.args = { tip: 'This is the block hash', title: 'Block Hash', value: sampleBlockWithPayloads._hash }
|
|
73
|
+
WithDataCompare.decorators = [appThemeDecorator]
|
|
74
|
+
|
|
75
|
+
const WithDataAndBadgeSmall = Template.bind({})
|
|
76
|
+
WithDataAndBadgeSmall.args = { badge: true, size: 'small', tip: 'This is the block hash', title: 'Block Hash', value: sampleBlockWithPayloads._hash }
|
|
77
|
+
WithDataAndBadgeSmall.decorators = [appThemeDecorator]
|
|
78
|
+
|
|
79
|
+
const WithDataAndBadgeMedium = Template.bind({})
|
|
80
|
+
WithDataAndBadgeMedium.args = { badge: true, size: 'medium', tip: 'This is the block hash', title: 'Block Hash', value: sampleBlockWithPayloads._hash }
|
|
81
|
+
WithDataAndBadgeMedium.decorators = [appThemeDecorator]
|
|
82
|
+
|
|
83
|
+
const WithDataAndBadgeLarge = Template.bind({})
|
|
84
|
+
WithDataAndBadgeLarge.args = { badge: true, size: 'large', tip: 'This is the block hash', title: 'Block Hash', value: sampleBlockWithPayloads._hash }
|
|
85
|
+
WithDataAndBadgeLarge.decorators = [appThemeDecorator]
|
|
86
|
+
|
|
87
|
+
const WithTip = Template.bind({})
|
|
88
|
+
WithTip.args = {
|
|
89
|
+
tip: 'This is the block hash',
|
|
90
|
+
title: 'Block Hash',
|
|
91
|
+
value: sampleBlockWithPayloads._hash,
|
|
92
|
+
}
|
|
93
|
+
WithTip.decorators = [appThemeDecorator]
|
|
94
|
+
|
|
95
|
+
const WithTipAndBadge = Template.bind({})
|
|
96
|
+
WithTipAndBadge.args = {
|
|
97
|
+
badge: true,
|
|
98
|
+
tip: 'This is the block hash',
|
|
99
|
+
title: 'Block Hash',
|
|
100
|
+
value: sampleBlockWithPayloads._hash,
|
|
101
|
+
}
|
|
102
|
+
WithTipAndBadge.decorators = [appThemeDecorator]
|
|
103
|
+
|
|
104
|
+
const WithActions = Template.bind({})
|
|
105
|
+
WithActions.args = {
|
|
106
|
+
actions: [{ name: 'ActionOne' }, { name: 'ActionTwo' }],
|
|
107
|
+
tip: 'This is the block hash',
|
|
108
|
+
title: 'Block Hash',
|
|
109
|
+
value: sampleBlockWithPayloads._hash,
|
|
110
|
+
}
|
|
111
|
+
WithActions.decorators = [appThemeDecorator]
|
|
112
|
+
|
|
113
|
+
const LargeWithValue = Template.bind({})
|
|
114
|
+
LargeWithValue.args = {
|
|
115
|
+
badge: true,
|
|
116
|
+
size: 'large',
|
|
117
|
+
tip: 'This is the block hash',
|
|
118
|
+
title: 'Block Hash',
|
|
119
|
+
value: sampleBlockWithPayloads._hash,
|
|
120
|
+
}
|
|
121
|
+
LargeWithValue.decorators = [appThemeDecorator]
|
|
122
|
+
|
|
123
|
+
const LargeWithValueAndActions = Template.bind({})
|
|
124
|
+
LargeWithValueAndActions.args = {
|
|
125
|
+
actions: [{ icon: <ReplayIcon />, name: 'ActionOne' }, { name: 'ActionTwo' }],
|
|
126
|
+
badge: true,
|
|
127
|
+
size: 'large',
|
|
128
|
+
tip: 'This is the block hash',
|
|
129
|
+
title: 'Block Hash',
|
|
130
|
+
value: sampleBlockWithPayloads._hash,
|
|
131
|
+
}
|
|
132
|
+
LargeWithValueAndActions.decorators = [appThemeDecorator]
|
|
133
|
+
|
|
134
|
+
const SmallWithValueAndActions = Template.bind({})
|
|
135
|
+
SmallWithValueAndActions.args = {
|
|
136
|
+
actions: [{ icon: <ReplayIcon />, name: 'ActionOne' }, { name: 'ActionTwo' }],
|
|
137
|
+
badge: true,
|
|
138
|
+
size: 'small',
|
|
139
|
+
tip: 'This is the block hash',
|
|
140
|
+
title: 'Block Hash',
|
|
141
|
+
value: sampleBlockWithPayloads._hash,
|
|
142
|
+
}
|
|
143
|
+
SmallWithValueAndActions.decorators = [appThemeDecorator]
|
|
144
|
+
|
|
145
|
+
export {
|
|
146
|
+
Default,
|
|
147
|
+
LargeWithValue,
|
|
148
|
+
LargeWithValueAndActions,
|
|
149
|
+
SmallWithValueAndActions,
|
|
150
|
+
WithActions,
|
|
151
|
+
WithData,
|
|
152
|
+
WithDataAndBadgeLarge,
|
|
153
|
+
WithDataAndBadgeMedium,
|
|
154
|
+
WithDataAndBadgeSmall,
|
|
155
|
+
WithDataCompare,
|
|
156
|
+
WithDataSmall,
|
|
157
|
+
WithTip,
|
|
158
|
+
WithTipAndBadge,
|
|
159
|
+
WithUndefinedData,
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// eslint-disable-next-line import/no-default-export
|
|
163
|
+
export default StorybookEntry
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { CircularProgress, TypographyVariant, useTheme } from '@mui/material'
|
|
2
|
+
import { FlexCol, FlexRow } from '@xylabs/sdk-react'
|
|
3
|
+
|
|
4
|
+
import { IdenticonCorner } from './IdenticonCorner'
|
|
5
|
+
import { PropertyActionsMenu } from './PropertyActionsMenu'
|
|
6
|
+
import { PropertyProps } from './PropertyProps'
|
|
7
|
+
import { SizeProp } from './SizeProp'
|
|
8
|
+
import { PropertyTitle } from './Title'
|
|
9
|
+
import { PropertyValue } from './Value'
|
|
10
|
+
|
|
11
|
+
export const Property: React.FC<PropertyProps> = ({ title, value, children, size = 'medium', tip, actions, required, badge = false, ...props }) => {
|
|
12
|
+
const theme = useTheme()
|
|
13
|
+
|
|
14
|
+
const sizeTitleHeight: Record<SizeProp, number> = {
|
|
15
|
+
large: 36,
|
|
16
|
+
medium: 20,
|
|
17
|
+
small: 14,
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const sizeValueHeight: Record<SizeProp, number> = {
|
|
21
|
+
large: 64,
|
|
22
|
+
medium: 36,
|
|
23
|
+
small: 26,
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const sizeVariants: Record<SizeProp, TypographyVariant> = {
|
|
27
|
+
large: 'h6',
|
|
28
|
+
medium: 'body1',
|
|
29
|
+
small: 'body1',
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return (
|
|
33
|
+
<FlexCol
|
|
34
|
+
minWidth={0}
|
|
35
|
+
alignItems="stretch"
|
|
36
|
+
border={1}
|
|
37
|
+
borderColor={required && value === undefined ? theme.palette.error.main : theme.palette.divider}
|
|
38
|
+
borderRadius={1}
|
|
39
|
+
overflow="hidden"
|
|
40
|
+
{...props}
|
|
41
|
+
>
|
|
42
|
+
{title !== undefined ? (
|
|
43
|
+
<PropertyTitle
|
|
44
|
+
tip={tip}
|
|
45
|
+
title={title}
|
|
46
|
+
size={size}
|
|
47
|
+
bgcolor={theme.palette.secondary.main}
|
|
48
|
+
color={theme.palette.getContrastText(theme.palette.secondary.main)}
|
|
49
|
+
height={sizeTitleHeight[size]}
|
|
50
|
+
more={<PropertyActionsMenu actions={actions} />}
|
|
51
|
+
/>
|
|
52
|
+
) : null}
|
|
53
|
+
<FlexRow justifyContent={value === undefined ? 'center' : 'space-between'} overflow="hidden" height={sizeValueHeight[size]}>
|
|
54
|
+
{children}
|
|
55
|
+
{value !== undefined ? (
|
|
56
|
+
<PropertyValue shortSpace={badge ? sizeValueHeight[size] : 0} value={value} typographyVariant={sizeVariants[size]} />
|
|
57
|
+
) : (
|
|
58
|
+
<CircularProgress size={16} />
|
|
59
|
+
)}
|
|
60
|
+
{value !== undefined ? badge ? <IdenticonCorner value={value} /> : null : null}
|
|
61
|
+
</FlexRow>
|
|
62
|
+
</FlexCol>
|
|
63
|
+
)
|
|
64
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { IconButton, Stack } from '@mui/material'
|
|
2
|
+
import { ButtonEx, FlexRow } from '@xylabs/sdk-react'
|
|
3
|
+
|
|
4
|
+
import { PropertyActionsProps } from './PropertyActionsProps'
|
|
5
|
+
|
|
6
|
+
export const PropertyActions: React.FC<PropertyActionsProps> = ({ buttons = false, actions, ...props }) => {
|
|
7
|
+
if (actions) {
|
|
8
|
+
return (actions?.length ?? 0) > 0 ? (
|
|
9
|
+
<FlexRow {...props}>
|
|
10
|
+
<Stack direction="row" spacing={1}>
|
|
11
|
+
{actions.map((action, index) => {
|
|
12
|
+
return action.icon ? (
|
|
13
|
+
<IconButton size="small" key={index} color="inherit" onClick={action.onClick}>
|
|
14
|
+
{action.icon}
|
|
15
|
+
</IconButton>
|
|
16
|
+
) : buttons ? (
|
|
17
|
+
<ButtonEx paddingY={0} color="primary" key={index} size="small" disabled={action.disabled} onClick={action.onClick} variant="contained">
|
|
18
|
+
{action.name}
|
|
19
|
+
</ButtonEx>
|
|
20
|
+
) : null
|
|
21
|
+
})}
|
|
22
|
+
</Stack>
|
|
23
|
+
</FlexRow>
|
|
24
|
+
) : null
|
|
25
|
+
}
|
|
26
|
+
return null
|
|
27
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import MoreHorizIcon from '@mui/icons-material/MoreHoriz'
|
|
2
|
+
import { IconButton, Menu, MenuItem } from '@mui/material'
|
|
3
|
+
import { FlexRow } from '@xylabs/sdk-react'
|
|
4
|
+
import { useState } from 'react'
|
|
5
|
+
|
|
6
|
+
import { PropertyActionsProps } from './PropertyActionsProps'
|
|
7
|
+
|
|
8
|
+
export const PropertyActionsMenu: React.FC<PropertyActionsProps> = ({ actions, ...props }) => {
|
|
9
|
+
const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null)
|
|
10
|
+
const open = !!anchorEl
|
|
11
|
+
|
|
12
|
+
const handleClick = (event: React.MouseEvent<HTMLElement>) => {
|
|
13
|
+
setAnchorEl(event.currentTarget)
|
|
14
|
+
}
|
|
15
|
+
const handleClose = () => {
|
|
16
|
+
setAnchorEl(null)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
return actions && actions?.length > 0 ? (
|
|
20
|
+
<FlexRow {...props}>
|
|
21
|
+
<IconButton size="small" color="inherit" onClick={handleClick}>
|
|
22
|
+
<MoreHorizIcon fontSize="inherit" />
|
|
23
|
+
</IconButton>
|
|
24
|
+
<Menu anchorEl={anchorEl} open={open} onClose={handleClose}>
|
|
25
|
+
{actions?.map((action) => {
|
|
26
|
+
return (
|
|
27
|
+
<MenuItem
|
|
28
|
+
key={action.name}
|
|
29
|
+
onClick={() => {
|
|
30
|
+
action?.onClick?.()
|
|
31
|
+
handleClose()
|
|
32
|
+
}}
|
|
33
|
+
>
|
|
34
|
+
{action.name}
|
|
35
|
+
</MenuItem>
|
|
36
|
+
)
|
|
37
|
+
})}
|
|
38
|
+
</Menu>
|
|
39
|
+
</FlexRow>
|
|
40
|
+
) : null
|
|
41
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { FlexBoxProps } from '@xylabs/sdk-react'
|
|
2
|
+
import { ReactNode } from 'react'
|
|
3
|
+
|
|
4
|
+
import { PropertyAction } from './PropertyAction'
|
|
5
|
+
import { SizeProp } from './SizeProp'
|
|
6
|
+
|
|
7
|
+
export interface PropertyProps extends FlexBoxProps {
|
|
8
|
+
actions?: PropertyAction[]
|
|
9
|
+
required?: boolean
|
|
10
|
+
tip?: ReactNode
|
|
11
|
+
title?: string
|
|
12
|
+
value?: string | number | boolean | null
|
|
13
|
+
badge?: boolean
|
|
14
|
+
size?: SizeProp
|
|
15
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type SizeProp = 'small' | 'medium' | 'large'
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { ComponentMeta, ComponentStory } from '@storybook/react'
|
|
2
|
+
|
|
3
|
+
import { PropertyTitle } from './Title'
|
|
4
|
+
|
|
5
|
+
const StorybookEntry = {
|
|
6
|
+
argTypes: {},
|
|
7
|
+
component: PropertyTitle,
|
|
8
|
+
parameters: {
|
|
9
|
+
docs: {
|
|
10
|
+
page: null,
|
|
11
|
+
},
|
|
12
|
+
},
|
|
13
|
+
title: 'Properties/Title',
|
|
14
|
+
} as ComponentMeta<typeof PropertyTitle>
|
|
15
|
+
|
|
16
|
+
const Template: ComponentStory<typeof PropertyTitle> = (args) => <PropertyTitle {...args}></PropertyTitle>
|
|
17
|
+
|
|
18
|
+
const Default = Template.bind({})
|
|
19
|
+
Default.args = {}
|
|
20
|
+
|
|
21
|
+
const WithData = Template.bind({})
|
|
22
|
+
|
|
23
|
+
WithData.args = { title: 'Sample Title' }
|
|
24
|
+
|
|
25
|
+
const WithDataAndActions = Template.bind({})
|
|
26
|
+
|
|
27
|
+
WithDataAndActions.args = { title: 'Sample Title' }
|
|
28
|
+
|
|
29
|
+
export { Default, WithData, WithDataAndActions }
|
|
30
|
+
|
|
31
|
+
// eslint-disable-next-line import/no-default-export
|
|
32
|
+
export default StorybookEntry
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { Typography, TypographyVariant, useTheme } from '@mui/material'
|
|
2
|
+
import { FlexBoxProps, FlexRow, QuickTipButton } from '@xylabs/sdk-react'
|
|
3
|
+
import { ReactNode } from 'react'
|
|
4
|
+
|
|
5
|
+
import { SizeProp } from './SizeProp'
|
|
6
|
+
|
|
7
|
+
export interface PropertyTitleProps extends FlexBoxProps {
|
|
8
|
+
tip?: ReactNode
|
|
9
|
+
more?: ReactNode
|
|
10
|
+
title?: string
|
|
11
|
+
size?: SizeProp
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export const PropertyTitle: React.FC<PropertyTitleProps> = ({ size = 'medium', tip, more, title, ...props }) => {
|
|
15
|
+
const sizeVariants: Record<SizeProp, TypographyVariant> = {
|
|
16
|
+
large: 'h6',
|
|
17
|
+
medium: 'caption',
|
|
18
|
+
small: 'caption',
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const theme = useTheme()
|
|
22
|
+
|
|
23
|
+
return (
|
|
24
|
+
<FlexRow justifyContent="space-between" {...props}>
|
|
25
|
+
<FlexRow paddingX={1}>
|
|
26
|
+
<Typography noWrap variant={sizeVariants[size]}>
|
|
27
|
+
{title}
|
|
28
|
+
</Typography>
|
|
29
|
+
{tip ? (
|
|
30
|
+
<QuickTipButton style={{ fontSize: theme.typography[sizeVariants[size]].fontSize }} color="inherit" title={title ?? ''}>
|
|
31
|
+
{tip}
|
|
32
|
+
</QuickTipButton>
|
|
33
|
+
) : null}
|
|
34
|
+
</FlexRow>
|
|
35
|
+
{more}
|
|
36
|
+
</FlexRow>
|
|
37
|
+
)
|
|
38
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { ComponentMeta, ComponentStory } from '@storybook/react'
|
|
2
|
+
|
|
3
|
+
import { sampleBlockWithPayloads } from '../.storybook'
|
|
4
|
+
import { PropertyValue } from './Value'
|
|
5
|
+
|
|
6
|
+
const StorybookEntry = {
|
|
7
|
+
argTypes: {},
|
|
8
|
+
component: PropertyValue,
|
|
9
|
+
parameters: {
|
|
10
|
+
docs: {
|
|
11
|
+
page: null,
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
title: 'Properties/Value',
|
|
15
|
+
} as ComponentMeta<typeof PropertyValue>
|
|
16
|
+
|
|
17
|
+
const Template: ComponentStory<typeof PropertyValue> = (args) => <PropertyValue {...args}></PropertyValue>
|
|
18
|
+
|
|
19
|
+
const Default = Template.bind({})
|
|
20
|
+
Default.args = {}
|
|
21
|
+
|
|
22
|
+
const WithData = Template.bind({})
|
|
23
|
+
|
|
24
|
+
WithData.args = { value: sampleBlockWithPayloads._hash }
|
|
25
|
+
|
|
26
|
+
export { Default, WithData }
|
|
27
|
+
|
|
28
|
+
// eslint-disable-next-line import/no-default-export
|
|
29
|
+
export default StorybookEntry
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { Typography, TypographyProps, useTheme } from '@mui/material'
|
|
2
|
+
import { Variant } from '@mui/material/styles/createTypography'
|
|
3
|
+
import { useEffect, useRef, useState } from 'react'
|
|
4
|
+
|
|
5
|
+
export interface PropertyValueProps extends TypographyProps<'div'> {
|
|
6
|
+
value?: string | number | boolean | null
|
|
7
|
+
typographyVariant?: Variant
|
|
8
|
+
/** @field The space that is removed from the ... at end (mainly for identicon) */
|
|
9
|
+
shortSpace?: number
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export const PropertyValue: React.FC<PropertyValueProps> = ({ value, shortSpace, typographyVariant = 'caption', ...props }) => {
|
|
13
|
+
const [parentWidth, setParentWidth] = useState<number>()
|
|
14
|
+
const theme = useTheme()
|
|
15
|
+
|
|
16
|
+
const ref = useRef<HTMLDivElement>(null)
|
|
17
|
+
|
|
18
|
+
const customThemeProps = {
|
|
19
|
+
clamped: parentWidth && theme ? parentWidth - parseInt(theme.spacing(2), 10) - (shortSpace ?? 0) : undefined,
|
|
20
|
+
title: value?.toString(),
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
useEffect(() => {
|
|
24
|
+
const resizeHandler = () => {
|
|
25
|
+
const smallestWidth = getSmallestParentWidth(ref.current)
|
|
26
|
+
setParentWidth(smallestWidth)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const getSmallestParentWidth = (element: HTMLElement | null) => {
|
|
30
|
+
let current = element?.parentElement
|
|
31
|
+
let width: number | null = null
|
|
32
|
+
while (current) {
|
|
33
|
+
if (width === null || current.clientWidth < width) {
|
|
34
|
+
width = current.clientWidth
|
|
35
|
+
}
|
|
36
|
+
current = current.parentElement
|
|
37
|
+
}
|
|
38
|
+
return width ?? undefined
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
window.addEventListener('resize', resizeHandler)
|
|
42
|
+
|
|
43
|
+
setParentWidth(getSmallestParentWidth(ref.current))
|
|
44
|
+
|
|
45
|
+
return () => {
|
|
46
|
+
window?.removeEventListener('resize', resizeHandler)
|
|
47
|
+
}
|
|
48
|
+
}, [])
|
|
49
|
+
|
|
50
|
+
return value !== undefined ? (
|
|
51
|
+
<Typography minWidth={0} marginX={1} ref={ref} component="div" variant={typographyVariant} fontFamily="monospace" fontWeight="light" {...customThemeProps} {...props}>
|
|
52
|
+
{value}
|
|
53
|
+
</Typography>
|
|
54
|
+
) : null
|
|
55
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// Any is ok since we are destructuring props of any shape
|
|
2
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
3
|
+
const usePropertyHeroProps = (props: Record<any, any>) => {
|
|
4
|
+
const { isHero, paddingFactor, showBadge } = props
|
|
5
|
+
return {
|
|
6
|
+
isHero,
|
|
7
|
+
paddingFactor,
|
|
8
|
+
showBadge,
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export { usePropertyHeroProps }
|
package/src/index.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './components'
|