@stack-spot/citric-react 0.36.0 → 0.37.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/citric.css +2844 -2832
- package/dist/components/Accordion.d.ts +1 -1
- package/dist/components/Accordion.js +1 -1
- package/dist/components/Alert.d.ts +1 -1
- package/dist/components/Alert.js +1 -1
- package/dist/components/AsyncContent.d.ts +1 -1
- package/dist/components/AsyncContent.js +1 -1
- package/dist/components/Avatar.d.ts +1 -1
- package/dist/components/Avatar.js +1 -1
- package/dist/components/AvatarGroup.d.ts +1 -1
- package/dist/components/AvatarGroup.js +1 -1
- package/dist/components/Badge.d.ts +1 -1
- package/dist/components/Badge.js +1 -1
- package/dist/components/Blockquote.d.ts +1 -1
- package/dist/components/Blockquote.js +1 -1
- package/dist/components/Breadcrumb.d.ts +1 -1
- package/dist/components/Breadcrumb.js +1 -1
- package/dist/components/Button.d.ts +1 -1
- package/dist/components/Button.js +1 -1
- package/dist/components/ButtonLink.d.ts +1 -1
- package/dist/components/ButtonLink.js +1 -1
- package/dist/components/Card.d.ts +1 -1
- package/dist/components/Card.js +1 -1
- package/dist/components/Checkbox.d.ts +1 -1
- package/dist/components/Checkbox.js +1 -1
- package/dist/components/CheckboxGroup.d.ts +1 -1
- package/dist/components/CheckboxGroup.js +1 -1
- package/dist/components/Circle.d.ts +1 -1
- package/dist/components/Circle.js +1 -1
- package/dist/components/Divider.d.ts +1 -1
- package/dist/components/Divider.js +1 -1
- package/dist/components/ErrorBoundary.d.ts +1 -1
- package/dist/components/ErrorBoundary.js +1 -1
- package/dist/components/ErrorMessage.d.ts +1 -1
- package/dist/components/ErrorMessage.js +1 -1
- package/dist/components/FallbackBoundary.d.ts +1 -1
- package/dist/components/FallbackBoundary.js +1 -1
- package/dist/components/Favorite.d.ts +1 -1
- package/dist/components/Favorite.js +1 -1
- package/dist/components/FieldGroup.d.ts +1 -1
- package/dist/components/FieldGroup.js +1 -1
- package/dist/components/Form.d.ts +2 -2
- package/dist/components/Form.js +1 -1
- package/dist/components/FormGroup.d.ts +1 -1
- package/dist/components/FormGroup.js +1 -1
- package/dist/components/Icon.d.ts +1 -1
- package/dist/components/Icon.js +1 -1
- package/dist/components/IconBox.d.ts +3 -3
- package/dist/components/IconBox.js +1 -1
- package/dist/components/ImageBox.d.ts +3 -3
- package/dist/components/ImageBox.js +1 -1
- package/dist/components/ImageWithFallback.d.ts +1 -1
- package/dist/components/ImageWithFallback.js +1 -1
- package/dist/components/Input.d.ts +1 -1
- package/dist/components/Input.js +1 -1
- package/dist/components/Link.d.ts +1 -1
- package/dist/components/Link.js +1 -1
- package/dist/components/LoadingPanel.d.ts +1 -1
- package/dist/components/LoadingPanel.js +1 -1
- package/dist/components/MenuOverlay/Menu.d.ts +1 -1
- package/dist/components/MenuOverlay/Menu.js +1 -1
- package/dist/components/MenuOverlay/index.d.ts +1 -1
- package/dist/components/MenuOverlay/index.js +1 -1
- package/dist/components/Overlay/index.d.ts +1 -1
- package/dist/components/Overlay/index.js +1 -1
- package/dist/components/Pagination.d.ts +1 -1
- package/dist/components/Pagination.js +1 -1
- package/dist/components/ProgressBar.d.ts +1 -1
- package/dist/components/ProgressBar.js +1 -1
- package/dist/components/ProgressCircular.d.ts +1 -1
- package/dist/components/ProgressCircular.js +1 -1
- package/dist/components/RadioGroup.d.ts +1 -1
- package/dist/components/RadioGroup.js +1 -1
- package/dist/components/Rating.d.ts +17 -3
- package/dist/components/Rating.d.ts.map +1 -1
- package/dist/components/Rating.js +11 -3
- package/dist/components/Rating.js.map +1 -1
- package/dist/components/Select/MultiSelect.d.ts +1 -1
- package/dist/components/Select/MultiSelect.js +1 -1
- package/dist/components/Select/RichSelect.d.ts +1 -1
- package/dist/components/Select/RichSelect.js +1 -1
- package/dist/components/Select/SimpleSelect.d.ts +1 -1
- package/dist/components/Select/SimpleSelect.js +1 -1
- package/dist/components/Select/index.d.ts +1 -1
- package/dist/components/Select/index.js +1 -1
- package/dist/components/SelectBox.d.ts +1 -1
- package/dist/components/SelectBox.js +1 -1
- package/dist/components/Skeleton.d.ts +1 -1
- package/dist/components/Skeleton.js +1 -1
- package/dist/components/Slider.d.ts +1 -1
- package/dist/components/Slider.js +1 -1
- package/dist/components/SmartTable.d.ts +1 -1
- package/dist/components/SmartTable.js +1 -1
- package/dist/components/Stepper.d.ts +1 -1
- package/dist/components/Stepper.js +1 -1
- package/dist/components/Table.d.ts +3 -3
- package/dist/components/Table.js +1 -1
- package/dist/components/Tabs/index.d.ts +1 -1
- package/dist/components/Tabs/index.js +1 -1
- package/dist/components/Textarea.d.ts +1 -1
- package/dist/components/Textarea.js +1 -1
- package/dist/components/Tooltip.d.ts +1 -1
- package/dist/components/Tooltip.js +1 -1
- package/dist/context/CitricProvider.d.ts +1 -1
- package/dist/context/CitricProvider.js +1 -1
- package/dist/overlay.js +1 -1
- package/dist/theme.css +415 -415
- package/package.json +3 -2
- package/scripts/build-css.ts +49 -49
- package/src/components/Accordion.tsx +130 -130
- package/src/components/Alert.tsx +24 -24
- package/src/components/AsyncContent.tsx +70 -70
- package/src/components/Avatar.tsx +45 -45
- package/src/components/AvatarGroup.tsx +49 -49
- package/src/components/Badge.tsx +47 -47
- package/src/components/Blockquote.tsx +18 -18
- package/src/components/Breadcrumb.tsx +33 -33
- package/src/components/Button.tsx +105 -105
- package/src/components/ButtonLink.tsx +45 -45
- package/src/components/Card.tsx +68 -68
- package/src/components/Checkbox.tsx +51 -51
- package/src/components/CheckboxGroup.tsx +152 -152
- package/src/components/Circle.tsx +43 -43
- package/src/components/CitricComponent.ts +47 -47
- package/src/components/Divider.tsx +24 -24
- package/src/components/ErrorBoundary.tsx +75 -75
- package/src/components/ErrorMessage.tsx +11 -11
- package/src/components/FallbackBoundary.tsx +40 -40
- package/src/components/Favorite.tsx +57 -57
- package/src/components/FieldGroup.tsx +46 -46
- package/src/components/Form.tsx +36 -36
- package/src/components/FormGroup.tsx +57 -57
- package/src/components/Icon.tsx +35 -35
- package/src/components/IconBox.tsx +134 -134
- package/src/components/ImageBox.tsx +125 -125
- package/src/components/ImageWithFallback.tsx +65 -65
- package/src/components/Input.tsx +49 -49
- package/src/components/Link.tsx +55 -55
- package/src/components/LoadingPanel.tsx +8 -8
- package/src/components/MenuOverlay/Menu.tsx +158 -158
- package/src/components/MenuOverlay/context.ts +20 -20
- package/src/components/MenuOverlay/index.tsx +55 -55
- package/src/components/MenuOverlay/keyboard.ts +60 -60
- package/src/components/MenuOverlay/types.ts +171 -171
- package/src/components/Overlay/context.ts +10 -10
- package/src/components/Overlay/index.tsx +164 -164
- package/src/components/Overlay/types.ts +70 -70
- package/src/components/Pagination.tsx +113 -113
- package/src/components/ProgressBar.tsx +45 -45
- package/src/components/ProgressCircular.tsx +45 -45
- package/src/components/RadioGroup.tsx +146 -146
- package/src/components/Rating.tsx +98 -35
- package/src/components/Select/MultiSelect.tsx +217 -217
- package/src/components/Select/RichSelect.tsx +128 -128
- package/src/components/Select/SimpleSelect.tsx +73 -73
- package/src/components/Select/hooks.ts +133 -133
- package/src/components/Select/index.tsx +35 -35
- package/src/components/Select/types.ts +134 -134
- package/src/components/SelectBox.tsx +167 -167
- package/src/components/Skeleton.tsx +53 -53
- package/src/components/Slider.tsx +89 -89
- package/src/components/SmartTable.tsx +227 -227
- package/src/components/Stepper.tsx +163 -163
- package/src/components/Table.tsx +234 -234
- package/src/components/Tabs/TabController.ts +54 -54
- package/src/components/Tabs/index.tsx +87 -87
- package/src/components/Tabs/types.ts +54 -54
- package/src/components/Tabs/utils.ts +6 -6
- package/src/components/Text.ts +111 -111
- package/src/components/Textarea.tsx +27 -27
- package/src/components/Tooltip.tsx +72 -72
- package/src/components/layout.tsx +101 -101
- package/src/context/CitricContext.tsx +4 -4
- package/src/context/CitricProvider.tsx +14 -14
- package/src/context/hooks.ts +6 -6
- package/src/index.ts +58 -58
- package/src/overlay.ts +341 -341
- package/src/types.ts +216 -216
- package/src/utils/ValueController.ts +28 -28
- package/src/utils/acessibility.ts +92 -92
- package/src/utils/checkbox.ts +121 -121
- package/src/utils/css.ts +119 -119
- package/src/utils/options.ts +9 -9
- package/src/utils/radio.ts +93 -93
- package/src/utils/react.ts +6 -6
- package/tsconfig.json +10 -10
|
@@ -1,49 +1,49 @@
|
|
|
1
|
-
import { listToClass } from '@stack-spot/portal-theme'
|
|
2
|
-
import { WithColorPalette } from '../types'
|
|
3
|
-
import { withRef } from '../utils/react'
|
|
4
|
-
import { Avatar } from './Avatar'
|
|
5
|
-
import { CitricComponent } from './CitricComponent'
|
|
6
|
-
|
|
7
|
-
export interface BaseAvatarGroupProps extends WithColorPalette {
|
|
8
|
-
/**
|
|
9
|
-
* @default 'lg'
|
|
10
|
-
*/
|
|
11
|
-
size?: 'xxs' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'xxl',
|
|
12
|
-
/**
|
|
13
|
-
* @default 'circle'
|
|
14
|
-
*/
|
|
15
|
-
appearance?: 'square' | 'circle',
|
|
16
|
-
/**
|
|
17
|
-
* The avatars in the group. Use "image" for rendering images instead of the avatar.
|
|
18
|
-
*/
|
|
19
|
-
items: { name?: string, image?: string }[],
|
|
20
|
-
/**
|
|
21
|
-
* A maximum number of avatars to show in the group.
|
|
22
|
-
**/
|
|
23
|
-
maxItems?: number,
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export type AvatarGroupProps = React.JSX.IntrinsicElements['div'] & BaseAvatarGroupProps
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Stacks a group of avatars horizontally.
|
|
30
|
-
*
|
|
31
|
-
* @example
|
|
32
|
-
* ```
|
|
33
|
-
* <AvatarGroup items={[{ name: 'John Smith' }, { name: 'Mary Anne', image: 'https://profile.com/123.png' }]} />
|
|
34
|
-
* ```
|
|
35
|
-
*/
|
|
36
|
-
export const AvatarGroup = withRef(({ size, items, appearance, maxItems, className, ...props }: AvatarGroupProps) => {
|
|
37
|
-
const avatars = items.map(({ name, image }) => <Avatar key={name} name={name} image={image} />, [items])
|
|
38
|
-
return (
|
|
39
|
-
<CitricComponent
|
|
40
|
-
tag="div"
|
|
41
|
-
component="avatar-group"
|
|
42
|
-
className={listToClass([size, appearance, className])}
|
|
43
|
-
data-max-items={maxItems}
|
|
44
|
-
{...props}
|
|
45
|
-
>
|
|
46
|
-
{avatars}
|
|
47
|
-
</CitricComponent>
|
|
48
|
-
)
|
|
49
|
-
})
|
|
1
|
+
import { listToClass } from '@stack-spot/portal-theme'
|
|
2
|
+
import { WithColorPalette } from '../types'
|
|
3
|
+
import { withRef } from '../utils/react'
|
|
4
|
+
import { Avatar } from './Avatar'
|
|
5
|
+
import { CitricComponent } from './CitricComponent'
|
|
6
|
+
|
|
7
|
+
export interface BaseAvatarGroupProps extends WithColorPalette {
|
|
8
|
+
/**
|
|
9
|
+
* @default 'lg'
|
|
10
|
+
*/
|
|
11
|
+
size?: 'xxs' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'xxl',
|
|
12
|
+
/**
|
|
13
|
+
* @default 'circle'
|
|
14
|
+
*/
|
|
15
|
+
appearance?: 'square' | 'circle',
|
|
16
|
+
/**
|
|
17
|
+
* The avatars in the group. Use "image" for rendering images instead of the avatar.
|
|
18
|
+
*/
|
|
19
|
+
items: { name?: string, image?: string }[],
|
|
20
|
+
/**
|
|
21
|
+
* A maximum number of avatars to show in the group.
|
|
22
|
+
**/
|
|
23
|
+
maxItems?: number,
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export type AvatarGroupProps = React.JSX.IntrinsicElements['div'] & BaseAvatarGroupProps
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Stacks a group of avatars horizontally.
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```
|
|
33
|
+
* <AvatarGroup items={[{ name: 'John Smith' }, { name: 'Mary Anne', image: 'https://profile.com/123.png' }]} />
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export const AvatarGroup = withRef(({ size, items, appearance, maxItems, className, ...props }: AvatarGroupProps) => {
|
|
37
|
+
const avatars = items.map(({ name, image }) => <Avatar key={name} name={name} image={image} />, [items])
|
|
38
|
+
return (
|
|
39
|
+
<CitricComponent
|
|
40
|
+
tag="div"
|
|
41
|
+
component="avatar-group"
|
|
42
|
+
className={listToClass([size, appearance, className])}
|
|
43
|
+
data-max-items={maxItems}
|
|
44
|
+
{...props}
|
|
45
|
+
>
|
|
46
|
+
{avatars}
|
|
47
|
+
</CitricComponent>
|
|
48
|
+
)
|
|
49
|
+
})
|
package/src/components/Badge.tsx
CHANGED
|
@@ -1,47 +1,47 @@
|
|
|
1
|
-
import { listToClass } from '@stack-spot/portal-theme'
|
|
2
|
-
import { HTMLTag, WithColorPalette, WithColorScheme } from '../types'
|
|
3
|
-
import { withRef } from '../utils/react'
|
|
4
|
-
import { CitricComponent } from './CitricComponent'
|
|
5
|
-
|
|
6
|
-
type ValidTags = 'a' | 'button' | 'li' | 'div' | 'span'
|
|
7
|
-
|
|
8
|
-
export interface BaseBadgeProps<T extends ValidTags = ValidTags> extends WithColorPalette, WithColorScheme {
|
|
9
|
-
/**
|
|
10
|
-
* @default 'div'
|
|
11
|
-
*/
|
|
12
|
-
tag?: T,
|
|
13
|
-
/**
|
|
14
|
-
* Determines how round the corners are.
|
|
15
|
-
*
|
|
16
|
-
* @default 'circle'
|
|
17
|
-
*/
|
|
18
|
-
appearance?: 'square' | 'circle',
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export type BadgeProps<T extends ValidTags> = HTMLTag[T] & BaseBadgeProps<T>
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Renders a badge. Badges have different color grades depending if they're focusable or not. Use `colorPalette` do determine the main
|
|
25
|
-
* color.
|
|
26
|
-
*
|
|
27
|
-
* @example
|
|
28
|
-
* ```
|
|
29
|
-
* <Badge>
|
|
30
|
-
* <Icon icon="PlusMini" />
|
|
31
|
-
* My first badge
|
|
32
|
-
* </Badge>
|
|
33
|
-
* ```
|
|
34
|
-
*/
|
|
35
|
-
export const Badge = withRef(
|
|
36
|
-
function Badge<T extends ValidTags>({ tag, appearance, className, children, ...props }: BadgeProps<T>) {
|
|
37
|
-
return (
|
|
38
|
-
<CitricComponent tag={tag || 'div'} component="badge" className={listToClass([appearance, className])} {...props as any}>
|
|
39
|
-
{children}
|
|
40
|
-
</CitricComponent>
|
|
41
|
-
)
|
|
42
|
-
},
|
|
43
|
-
)
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
// export const Badge = withRef(_Badge)
|
|
47
|
-
|
|
1
|
+
import { listToClass } from '@stack-spot/portal-theme'
|
|
2
|
+
import { HTMLTag, WithColorPalette, WithColorScheme } from '../types'
|
|
3
|
+
import { withRef } from '../utils/react'
|
|
4
|
+
import { CitricComponent } from './CitricComponent'
|
|
5
|
+
|
|
6
|
+
type ValidTags = 'a' | 'button' | 'li' | 'div' | 'span'
|
|
7
|
+
|
|
8
|
+
export interface BaseBadgeProps<T extends ValidTags = ValidTags> extends WithColorPalette, WithColorScheme {
|
|
9
|
+
/**
|
|
10
|
+
* @default 'div'
|
|
11
|
+
*/
|
|
12
|
+
tag?: T,
|
|
13
|
+
/**
|
|
14
|
+
* Determines how round the corners are.
|
|
15
|
+
*
|
|
16
|
+
* @default 'circle'
|
|
17
|
+
*/
|
|
18
|
+
appearance?: 'square' | 'circle',
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export type BadgeProps<T extends ValidTags> = HTMLTag[T] & BaseBadgeProps<T>
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Renders a badge. Badges have different color grades depending if they're focusable or not. Use `colorPalette` do determine the main
|
|
25
|
+
* color.
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```
|
|
29
|
+
* <Badge>
|
|
30
|
+
* <Icon icon="PlusMini" />
|
|
31
|
+
* My first badge
|
|
32
|
+
* </Badge>
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
export const Badge = withRef(
|
|
36
|
+
function Badge<T extends ValidTags>({ tag, appearance, className, children, ...props }: BadgeProps<T>) {
|
|
37
|
+
return (
|
|
38
|
+
<CitricComponent tag={tag || 'div'} component="badge" className={listToClass([appearance, className])} {...props as any}>
|
|
39
|
+
{children}
|
|
40
|
+
</CitricComponent>
|
|
41
|
+
)
|
|
42
|
+
},
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
// export const Badge = withRef(_Badge)
|
|
47
|
+
|
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
import { WithColorPalette, WithColorScheme } from '../types'
|
|
2
|
-
import { withRef } from '../utils/react'
|
|
3
|
-
import { CitricComponent } from './CitricComponent'
|
|
4
|
-
|
|
5
|
-
export type BaseBlockquoteProps = WithColorScheme & WithColorPalette
|
|
6
|
-
|
|
7
|
-
export type BlockquoteProps = React.JSX.IntrinsicElements['blockquote'] & BaseBlockquoteProps
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Renders a quote.
|
|
11
|
-
*
|
|
12
|
-
* @example
|
|
13
|
-
* ```
|
|
14
|
-
* <Blockquote>To be or not to be, that's the question</Blockquote>
|
|
15
|
-
* ```
|
|
16
|
-
*/
|
|
17
|
-
export const Blockquote = withRef(({ children, ...props }: BlockquoteProps) =>
|
|
18
|
-
<CitricComponent tag="blockquote" component="blockquote" {...props}>{children}</CitricComponent>)
|
|
1
|
+
import { WithColorPalette, WithColorScheme } from '../types'
|
|
2
|
+
import { withRef } from '../utils/react'
|
|
3
|
+
import { CitricComponent } from './CitricComponent'
|
|
4
|
+
|
|
5
|
+
export type BaseBlockquoteProps = WithColorScheme & WithColorPalette
|
|
6
|
+
|
|
7
|
+
export type BlockquoteProps = React.JSX.IntrinsicElements['blockquote'] & BaseBlockquoteProps
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Renders a quote.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```
|
|
14
|
+
* <Blockquote>To be or not to be, that's the question</Blockquote>
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
export const Blockquote = withRef(({ children, ...props }: BlockquoteProps) =>
|
|
18
|
+
<CitricComponent tag="blockquote" component="blockquote" {...props}>{children}</CitricComponent>)
|
|
@@ -1,33 +1,33 @@
|
|
|
1
|
-
import { useMemo } from 'react'
|
|
2
|
-
import { withRef } from '../utils/react'
|
|
3
|
-
import { CitricComponent } from './CitricComponent'
|
|
4
|
-
import { Link } from './Link'
|
|
5
|
-
|
|
6
|
-
interface BreadCrumbItem {
|
|
7
|
-
label: string,
|
|
8
|
-
href?: string,
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export interface BaseBreadcrumbProps {
|
|
12
|
-
items: BreadCrumbItem[],
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export type BreadcrumbProps = React.JSX.IntrinsicElements['nav'] & BaseBreadcrumbProps
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Renders a simple navigation bar with links to the previous pages.
|
|
19
|
-
*
|
|
20
|
-
* @example
|
|
21
|
-
* ```
|
|
22
|
-
* <Breadcrumb items={[{ label: 'Home', href: '/' }, { label: 'Settings', href: '/settings' }, { label: 'Profile' }]} />
|
|
23
|
-
* ```
|
|
24
|
-
*/
|
|
25
|
-
export const Breadcrumb = withRef(({ items, ...props }: BreadcrumbProps) => {
|
|
26
|
-
const children = useMemo(
|
|
27
|
-
() => items.map(
|
|
28
|
-
(item, index) => item.href ? <li key={index}><Link href={item.href}>{item.label}</Link></li> : <li key={index}>{item.label}</li>,
|
|
29
|
-
),
|
|
30
|
-
[items],
|
|
31
|
-
)
|
|
32
|
-
return <CitricComponent tag="nav" component="breadcrumb" {...props}><ul>{children}</ul></CitricComponent>
|
|
33
|
-
})
|
|
1
|
+
import { useMemo } from 'react'
|
|
2
|
+
import { withRef } from '../utils/react'
|
|
3
|
+
import { CitricComponent } from './CitricComponent'
|
|
4
|
+
import { Link } from './Link'
|
|
5
|
+
|
|
6
|
+
interface BreadCrumbItem {
|
|
7
|
+
label: string,
|
|
8
|
+
href?: string,
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface BaseBreadcrumbProps {
|
|
12
|
+
items: BreadCrumbItem[],
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export type BreadcrumbProps = React.JSX.IntrinsicElements['nav'] & BaseBreadcrumbProps
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Renders a simple navigation bar with links to the previous pages.
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```
|
|
22
|
+
* <Breadcrumb items={[{ label: 'Home', href: '/' }, { label: 'Settings', href: '/settings' }, { label: 'Profile' }]} />
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
export const Breadcrumb = withRef(({ items, ...props }: BreadcrumbProps) => {
|
|
26
|
+
const children = useMemo(
|
|
27
|
+
() => items.map(
|
|
28
|
+
(item, index) => item.href ? <li key={index}><Link href={item.href}>{item.label}</Link></li> : <li key={index}>{item.label}</li>,
|
|
29
|
+
),
|
|
30
|
+
[items],
|
|
31
|
+
)
|
|
32
|
+
return <CitricComponent tag="nav" component="breadcrumb" {...props}><ul>{children}</ul></CitricComponent>
|
|
33
|
+
})
|
|
@@ -1,105 +1,105 @@
|
|
|
1
|
-
import { listToClass } from '@stack-spot/portal-theme'
|
|
2
|
-
import { Children, useMemo, useState } from 'react'
|
|
3
|
-
import { useCitricController } from '../context/hooks'
|
|
4
|
-
import { WithColorScheme } from '../types'
|
|
5
|
-
import { withRef } from '../utils/react'
|
|
6
|
-
import { CitricComponent } from './CitricComponent'
|
|
7
|
-
import { ProgressCircular } from './ProgressCircular'
|
|
8
|
-
|
|
9
|
-
export interface BaseButtonProps extends WithColorScheme {
|
|
10
|
-
/**
|
|
11
|
-
* - contained for buttons with background;
|
|
12
|
-
* - outlined for transparent buttons with borders;
|
|
13
|
-
* - text for buttons with no borders or background;
|
|
14
|
-
* - none for buttons with no borders, background, paddings or any state effect (e.g. hover).
|
|
15
|
-
* @default 'contained'
|
|
16
|
-
*/
|
|
17
|
-
appearance?: 'outlined' | 'text' | 'contained' | 'none',
|
|
18
|
-
/**
|
|
19
|
-
* Size of the button.
|
|
20
|
-
* @default 'md'
|
|
21
|
-
*/
|
|
22
|
-
size?: 'sm' | 'md' | 'lg',
|
|
23
|
-
/**
|
|
24
|
-
* Animated text to show on when the button is clicked.
|
|
25
|
-
*/
|
|
26
|
-
feedback?: string,
|
|
27
|
-
/**
|
|
28
|
-
* Whether or not to show a loading feedback instead of the button's content.
|
|
29
|
-
*
|
|
30
|
-
* Buttons in the loading state are also disabled.
|
|
31
|
-
*/
|
|
32
|
-
loading?: boolean,
|
|
33
|
-
/**
|
|
34
|
-
* Function to run when the button is clicked. If this function returns a promise, the button will automatically show a loading feedback
|
|
35
|
-
* until the promise completes.
|
|
36
|
-
*/
|
|
37
|
-
onClick?: (event: React.MouseEvent<HTMLButtonElement, MouseEvent>) => any,
|
|
38
|
-
/**
|
|
39
|
-
* Metadata for the general onClick event, set by the CitricController. Useful for creating analytics data.
|
|
40
|
-
*
|
|
41
|
-
* This only takes effect if there's a CitricController in React's context. The value of `metadata` is passed to the function
|
|
42
|
-
* `onClickButton` of the controller.
|
|
43
|
-
*
|
|
44
|
-
* @default false
|
|
45
|
-
*/
|
|
46
|
-
metadata?: any,
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
export type ButtonProps = Omit<React.JSX.IntrinsicElements['button'], 'onClick'> & BaseButtonProps
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* Renders a button. The type is "button" by default.
|
|
53
|
-
*
|
|
54
|
-
* Whenever a button is clicked, the function `onClickButton` of the nearest CitricController is called with the event and the value of the
|
|
55
|
-
* prop `metadata`.
|
|
56
|
-
*
|
|
57
|
-
* @example
|
|
58
|
-
* ```
|
|
59
|
-
* <Button>My Button</Button>
|
|
60
|
-
* ```
|
|
61
|
-
*/
|
|
62
|
-
export const Button = withRef((
|
|
63
|
-
{ appearance, size, feedback, loading, disabled, onClick, className, children, type = 'button', metadata, ...props }: ButtonProps,
|
|
64
|
-
) => {
|
|
65
|
-
const citric = useCitricController()
|
|
66
|
-
const [waiting, setWaiting] = useState(false)
|
|
67
|
-
const busy = loading || waiting
|
|
68
|
-
const isAllLowercase = useMemo(
|
|
69
|
-
() => !Children.toArray(children).some(c => typeof c === 'string' && c.toLocaleLowerCase() !== c),
|
|
70
|
-
[children],
|
|
71
|
-
)
|
|
72
|
-
|
|
73
|
-
async function handleClick(e: React.MouseEvent<HTMLButtonElement, MouseEvent>) {
|
|
74
|
-
const result = onClick?.(e)
|
|
75
|
-
citric?.onClickButton?.(e, metadata)
|
|
76
|
-
if (result instanceof Promise) {
|
|
77
|
-
setWaiting(true)
|
|
78
|
-
try {
|
|
79
|
-
await result
|
|
80
|
-
} catch { /* empty */ }
|
|
81
|
-
setWaiting(false)
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
return (
|
|
86
|
-
<CitricComponent
|
|
87
|
-
tag="button"
|
|
88
|
-
component="button"
|
|
89
|
-
className={listToClass([size, appearance, isAllLowercase && 'short-text', className])}
|
|
90
|
-
data-feedback={feedback || undefined}
|
|
91
|
-
onClick={handleClick}
|
|
92
|
-
aria-busy={busy}
|
|
93
|
-
disabled={disabled || busy}
|
|
94
|
-
type={type}
|
|
95
|
-
{...props}
|
|
96
|
-
>
|
|
97
|
-
{busy ? <div>{children}</div> : children}
|
|
98
|
-
{busy && (
|
|
99
|
-
<div className="loader">
|
|
100
|
-
<ProgressCircular size="sm" />
|
|
101
|
-
</div>
|
|
102
|
-
)}
|
|
103
|
-
</CitricComponent>
|
|
104
|
-
)
|
|
105
|
-
})
|
|
1
|
+
import { listToClass } from '@stack-spot/portal-theme'
|
|
2
|
+
import { Children, useMemo, useState } from 'react'
|
|
3
|
+
import { useCitricController } from '../context/hooks'
|
|
4
|
+
import { WithColorScheme } from '../types'
|
|
5
|
+
import { withRef } from '../utils/react'
|
|
6
|
+
import { CitricComponent } from './CitricComponent'
|
|
7
|
+
import { ProgressCircular } from './ProgressCircular'
|
|
8
|
+
|
|
9
|
+
export interface BaseButtonProps extends WithColorScheme {
|
|
10
|
+
/**
|
|
11
|
+
* - contained for buttons with background;
|
|
12
|
+
* - outlined for transparent buttons with borders;
|
|
13
|
+
* - text for buttons with no borders or background;
|
|
14
|
+
* - none for buttons with no borders, background, paddings or any state effect (e.g. hover).
|
|
15
|
+
* @default 'contained'
|
|
16
|
+
*/
|
|
17
|
+
appearance?: 'outlined' | 'text' | 'contained' | 'none',
|
|
18
|
+
/**
|
|
19
|
+
* Size of the button.
|
|
20
|
+
* @default 'md'
|
|
21
|
+
*/
|
|
22
|
+
size?: 'sm' | 'md' | 'lg',
|
|
23
|
+
/**
|
|
24
|
+
* Animated text to show on when the button is clicked.
|
|
25
|
+
*/
|
|
26
|
+
feedback?: string,
|
|
27
|
+
/**
|
|
28
|
+
* Whether or not to show a loading feedback instead of the button's content.
|
|
29
|
+
*
|
|
30
|
+
* Buttons in the loading state are also disabled.
|
|
31
|
+
*/
|
|
32
|
+
loading?: boolean,
|
|
33
|
+
/**
|
|
34
|
+
* Function to run when the button is clicked. If this function returns a promise, the button will automatically show a loading feedback
|
|
35
|
+
* until the promise completes.
|
|
36
|
+
*/
|
|
37
|
+
onClick?: (event: React.MouseEvent<HTMLButtonElement, MouseEvent>) => any,
|
|
38
|
+
/**
|
|
39
|
+
* Metadata for the general onClick event, set by the CitricController. Useful for creating analytics data.
|
|
40
|
+
*
|
|
41
|
+
* This only takes effect if there's a CitricController in React's context. The value of `metadata` is passed to the function
|
|
42
|
+
* `onClickButton` of the controller.
|
|
43
|
+
*
|
|
44
|
+
* @default false
|
|
45
|
+
*/
|
|
46
|
+
metadata?: any,
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export type ButtonProps = Omit<React.JSX.IntrinsicElements['button'], 'onClick'> & BaseButtonProps
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Renders a button. The type is "button" by default.
|
|
53
|
+
*
|
|
54
|
+
* Whenever a button is clicked, the function `onClickButton` of the nearest CitricController is called with the event and the value of the
|
|
55
|
+
* prop `metadata`.
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* ```
|
|
59
|
+
* <Button>My Button</Button>
|
|
60
|
+
* ```
|
|
61
|
+
*/
|
|
62
|
+
export const Button = withRef((
|
|
63
|
+
{ appearance, size, feedback, loading, disabled, onClick, className, children, type = 'button', metadata, ...props }: ButtonProps,
|
|
64
|
+
) => {
|
|
65
|
+
const citric = useCitricController()
|
|
66
|
+
const [waiting, setWaiting] = useState(false)
|
|
67
|
+
const busy = loading || waiting
|
|
68
|
+
const isAllLowercase = useMemo(
|
|
69
|
+
() => !Children.toArray(children).some(c => typeof c === 'string' && c.toLocaleLowerCase() !== c),
|
|
70
|
+
[children],
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
async function handleClick(e: React.MouseEvent<HTMLButtonElement, MouseEvent>) {
|
|
74
|
+
const result = onClick?.(e)
|
|
75
|
+
citric?.onClickButton?.(e, metadata)
|
|
76
|
+
if (result instanceof Promise) {
|
|
77
|
+
setWaiting(true)
|
|
78
|
+
try {
|
|
79
|
+
await result
|
|
80
|
+
} catch { /* empty */ }
|
|
81
|
+
setWaiting(false)
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return (
|
|
86
|
+
<CitricComponent
|
|
87
|
+
tag="button"
|
|
88
|
+
component="button"
|
|
89
|
+
className={listToClass([size, appearance, isAllLowercase && 'short-text', className])}
|
|
90
|
+
data-feedback={feedback || undefined}
|
|
91
|
+
onClick={handleClick}
|
|
92
|
+
aria-busy={busy}
|
|
93
|
+
disabled={disabled || busy}
|
|
94
|
+
type={type}
|
|
95
|
+
{...props}
|
|
96
|
+
>
|
|
97
|
+
{busy ? <div>{children}</div> : children}
|
|
98
|
+
{busy && (
|
|
99
|
+
<div className="loader">
|
|
100
|
+
<ProgressCircular size="sm" />
|
|
101
|
+
</div>
|
|
102
|
+
)}
|
|
103
|
+
</CitricComponent>
|
|
104
|
+
)
|
|
105
|
+
})
|
|
@@ -1,45 +1,45 @@
|
|
|
1
|
-
import { listToClass } from '@stack-spot/portal-theme'
|
|
2
|
-
import { Children, useMemo } from 'react'
|
|
3
|
-
import { useCitricController } from '../context/hooks'
|
|
4
|
-
import { withRef } from '../utils/react'
|
|
5
|
-
import { BaseButtonProps } from './Button'
|
|
6
|
-
import { asCitricProps, CitricComponent } from './CitricComponent'
|
|
7
|
-
|
|
8
|
-
export type BaseButtonLinkProps = Omit<BaseButtonProps, 'onClick' | 'loading' | 'type'>
|
|
9
|
-
export type ButtonLinkProps = React.JSX.IntrinsicElements['a'] & BaseButtonLinkProps
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Renders a link with the appearance of a button.
|
|
13
|
-
*
|
|
14
|
-
* Whenever a link is clicked, the function `onClickLink` of the nearest CitricController is called with the event and the value of the
|
|
15
|
-
* prop `metadata`.
|
|
16
|
-
*
|
|
17
|
-
* @example
|
|
18
|
-
* ```
|
|
19
|
-
* <ButtonLink href="#">My Button Link</ButtonLink>
|
|
20
|
-
* ```
|
|
21
|
-
*/
|
|
22
|
-
export const ButtonLink = withRef((
|
|
23
|
-
{ appearance, size, feedback, onClick, className, children, metadata, ...props }: ButtonLinkProps,
|
|
24
|
-
) => {
|
|
25
|
-
const citric = useCitricController()
|
|
26
|
-
const isAllLowercase = useMemo(
|
|
27
|
-
() => !Children.toArray(children).some(c => typeof c === 'string' && c.toLocaleLowerCase() !== c),
|
|
28
|
-
[children],
|
|
29
|
-
)
|
|
30
|
-
|
|
31
|
-
const linkProps = {
|
|
32
|
-
component: 'button',
|
|
33
|
-
className: listToClass([size, appearance, isAllLowercase && 'short-text', className]),
|
|
34
|
-
onClick: (e: React.MouseEvent<HTMLAnchorElement>) => {
|
|
35
|
-
onClick?.(e)
|
|
36
|
-
citric?.onClickLink?.(e, metadata)
|
|
37
|
-
},
|
|
38
|
-
'data-feedback': feedback || undefined,
|
|
39
|
-
...props,
|
|
40
|
-
} as const
|
|
41
|
-
|
|
42
|
-
return citric?.renderLink
|
|
43
|
-
? citric.renderLink(asCitricProps({ ...linkProps, children }))
|
|
44
|
-
: <CitricComponent tag="a" {...linkProps}>{children}</CitricComponent>
|
|
45
|
-
})
|
|
1
|
+
import { listToClass } from '@stack-spot/portal-theme'
|
|
2
|
+
import { Children, useMemo } from 'react'
|
|
3
|
+
import { useCitricController } from '../context/hooks'
|
|
4
|
+
import { withRef } from '../utils/react'
|
|
5
|
+
import { BaseButtonProps } from './Button'
|
|
6
|
+
import { asCitricProps, CitricComponent } from './CitricComponent'
|
|
7
|
+
|
|
8
|
+
export type BaseButtonLinkProps = Omit<BaseButtonProps, 'onClick' | 'loading' | 'type'>
|
|
9
|
+
export type ButtonLinkProps = React.JSX.IntrinsicElements['a'] & BaseButtonLinkProps
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Renders a link with the appearance of a button.
|
|
13
|
+
*
|
|
14
|
+
* Whenever a link is clicked, the function `onClickLink` of the nearest CitricController is called with the event and the value of the
|
|
15
|
+
* prop `metadata`.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```
|
|
19
|
+
* <ButtonLink href="#">My Button Link</ButtonLink>
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export const ButtonLink = withRef((
|
|
23
|
+
{ appearance, size, feedback, onClick, className, children, metadata, ...props }: ButtonLinkProps,
|
|
24
|
+
) => {
|
|
25
|
+
const citric = useCitricController()
|
|
26
|
+
const isAllLowercase = useMemo(
|
|
27
|
+
() => !Children.toArray(children).some(c => typeof c === 'string' && c.toLocaleLowerCase() !== c),
|
|
28
|
+
[children],
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
const linkProps = {
|
|
32
|
+
component: 'button',
|
|
33
|
+
className: listToClass([size, appearance, isAllLowercase && 'short-text', className]),
|
|
34
|
+
onClick: (e: React.MouseEvent<HTMLAnchorElement>) => {
|
|
35
|
+
onClick?.(e)
|
|
36
|
+
citric?.onClickLink?.(e, metadata)
|
|
37
|
+
},
|
|
38
|
+
'data-feedback': feedback || undefined,
|
|
39
|
+
...props,
|
|
40
|
+
} as const
|
|
41
|
+
|
|
42
|
+
return citric?.renderLink
|
|
43
|
+
? citric.renderLink(asCitricProps({ ...linkProps, children }))
|
|
44
|
+
: <CitricComponent tag="a" {...linkProps}>{children}</CitricComponent>
|
|
45
|
+
})
|