@saas-ui/react 2.11.2 → 3.0.0-alpha.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/CHANGELOG.md +7 -154
- package/dist/index.cjs +8461 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +26 -0
- package/dist/index.d.ts +25 -7
- package/dist/index.js +8415 -35
- package/dist/index.js.map +1 -1
- package/package.json +24 -21
- package/src/components/accordion.tsx +47 -0
- package/src/components/action-bar.tsx +40 -0
- package/src/components/alert.tsx +51 -0
- package/src/components/app-shell/app-shell.recipe.ts +52 -0
- package/src/components/app-shell/app-shell.stories.tsx +51 -0
- package/src/components/app-shell/app-shell.tsx +94 -0
- package/src/components/app-shell/index.ts +3 -0
- package/src/components/avatar.tsx +74 -0
- package/src/components/blockquote.tsx +31 -0
- package/src/components/breadcrumbs/breadcrumb.stories.tsx +17 -0
- package/src/components/breadcrumbs/breadcrumb.tsx +36 -0
- package/src/components/breadcrumbs/index.ts +1 -0
- package/src/components/breadcrumbs/namespace.ts +8 -0
- package/src/components/button/button.recipe.ts +182 -0
- package/src/components/button/button.stories.tsx +99 -0
- package/src/components/button/button.tsx +55 -0
- package/src/components/button/index.ts +2 -0
- package/src/components/checkbox/checkbox.tsx +26 -0
- package/src/components/checkbox/index.ts +2 -0
- package/src/components/checkbox-card.tsx +57 -0
- package/src/components/checkbox.tsx +25 -0
- package/src/components/clipboard.tsx +107 -0
- package/src/components/close-button/close-button.stories.tsx +12 -0
- package/src/components/close-button/close-button.tsx +18 -0
- package/src/components/close-button/index.ts +2 -0
- package/src/components/color-mode.tsx +65 -0
- package/src/components/command/command.recipe.ts +17 -0
- package/src/components/command/command.stories.tsx +47 -0
- package/src/components/command/command.tsx +50 -0
- package/src/components/command/index.ts +1 -0
- package/src/components/data-list.tsx +37 -0
- package/src/components/dialog/dialog.tsx +66 -0
- package/src/components/dialog/index.ts +1 -0
- package/src/components/dialog/namespace.ts +18 -0
- package/src/components/drawer/drawer.tsx +56 -0
- package/src/components/drawer/index.ts +3 -0
- package/src/components/drawer/namespace.ts +19 -0
- package/src/components/empty-state.tsx +34 -0
- package/src/components/field.tsx +33 -0
- package/src/components/file-button.tsx +166 -0
- package/src/components/grid-list/grid-list.recipe.ts +113 -0
- package/src/components/hover-card.tsx +35 -0
- package/src/components/icon-badge/icon-badge.recipe.ts +57 -0
- package/src/components/icon-badge/icon-badge.stories.tsx +38 -0
- package/src/components/icon-badge/icon-badge.tsx +59 -0
- package/src/components/icon-badge/index.ts +2 -0
- package/src/components/icons/create-icon.tsx +41 -0
- package/src/components/icons/icons.tsx +121 -0
- package/src/components/icons/index.ts +1 -0
- package/src/components/input-group/index.ts +1 -0
- package/src/components/input-group/input-group.tsx +46 -0
- package/src/components/link/index.ts +2 -0
- package/src/components/link/link.stories.tsx +17 -0
- package/src/components/link/link.test.tsx +33 -0
- package/src/components/link/link.tsx +27 -0
- package/src/components/link-button.tsx +12 -0
- package/src/components/loading-overlay/index.ts +1 -0
- package/src/components/loading-overlay/loading-overlay.recipe.ts +61 -0
- package/src/components/loading-overlay/loading-overlay.stories.tsx +68 -0
- package/src/components/loading-overlay/loading-overlay.tsx +54 -0
- package/src/components/loading-overlay/namespace.ts +7 -0
- package/src/components/menu.tsx +108 -0
- package/src/components/native-select.tsx +57 -0
- package/src/components/navbar/index.ts +1 -0
- package/src/components/navbar/namespace.ts +9 -0
- package/src/components/navbar/navbar.recipe.ts +109 -0
- package/src/components/navbar/navbar.stories.tsx +435 -0
- package/src/components/navbar/navbar.test.tsx +49 -0
- package/src/components/navbar/navbar.tsx +39 -0
- package/src/components/number-input/index.ts +2 -0
- package/src/components/number-input/number-input.tsx +41 -0
- package/src/components/pagination.tsx +207 -0
- package/src/components/password-input/index.ts +2 -0
- package/src/components/password-input/password-input.tsx +98 -0
- package/src/components/persona/index.ts +2 -0
- package/src/components/persona/namespace.ts +18 -0
- package/src/components/persona/persona-primitive.tsx +220 -0
- package/src/components/persona/persona.recipe.ts +94 -0
- package/src/components/persona/persona.stories.tsx +101 -0
- package/src/components/persona/persona.tsx +143 -0
- package/src/components/pin-input/index.ts +2 -0
- package/src/components/pin-input/pin-input.tsx +36 -0
- package/src/components/popover.tsx +58 -0
- package/src/components/progress-circle.tsx +37 -0
- package/src/components/progress.tsx +40 -0
- package/src/components/prose.tsx +264 -0
- package/src/components/provider.tsx +12 -0
- package/src/components/radio/index.ts +2 -0
- package/src/components/radio/radio.tsx +27 -0
- package/src/components/radio-card.tsx +57 -0
- package/src/components/radio.tsx +24 -0
- package/src/components/rating.tsx +27 -0
- package/src/components/search-input/index.ts +2 -0
- package/src/components/search-input/search-input.stories.tsx +63 -0
- package/src/components/search-input/search-input.tsx +134 -0
- package/src/components/segmented-control.tsx +47 -0
- package/src/components/select/index.ts +1 -0
- package/src/components/select/namespace.ts +18 -0
- package/src/components/select/select.tsx +135 -0
- package/src/components/sidebar/index.ts +7 -0
- package/src/components/sidebar/namespace.ts +27 -0
- package/src/components/sidebar/sidebar-item.recipe.ts +65 -0
- package/src/components/sidebar/sidebar.recipe.ts +237 -0
- package/src/components/sidebar/sidebar.stories.tsx +903 -0
- package/src/components/sidebar/sidebar.tsx +204 -0
- package/src/components/skeleton.tsx +44 -0
- package/src/components/slider.tsx +53 -0
- package/src/components/spinner/index.ts +2 -0
- package/src/components/spinner/spinner.stories.tsx +19 -0
- package/src/components/spinner/spinner.tsx +21 -0
- package/src/components/stat.tsx +75 -0
- package/src/components/status.tsx +29 -0
- package/src/components/stepper-input.tsx +49 -0
- package/src/components/steps/index.ts +1 -0
- package/src/components/steps/namespace.ts +16 -0
- package/src/components/steps/steps.tsx +82 -0
- package/src/components/switch/index.ts +3 -0
- package/src/components/switch/switch.tsx +39 -0
- package/src/components/tag.tsx +39 -0
- package/src/components/timeline.tsx +17 -0
- package/src/components/toaster.tsx +43 -0
- package/src/components/toggle-tip.tsx +62 -0
- package/src/components/tooltip.tsx +46 -0
- package/src/index.ts +6 -7
- package/src/preset.ts +9 -0
- package/src/provider/index.ts +4 -0
- package/src/provider/sui-provider.tsx +34 -0
- package/src/provider/use-link.test.tsx +60 -0
- package/src/provider/use-link.tsx +13 -0
- package/src/theme/animation-styles.ts +53 -0
- package/src/theme/breakpoints.ts +11 -0
- package/src/theme/conditions.ts +26 -0
- package/src/theme/fluid-font-sizes.ts +65 -0
- package/src/theme/global-css.ts +94 -0
- package/src/theme/index.ts +72 -0
- package/src/theme/layer-styles.ts +116 -0
- package/src/theme/recipes/chakra/accordion.ts +145 -0
- package/src/theme/recipes/chakra/action-bar.ts +62 -0
- package/src/theme/recipes/chakra/alert.ts +157 -0
- package/src/theme/recipes/chakra/avatar.ts +141 -0
- package/src/theme/recipes/chakra/badge.ts +67 -0
- package/src/theme/recipes/chakra/blockquote.ts +83 -0
- package/src/theme/recipes/chakra/breadcrumb.ts +94 -0
- package/src/theme/recipes/chakra/card.ts +99 -0
- package/src/theme/recipes/chakra/checkbox-card.ts +212 -0
- package/src/theme/recipes/chakra/checkbox.ts +70 -0
- package/src/theme/recipes/chakra/checkmark.ts +83 -0
- package/src/theme/recipes/chakra/code.ts +17 -0
- package/src/theme/recipes/chakra/collapsible.ts +20 -0
- package/src/theme/recipes/chakra/container.ts +26 -0
- package/src/theme/recipes/chakra/data-list.ts +80 -0
- package/src/theme/recipes/chakra/dialog.ts +225 -0
- package/src/theme/recipes/chakra/drawer.ts +201 -0
- package/src/theme/recipes/chakra/editable.ts +88 -0
- package/src/theme/recipes/chakra/empty-state.ts +88 -0
- package/src/theme/recipes/chakra/field.ts +68 -0
- package/src/theme/recipes/chakra/fieldset.ts +62 -0
- package/src/theme/recipes/chakra/file-upload.ts +96 -0
- package/src/theme/recipes/chakra/heading.ts +27 -0
- package/src/theme/recipes/chakra/hover-card.ts +68 -0
- package/src/theme/recipes/chakra/icon.ts +30 -0
- package/src/theme/recipes/chakra/input-addon.ts +40 -0
- package/src/theme/recipes/chakra/input.ts +96 -0
- package/src/theme/recipes/chakra/kbd.ts +60 -0
- package/src/theme/recipes/chakra/link.ts +37 -0
- package/src/theme/recipes/chakra/list.ts +67 -0
- package/src/theme/recipes/chakra/mark.ts +27 -0
- package/src/theme/recipes/chakra/menu.ts +124 -0
- package/src/theme/recipes/chakra/native-select.ts +140 -0
- package/src/theme/recipes/chakra/number-input.ts +115 -0
- package/src/theme/recipes/chakra/pin-input.ts +27 -0
- package/src/theme/recipes/chakra/popover.ts +86 -0
- package/src/theme/recipes/chakra/progress-circle.ts +94 -0
- package/src/theme/recipes/chakra/progress.ts +127 -0
- package/src/theme/recipes/chakra/radio-card.ts +220 -0
- package/src/theme/recipes/chakra/radio-group.ts +72 -0
- package/src/theme/recipes/chakra/radiomark.ts +107 -0
- package/src/theme/recipes/chakra/rating-group.ts +94 -0
- package/src/theme/recipes/chakra/segment-group.ts +117 -0
- package/src/theme/recipes/chakra/select.ts +282 -0
- package/src/theme/recipes/chakra/separator.ts +51 -0
- package/src/theme/recipes/chakra/skeleton.ts +53 -0
- package/src/theme/recipes/chakra/skip-nav-link.ts +34 -0
- package/src/theme/recipes/chakra/slider.ts +178 -0
- package/src/theme/recipes/chakra/spinner.ts +32 -0
- package/src/theme/recipes/chakra/stat.ts +79 -0
- package/src/theme/recipes/chakra/status.ts +48 -0
- package/src/theme/recipes/chakra/steps.ts +218 -0
- package/src/theme/recipes/chakra/switch.ts +167 -0
- package/src/theme/recipes/chakra/table.ts +172 -0
- package/src/theme/recipes/chakra/tabs.ts +280 -0
- package/src/theme/recipes/chakra/tag.ts +131 -0
- package/src/theme/recipes/chakra/textarea.ts +88 -0
- package/src/theme/recipes/chakra/timeline.ts +138 -0
- package/src/theme/recipes/chakra/toast.ts +96 -0
- package/src/theme/recipes/chakra/tooltip.ts +40 -0
- package/src/theme/recipes.ts +46 -0
- package/src/theme/semantic-tokens/colors.ts +403 -0
- package/src/theme/semantic-tokens/radii.ts +7 -0
- package/src/theme/semantic-tokens/shadows.ts +52 -0
- package/src/theme/slot-recipes.ts +104 -0
- package/src/theme/text-styles.ts +39 -0
- package/src/theme/tokens/animations.ts +8 -0
- package/src/theme/tokens/aspect-ratios.ts +10 -0
- package/src/theme/tokens/blurs.ts +12 -0
- package/src/theme/tokens/borders.ts +9 -0
- package/src/theme/tokens/colors.ts +177 -0
- package/src/theme/tokens/cursor.ts +12 -0
- package/src/theme/tokens/durations.ts +11 -0
- package/src/theme/tokens/easings.ts +10 -0
- package/src/theme/tokens/font-sizes.ts +20 -0
- package/src/theme/tokens/font-weights.ts +13 -0
- package/src/theme/tokens/fonts.ts +15 -0
- package/src/theme/tokens/keyframes.ts +173 -0
- package/src/theme/tokens/letter-spacing.ts +9 -0
- package/src/theme/tokens/line-heights.ts +19 -0
- package/src/theme/tokens/radius.ts +18 -0
- package/src/theme/tokens/sizes.ts +71 -0
- package/src/theme/tokens/spacing.ts +38 -0
- package/src/theme/tokens/z-indices.ts +34 -0
- package/src/theme/utils.ts +46 -0
- package/dist/index.d.mts +0 -8
- package/dist/index.mjs +0 -11
- package/dist/index.mjs.map +0 -1
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
|
|
3
|
+
import { Button, Center, Tooltip, VStack } from '@chakra-ui/react'
|
|
4
|
+
|
|
5
|
+
import { Command } from './command'
|
|
6
|
+
|
|
7
|
+
export default {
|
|
8
|
+
title: 'Components/Command',
|
|
9
|
+
decorators: [
|
|
10
|
+
(Story: any) => (
|
|
11
|
+
<Center height="100%">
|
|
12
|
+
<Story />
|
|
13
|
+
</Center>
|
|
14
|
+
),
|
|
15
|
+
],
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export const Basic = {
|
|
19
|
+
render: () => (
|
|
20
|
+
<VStack>
|
|
21
|
+
<Command>shift+X</Command>
|
|
22
|
+
<Command>A then B</Command>
|
|
23
|
+
<Command>alt or option</Command>
|
|
24
|
+
</VStack>
|
|
25
|
+
),
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export const TooltipCommand = {
|
|
29
|
+
render: () => (
|
|
30
|
+
<Tooltip.Root>
|
|
31
|
+
<Tooltip.Trigger>
|
|
32
|
+
<Button>Inbox</Button>
|
|
33
|
+
</Tooltip.Trigger>
|
|
34
|
+
<Tooltip.Positioner>
|
|
35
|
+
<Tooltip.Content>
|
|
36
|
+
<Tooltip.Arrow>
|
|
37
|
+
<Tooltip.ArrowTip />
|
|
38
|
+
</Tooltip.Arrow>
|
|
39
|
+
|
|
40
|
+
<>
|
|
41
|
+
Inbox <Command>G then I</Command>
|
|
42
|
+
</>
|
|
43
|
+
</Tooltip.Content>
|
|
44
|
+
</Tooltip.Positioner>
|
|
45
|
+
</Tooltip.Root>
|
|
46
|
+
),
|
|
47
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import * as React from 'react'
|
|
2
|
+
|
|
3
|
+
import { Kbd } from '@chakra-ui/react'
|
|
4
|
+
import {
|
|
5
|
+
type HTMLChakraProps,
|
|
6
|
+
type RecipeProps,
|
|
7
|
+
UnstyledProp,
|
|
8
|
+
createRecipeContext,
|
|
9
|
+
} from '@chakra-ui/react'
|
|
10
|
+
|
|
11
|
+
const { withContext } = createRecipeContext({
|
|
12
|
+
key: 'command',
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
export interface CommandBaseProps extends RecipeProps<'span'>, UnstyledProp {}
|
|
16
|
+
|
|
17
|
+
export interface CommandProps
|
|
18
|
+
extends HTMLChakraProps<'span', CommandBaseProps> {}
|
|
19
|
+
|
|
20
|
+
const Key: React.FC<HTMLChakraProps<'span'>> = ({ children }) => {
|
|
21
|
+
if (typeof children !== 'string') {
|
|
22
|
+
return <>{children}</>
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if (['then', 'or', '+'].includes(children)) {
|
|
26
|
+
return <span>{children}</span>
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return <Kbd>{children}</Kbd>
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export const Command: React.FC<HTMLChakraProps<'span'>> = (props) => {
|
|
33
|
+
const { children, ...rest } = props
|
|
34
|
+
|
|
35
|
+
if (typeof children !== 'string') {
|
|
36
|
+
return <>{children}</>
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const keys = children.split(/\s|\+/)
|
|
40
|
+
|
|
41
|
+
return (
|
|
42
|
+
<CommandRoot {...rest}>
|
|
43
|
+
{keys.map((key) => (
|
|
44
|
+
<Key key={key}>{key}</Key>
|
|
45
|
+
))}
|
|
46
|
+
</CommandRoot>
|
|
47
|
+
)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const CommandRoot = withContext('span')
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Command } from './command'
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { DataList as ChakraDataList, IconButton } from "@chakra-ui/react"
|
|
2
|
+
import { ToggleTip } from "compositions/ui/toggle-tip"
|
|
3
|
+
import { forwardRef } from "react"
|
|
4
|
+
import { HiOutlineInformationCircle } from "react-icons/hi2"
|
|
5
|
+
|
|
6
|
+
export const DataListRoot = ChakraDataList.Root
|
|
7
|
+
|
|
8
|
+
interface ItemProps extends ChakraDataList.ItemProps {
|
|
9
|
+
label: React.ReactNode
|
|
10
|
+
value: React.ReactNode
|
|
11
|
+
info?: React.ReactNode
|
|
12
|
+
grow?: boolean
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export const DataListItem = forwardRef<HTMLDivElement, ItemProps>(
|
|
16
|
+
function DataListItem(props, ref) {
|
|
17
|
+
const { label, info, value, children, grow, ...rest } = props
|
|
18
|
+
return (
|
|
19
|
+
<ChakraDataList.Item ref={ref} {...rest}>
|
|
20
|
+
<ChakraDataList.ItemLabel flex={grow ? "1" : undefined}>
|
|
21
|
+
{label}
|
|
22
|
+
{info && (
|
|
23
|
+
<ToggleTip content={info}>
|
|
24
|
+
<IconButton variant="ghost" aria-label="info" size="2xs">
|
|
25
|
+
<HiOutlineInformationCircle />
|
|
26
|
+
</IconButton>
|
|
27
|
+
</ToggleTip>
|
|
28
|
+
)}
|
|
29
|
+
</ChakraDataList.ItemLabel>
|
|
30
|
+
<ChakraDataList.ItemValue flex={grow ? "1" : undefined}>
|
|
31
|
+
{value}
|
|
32
|
+
</ChakraDataList.ItemValue>
|
|
33
|
+
{children}
|
|
34
|
+
</ChakraDataList.Item>
|
|
35
|
+
)
|
|
36
|
+
},
|
|
37
|
+
)
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { forwardRef } from 'react'
|
|
2
|
+
|
|
3
|
+
import { Dialog as ChakraDialog, Portal } from '@chakra-ui/react'
|
|
4
|
+
|
|
5
|
+
import { CloseButton } from '#components/close-button'
|
|
6
|
+
|
|
7
|
+
export interface DialogContentProps extends ChakraDialog.ContentProps {
|
|
8
|
+
portalled?: boolean
|
|
9
|
+
portalRef?: React.RefObject<HTMLElement>
|
|
10
|
+
backdrop?: boolean
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export const DialogContent = forwardRef<HTMLDivElement, DialogContentProps>(
|
|
14
|
+
function DialogContent(props, ref) {
|
|
15
|
+
const {
|
|
16
|
+
children,
|
|
17
|
+
portalled = true,
|
|
18
|
+
portalRef,
|
|
19
|
+
backdrop = true,
|
|
20
|
+
...rest
|
|
21
|
+
} = props
|
|
22
|
+
|
|
23
|
+
return (
|
|
24
|
+
<Portal disabled={!portalled} container={portalRef}>
|
|
25
|
+
{backdrop && <ChakraDialog.Backdrop />}
|
|
26
|
+
<ChakraDialog.Positioner>
|
|
27
|
+
<ChakraDialog.Content ref={ref} {...rest} asChild={false}>
|
|
28
|
+
{children}
|
|
29
|
+
</ChakraDialog.Content>
|
|
30
|
+
</ChakraDialog.Positioner>
|
|
31
|
+
</Portal>
|
|
32
|
+
)
|
|
33
|
+
},
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
export const DialogCloseTrigger = forwardRef<
|
|
37
|
+
HTMLButtonElement,
|
|
38
|
+
ChakraDialog.CloseTriggerProps
|
|
39
|
+
>(function DialogCloseTrigger(props, ref) {
|
|
40
|
+
return (
|
|
41
|
+
<ChakraDialog.CloseTrigger
|
|
42
|
+
position="absolute"
|
|
43
|
+
top="2"
|
|
44
|
+
insetEnd="2"
|
|
45
|
+
{...props}
|
|
46
|
+
asChild
|
|
47
|
+
>
|
|
48
|
+
<CloseButton size="sm" ref={ref}>
|
|
49
|
+
{props.children}
|
|
50
|
+
</CloseButton>
|
|
51
|
+
</ChakraDialog.CloseTrigger>
|
|
52
|
+
)
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
export type DialogRootProps = ChakraDialog.RootProps
|
|
56
|
+
|
|
57
|
+
export const DialogRoot = ChakraDialog.Root
|
|
58
|
+
export const DialogFooter = ChakraDialog.Footer
|
|
59
|
+
export const DialogHeader = ChakraDialog.Header
|
|
60
|
+
export const DialogBody = ChakraDialog.Body
|
|
61
|
+
export const DialogBackdrop = ChakraDialog.Backdrop
|
|
62
|
+
export const DialogTitle = ChakraDialog.Title
|
|
63
|
+
export const DialogDescription = ChakraDialog.Description
|
|
64
|
+
export const DialogTrigger = ChakraDialog.Trigger
|
|
65
|
+
export const DialogActionTrigger = ChakraDialog.ActionTrigger
|
|
66
|
+
export const DialogContext = ChakraDialog.Context
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * as Dialog from './namespace.ts'
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export {
|
|
2
|
+
DialogRoot as Root,
|
|
3
|
+
DialogContent as Content,
|
|
4
|
+
DialogCloseTrigger as CloseTrigger,
|
|
5
|
+
DialogHeader as Header,
|
|
6
|
+
DialogBody as Body,
|
|
7
|
+
DialogFooter as Footer,
|
|
8
|
+
DialogActionTrigger as ActionTrigger,
|
|
9
|
+
DialogBackdrop as Backdrop,
|
|
10
|
+
DialogDescription as Description,
|
|
11
|
+
DialogTitle as Title,
|
|
12
|
+
DialogTrigger as Trigger,
|
|
13
|
+
DialogContext as Context,
|
|
14
|
+
} from './dialog.tsx'
|
|
15
|
+
export type {
|
|
16
|
+
DialogContentProps as ContentProps,
|
|
17
|
+
DialogRootProps as RootProps,
|
|
18
|
+
} from './dialog.tsx'
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { forwardRef } from 'react'
|
|
2
|
+
|
|
3
|
+
import { Drawer as ChakraDrawer, Portal } from '@chakra-ui/react'
|
|
4
|
+
|
|
5
|
+
import { CloseButton } from '#components/close-button'
|
|
6
|
+
|
|
7
|
+
export interface DrawerContentProps extends ChakraDrawer.ContentProps {
|
|
8
|
+
portalled?: boolean
|
|
9
|
+
portalRef?: React.RefObject<HTMLElement>
|
|
10
|
+
offset?: ChakraDrawer.ContentProps['padding']
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export const DrawerContent = forwardRef<HTMLDivElement, DrawerContentProps>(
|
|
14
|
+
function DrawerContent(props, ref) {
|
|
15
|
+
const { children, portalled = true, portalRef, offset, ...rest } = props
|
|
16
|
+
return (
|
|
17
|
+
<Portal disabled={!portalled} container={portalRef}>
|
|
18
|
+
<ChakraDrawer.Positioner padding={offset}>
|
|
19
|
+
<ChakraDrawer.Content ref={ref} {...rest} asChild={false}>
|
|
20
|
+
{children}
|
|
21
|
+
</ChakraDrawer.Content>
|
|
22
|
+
</ChakraDrawer.Positioner>
|
|
23
|
+
</Portal>
|
|
24
|
+
)
|
|
25
|
+
},
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
export const DrawerCloseTrigger = forwardRef<
|
|
29
|
+
HTMLButtonElement,
|
|
30
|
+
ChakraDrawer.CloseTriggerProps
|
|
31
|
+
>(function DrawerCloseTrigger(props, ref) {
|
|
32
|
+
return (
|
|
33
|
+
<ChakraDrawer.CloseTrigger
|
|
34
|
+
position="absolute"
|
|
35
|
+
top="2"
|
|
36
|
+
insetEnd="2"
|
|
37
|
+
{...props}
|
|
38
|
+
asChild
|
|
39
|
+
>
|
|
40
|
+
<CloseButton size="sm" ref={ref} />
|
|
41
|
+
</ChakraDrawer.CloseTrigger>
|
|
42
|
+
)
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
export const DrawerTrigger = ChakraDrawer.Trigger
|
|
46
|
+
export const DrawerRoot = ChakraDrawer.Root
|
|
47
|
+
export const DrawerFooter = ChakraDrawer.Footer
|
|
48
|
+
export const DrawerHeader = ChakraDrawer.Header
|
|
49
|
+
export const DrawerBody = ChakraDrawer.Body
|
|
50
|
+
export const DrawerBackdrop = ChakraDrawer.Backdrop
|
|
51
|
+
export const DrawerDescription = ChakraDrawer.Description
|
|
52
|
+
export const DrawerTitle = ChakraDrawer.Title
|
|
53
|
+
export const DrawerActionTrigger = ChakraDrawer.ActionTrigger
|
|
54
|
+
export const DrawerContext = ChakraDrawer.Context
|
|
55
|
+
|
|
56
|
+
export type DrawerRootProps = ChakraDrawer.RootProps
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export {
|
|
2
|
+
DrawerRoot as Root,
|
|
3
|
+
DrawerContent as Content,
|
|
4
|
+
DrawerCloseTrigger as CloseTrigger,
|
|
5
|
+
DrawerHeader as Header,
|
|
6
|
+
DrawerBody as Body,
|
|
7
|
+
DrawerFooter as Footer,
|
|
8
|
+
DrawerActionTrigger as ActionTrigger,
|
|
9
|
+
DrawerBackdrop as Backdrop,
|
|
10
|
+
DrawerDescription as Description,
|
|
11
|
+
DrawerTitle as Title,
|
|
12
|
+
DrawerTrigger as Trigger,
|
|
13
|
+
DrawerContext as Context,
|
|
14
|
+
} from './drawer.tsx'
|
|
15
|
+
|
|
16
|
+
export type {
|
|
17
|
+
DrawerContentProps as ContentProps,
|
|
18
|
+
DrawerRootProps as RootProps,
|
|
19
|
+
} from './drawer.tsx'
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { EmptyState as ChakraEmptyState, VStack } from "@chakra-ui/react"
|
|
2
|
+
import { forwardRef } from "react"
|
|
3
|
+
|
|
4
|
+
export interface EmptyStateProps extends ChakraEmptyState.RootProps {
|
|
5
|
+
title: string
|
|
6
|
+
description?: string
|
|
7
|
+
icon?: React.ReactNode
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export const EmptyState = forwardRef<HTMLDivElement, EmptyStateProps>(
|
|
11
|
+
function EmptyState(props, ref) {
|
|
12
|
+
const { title, description, icon, children, ...rest } = props
|
|
13
|
+
return (
|
|
14
|
+
<ChakraEmptyState.Root ref={ref} {...rest}>
|
|
15
|
+
<ChakraEmptyState.Content>
|
|
16
|
+
{icon && (
|
|
17
|
+
<ChakraEmptyState.Indicator>{icon}</ChakraEmptyState.Indicator>
|
|
18
|
+
)}
|
|
19
|
+
{description ? (
|
|
20
|
+
<VStack textAlign="center">
|
|
21
|
+
<ChakraEmptyState.Title>{title}</ChakraEmptyState.Title>
|
|
22
|
+
<ChakraEmptyState.Description>
|
|
23
|
+
{description}
|
|
24
|
+
</ChakraEmptyState.Description>
|
|
25
|
+
</VStack>
|
|
26
|
+
) : (
|
|
27
|
+
<ChakraEmptyState.Title>{title}</ChakraEmptyState.Title>
|
|
28
|
+
)}
|
|
29
|
+
{children}
|
|
30
|
+
</ChakraEmptyState.Content>
|
|
31
|
+
</ChakraEmptyState.Root>
|
|
32
|
+
)
|
|
33
|
+
},
|
|
34
|
+
)
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { Field as ChakraField } from "@chakra-ui/react"
|
|
2
|
+
import { forwardRef } from "react"
|
|
3
|
+
|
|
4
|
+
export interface FieldProps extends Omit<ChakraField.RootProps, "label"> {
|
|
5
|
+
label?: React.ReactNode
|
|
6
|
+
helperText?: React.ReactNode
|
|
7
|
+
errorText?: React.ReactNode
|
|
8
|
+
optionalText?: React.ReactNode
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export const Field = forwardRef<HTMLDivElement, FieldProps>(
|
|
12
|
+
function Field(props, ref) {
|
|
13
|
+
const { label, children, helperText, errorText, optionalText, ...rest } =
|
|
14
|
+
props
|
|
15
|
+
return (
|
|
16
|
+
<ChakraField.Root ref={ref} {...rest}>
|
|
17
|
+
{label && (
|
|
18
|
+
<ChakraField.Label>
|
|
19
|
+
{label}
|
|
20
|
+
<ChakraField.RequiredIndicator fallback={optionalText} />
|
|
21
|
+
</ChakraField.Label>
|
|
22
|
+
)}
|
|
23
|
+
{children}
|
|
24
|
+
{helperText && (
|
|
25
|
+
<ChakraField.HelperText>{helperText}</ChakraField.HelperText>
|
|
26
|
+
)}
|
|
27
|
+
{errorText && (
|
|
28
|
+
<ChakraField.ErrorText>{errorText}</ChakraField.ErrorText>
|
|
29
|
+
)}
|
|
30
|
+
</ChakraField.Root>
|
|
31
|
+
)
|
|
32
|
+
},
|
|
33
|
+
)
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import type { ButtonProps, RecipeProps } from "@chakra-ui/react"
|
|
4
|
+
import {
|
|
5
|
+
Button,
|
|
6
|
+
FileUpload as ChakraFileUpload,
|
|
7
|
+
Icon,
|
|
8
|
+
IconButton,
|
|
9
|
+
Span,
|
|
10
|
+
Text,
|
|
11
|
+
useFileUploadContext,
|
|
12
|
+
useRecipe,
|
|
13
|
+
} from "@chakra-ui/react"
|
|
14
|
+
import { forwardRef } from "react"
|
|
15
|
+
import { LuFile, LuUpload, LuX } from "react-icons/lu"
|
|
16
|
+
|
|
17
|
+
export interface FileUploadRootProps extends ChakraFileUpload.RootProps {
|
|
18
|
+
inputProps?: React.InputHTMLAttributes<HTMLInputElement>
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export const FileUploadRoot = forwardRef<HTMLInputElement, FileUploadRootProps>(
|
|
22
|
+
function FileUploadRoot(props, ref) {
|
|
23
|
+
const { children, inputProps, ...rest } = props
|
|
24
|
+
return (
|
|
25
|
+
<ChakraFileUpload.Root {...rest}>
|
|
26
|
+
<ChakraFileUpload.HiddenInput ref={ref} {...inputProps} />
|
|
27
|
+
{children}
|
|
28
|
+
</ChakraFileUpload.Root>
|
|
29
|
+
)
|
|
30
|
+
},
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
export interface FileUploadDropzoneProps
|
|
34
|
+
extends ChakraFileUpload.DropzoneProps {
|
|
35
|
+
label: React.ReactNode
|
|
36
|
+
description?: React.ReactNode
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export const FileUploadDropzone = forwardRef<
|
|
40
|
+
HTMLInputElement,
|
|
41
|
+
FileUploadDropzoneProps
|
|
42
|
+
>(function FileUploadDropzone(props, ref) {
|
|
43
|
+
const { children, label, description, ...rest } = props
|
|
44
|
+
return (
|
|
45
|
+
<ChakraFileUpload.Dropzone ref={ref} {...rest}>
|
|
46
|
+
<Icon fontSize="xl" color="fg.muted">
|
|
47
|
+
<LuUpload />
|
|
48
|
+
</Icon>
|
|
49
|
+
<ChakraFileUpload.DropzoneContent>
|
|
50
|
+
<div>{label}</div>
|
|
51
|
+
{description && <Text color="fg.muted">{description}</Text>}
|
|
52
|
+
</ChakraFileUpload.DropzoneContent>
|
|
53
|
+
{children}
|
|
54
|
+
</ChakraFileUpload.Dropzone>
|
|
55
|
+
)
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
interface VisibilityProps {
|
|
59
|
+
showSize?: boolean
|
|
60
|
+
clearable?: boolean
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
interface FileUploadItemProps extends VisibilityProps {
|
|
64
|
+
file: File
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const FileUploadItem = (props: FileUploadItemProps) => {
|
|
68
|
+
const { file, showSize, clearable } = props
|
|
69
|
+
return (
|
|
70
|
+
<ChakraFileUpload.Item file={file}>
|
|
71
|
+
<ChakraFileUpload.ItemPreview asChild>
|
|
72
|
+
<Icon fontSize="lg" color="fg.muted">
|
|
73
|
+
<LuFile />
|
|
74
|
+
</Icon>
|
|
75
|
+
</ChakraFileUpload.ItemPreview>
|
|
76
|
+
|
|
77
|
+
{showSize ? (
|
|
78
|
+
<ChakraFileUpload.ItemContent>
|
|
79
|
+
<ChakraFileUpload.ItemName />
|
|
80
|
+
<ChakraFileUpload.ItemSizeText />
|
|
81
|
+
</ChakraFileUpload.ItemContent>
|
|
82
|
+
) : (
|
|
83
|
+
<ChakraFileUpload.ItemName flex="1" />
|
|
84
|
+
)}
|
|
85
|
+
|
|
86
|
+
{clearable && (
|
|
87
|
+
<ChakraFileUpload.ItemDeleteTrigger asChild>
|
|
88
|
+
<IconButton variant="ghost" color="fg.muted" size="xs">
|
|
89
|
+
<LuX />
|
|
90
|
+
</IconButton>
|
|
91
|
+
</ChakraFileUpload.ItemDeleteTrigger>
|
|
92
|
+
)}
|
|
93
|
+
</ChakraFileUpload.Item>
|
|
94
|
+
)
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
interface FileUploadListProps
|
|
98
|
+
extends VisibilityProps,
|
|
99
|
+
ChakraFileUpload.ItemGroupProps {
|
|
100
|
+
files?: File[]
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export const FileUploadList = forwardRef<HTMLUListElement, FileUploadListProps>(
|
|
104
|
+
function FileUploadList(props, ref) {
|
|
105
|
+
const { showSize, clearable, files, ...rest } = props
|
|
106
|
+
|
|
107
|
+
const fileUpload = useFileUploadContext()
|
|
108
|
+
const acceptedFiles = files ?? fileUpload.acceptedFiles
|
|
109
|
+
|
|
110
|
+
if (acceptedFiles.length === 0) return null
|
|
111
|
+
|
|
112
|
+
return (
|
|
113
|
+
<ChakraFileUpload.ItemGroup ref={ref} {...rest}>
|
|
114
|
+
{acceptedFiles.map((file) => (
|
|
115
|
+
<FileUploadItem
|
|
116
|
+
key={file.name}
|
|
117
|
+
file={file}
|
|
118
|
+
showSize={showSize}
|
|
119
|
+
clearable={clearable}
|
|
120
|
+
/>
|
|
121
|
+
))}
|
|
122
|
+
</ChakraFileUpload.ItemGroup>
|
|
123
|
+
)
|
|
124
|
+
},
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
type Assign<T, U> = Omit<T, keyof U> & U
|
|
128
|
+
|
|
129
|
+
interface FileInputProps extends Assign<ButtonProps, RecipeProps<"input">> {
|
|
130
|
+
placeholder?: React.ReactNode
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
export const FileInput = forwardRef<HTMLButtonElement, FileInputProps>(
|
|
134
|
+
function FileInput(props, ref) {
|
|
135
|
+
const inputRecipe = useRecipe({ key: "input" })
|
|
136
|
+
const [recipeProps, restProps] = inputRecipe.splitVariantProps(props)
|
|
137
|
+
const { placeholder = "Select file(s)", ...rest } = restProps
|
|
138
|
+
return (
|
|
139
|
+
<ChakraFileUpload.Trigger asChild>
|
|
140
|
+
<Button
|
|
141
|
+
unstyled
|
|
142
|
+
py="0"
|
|
143
|
+
ref={ref}
|
|
144
|
+
{...rest}
|
|
145
|
+
css={[inputRecipe(recipeProps), props.css]}
|
|
146
|
+
>
|
|
147
|
+
<ChakraFileUpload.Context>
|
|
148
|
+
{({ acceptedFiles }) => {
|
|
149
|
+
if (acceptedFiles.length === 1) {
|
|
150
|
+
return <span>{acceptedFiles[0].name}</span>
|
|
151
|
+
}
|
|
152
|
+
if (acceptedFiles.length > 1) {
|
|
153
|
+
return <span>{acceptedFiles.length} files</span>
|
|
154
|
+
}
|
|
155
|
+
return <Span color="fg.subtle">{placeholder}</Span>
|
|
156
|
+
}}
|
|
157
|
+
</ChakraFileUpload.Context>
|
|
158
|
+
</Button>
|
|
159
|
+
</ChakraFileUpload.Trigger>
|
|
160
|
+
)
|
|
161
|
+
},
|
|
162
|
+
)
|
|
163
|
+
|
|
164
|
+
export const FileUploadLabel = ChakraFileUpload.Label
|
|
165
|
+
export const FileUploadClearTrigger = ChakraFileUpload.ClearTrigger
|
|
166
|
+
export const FileUploadTrigger = ChakraFileUpload.Trigger
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { defineSlotRecipe } from '@chakra-ui/react'
|
|
2
|
+
|
|
3
|
+
export const gridListSlotRecipe = defineSlotRecipe({
|
|
4
|
+
className: 'sui-grid-list',
|
|
5
|
+
slots: ['root', 'item', 'header', 'icon'],
|
|
6
|
+
base: {
|
|
7
|
+
root: {
|
|
8
|
+
py: 2,
|
|
9
|
+
position: 'relative',
|
|
10
|
+
},
|
|
11
|
+
item: {
|
|
12
|
+
display: 'flex',
|
|
13
|
+
flexDirection: 'row',
|
|
14
|
+
alignItems: 'center',
|
|
15
|
+
justifyContent: 'space-between',
|
|
16
|
+
flex: 1,
|
|
17
|
+
cursor: 'pointer',
|
|
18
|
+
userSelect: 'none',
|
|
19
|
+
transitionProperty: 'common',
|
|
20
|
+
transitionDuration: 'normal',
|
|
21
|
+
borderRadius: 'inherit',
|
|
22
|
+
outline: 'none',
|
|
23
|
+
_hover: {
|
|
24
|
+
bg: 'blackAlpha.50',
|
|
25
|
+
_dark: {
|
|
26
|
+
bg: 'whiteAlpha.50',
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
_focusVisible: {
|
|
30
|
+
boxShadow: 'outline',
|
|
31
|
+
},
|
|
32
|
+
_focus: {
|
|
33
|
+
bg: 'blackAlpha.50',
|
|
34
|
+
_dark: {
|
|
35
|
+
bg: 'whiteAlpha.50',
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
_active: {
|
|
39
|
+
bg: 'blackAlpha.100',
|
|
40
|
+
_dark: {
|
|
41
|
+
bg: 'whiteAlpha.100',
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
_disabled: {
|
|
45
|
+
cursor: 'inherit',
|
|
46
|
+
opacity: 0.5,
|
|
47
|
+
_hover: {
|
|
48
|
+
bg: 'transparent',
|
|
49
|
+
_dark: {
|
|
50
|
+
bg: 'transparent',
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
_active: {
|
|
54
|
+
bg: 'transparent',
|
|
55
|
+
_dark: {
|
|
56
|
+
bg: 'transparent',
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
header: {
|
|
62
|
+
display: 'flex',
|
|
63
|
+
flexDirection: 'row',
|
|
64
|
+
position: 'sticky',
|
|
65
|
+
fontSize: 'md',
|
|
66
|
+
fontWeight: 'semibold',
|
|
67
|
+
color: 'muted',
|
|
68
|
+
},
|
|
69
|
+
icon: {
|
|
70
|
+
display: 'flex',
|
|
71
|
+
flexShrink: 0,
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
variants: {
|
|
75
|
+
size: {
|
|
76
|
+
sm: {
|
|
77
|
+
root: {
|
|
78
|
+
fontSize: 'sm',
|
|
79
|
+
},
|
|
80
|
+
item: {
|
|
81
|
+
py: 1,
|
|
82
|
+
px: 1,
|
|
83
|
+
},
|
|
84
|
+
header: {
|
|
85
|
+
py: 1,
|
|
86
|
+
px: 1,
|
|
87
|
+
},
|
|
88
|
+
cell: {
|
|
89
|
+
px: 1,
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
md: {
|
|
93
|
+
root: {
|
|
94
|
+
fontSize: 'md',
|
|
95
|
+
},
|
|
96
|
+
item: {
|
|
97
|
+
py: 2,
|
|
98
|
+
px: 2,
|
|
99
|
+
},
|
|
100
|
+
header: {
|
|
101
|
+
py: 2,
|
|
102
|
+
px: 2,
|
|
103
|
+
},
|
|
104
|
+
cell: {
|
|
105
|
+
px: 2,
|
|
106
|
+
},
|
|
107
|
+
},
|
|
108
|
+
},
|
|
109
|
+
},
|
|
110
|
+
defaultVariants: {
|
|
111
|
+
size: 'md',
|
|
112
|
+
},
|
|
113
|
+
})
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { HoverCard, Portal } from "@chakra-ui/react"
|
|
2
|
+
import { forwardRef } from "react"
|
|
3
|
+
|
|
4
|
+
interface HoverCardContentProps extends HoverCard.ContentProps {
|
|
5
|
+
portalled?: boolean
|
|
6
|
+
portalRef?: React.RefObject<HTMLElement>
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export const HoverCardContent = forwardRef<
|
|
10
|
+
HTMLDivElement,
|
|
11
|
+
HoverCardContentProps
|
|
12
|
+
>(function HoverCardContent(props, ref) {
|
|
13
|
+
const { portalled = true, portalRef, ...rest } = props
|
|
14
|
+
|
|
15
|
+
return (
|
|
16
|
+
<Portal disabled={!portalled} container={portalRef}>
|
|
17
|
+
<HoverCard.Positioner>
|
|
18
|
+
<HoverCard.Content ref={ref} {...rest} />
|
|
19
|
+
</HoverCard.Positioner>
|
|
20
|
+
</Portal>
|
|
21
|
+
)
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
export const HoverCardArrow = forwardRef<HTMLDivElement, HoverCard.ArrowProps>(
|
|
25
|
+
function HoverCardArrow(props, ref) {
|
|
26
|
+
return (
|
|
27
|
+
<HoverCard.Arrow ref={ref} {...props}>
|
|
28
|
+
<HoverCard.ArrowTip />
|
|
29
|
+
</HoverCard.Arrow>
|
|
30
|
+
)
|
|
31
|
+
},
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
export const HoverCardRoot = HoverCard.Root
|
|
35
|
+
export const HoverCardTrigger = HoverCard.Trigger
|