@dxos/react-ui 0.1.0 → 0.1.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dxos/react-ui",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "Vite plugin which configures a low-level design system for DXOS.",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
@@ -17,6 +17,7 @@
17
17
  "@fontsource/roboto-flex": "^4.5.2",
18
18
  "@fontsource/space-grotesk": "^4.5.10",
19
19
  "@headlessui/react": "^1.7.3",
20
+ "@radix-ui/react-alert-dialog": "^1.0.2",
20
21
  "@radix-ui/react-avatar": "^1.0.1",
21
22
  "@radix-ui/react-dialog": "^1.0.0",
22
23
  "@radix-ui/react-navigation-menu": "^1.1.1",
@@ -31,10 +32,11 @@
31
32
  "postcss": "^8.4.17",
32
33
  "qrcode.react": "^3.1.0",
33
34
  "tailwindcss": "^3.1.8",
35
+ "tailwindcss-logical": "^3.0.0",
34
36
  "tailwindcss-radix": "^2.6.0"
35
37
  },
36
38
  "devDependencies": {
37
- "@dxos/vite-plugin": "0.1.0",
39
+ "@dxos/vite-plugin": "0.1.2",
38
40
  "@types/react": "^18.0.21",
39
41
  "@types/react-dom": "^18.0.6",
40
42
  "@vitejs/plugin-react": "^2.0.1",
@@ -0,0 +1,35 @@
1
+ //
2
+ // Copyright 2022 DXOS.org
3
+ //
4
+
5
+ import '@dxosTheme';
6
+ import React from 'react';
7
+
8
+ import { templateForComponent } from '../../testing';
9
+ import { Button } from '../Button';
10
+ import { AlertDialog, AlertDialogProps } from './AlertDialog';
11
+
12
+ export default {
13
+ title: 'react-ui/AlertDialog',
14
+ component: AlertDialog
15
+ };
16
+
17
+ const Template = ({ children, ...props }: AlertDialogProps) => {
18
+ return <AlertDialog {...props}>{children}</AlertDialog>;
19
+ };
20
+
21
+ export const Default = templateForComponent(Template)({
22
+ openTrigger: '',
23
+ title: '',
24
+ confirmTrigger: <span />
25
+ });
26
+ Default.args = {
27
+ openTrigger: <Button>Reset device</Button>,
28
+ cancelTrigger: <Button>Cancel</Button>,
29
+ confirmTrigger: <Button variant='primary'>GO</Button>,
30
+ destructiveConfirmString: "I've definitely had my coffee",
31
+ destructiveConfirmInputProps: {
32
+ label: "Type “I've definitely had my coffee” to confirm"
33
+ },
34
+ title: 'Reset your device'
35
+ };
@@ -0,0 +1,127 @@
1
+ //
2
+ // Copyright 2022 DXOS.org
3
+ //
4
+
5
+ import { Transition } from '@headlessui/react';
6
+ import * as AlertDialogPrimitive from '@radix-ui/react-alert-dialog';
7
+ import cx from 'classnames';
8
+ import React, { cloneElement, Fragment, ReactHTMLElement, ReactNode, useEffect, useState } from 'react';
9
+
10
+ import { defaultDescription, defaultFocus } from '../../styles';
11
+ import { Input, InputProps } from '../Input';
12
+
13
+ export interface AlertDialogProps {
14
+ title: ReactNode;
15
+ openTrigger?: ReactNode;
16
+ cancelTrigger?: ReactNode;
17
+ confirmTrigger: Omit<ReactHTMLElement<HTMLElement>, 'ref'>;
18
+ destructiveConfirmString?: string;
19
+ destructiveConfirmInputProps?: Omit<InputProps, 'onChange' | 'initialValue'>;
20
+ titleVisuallyHidden?: boolean;
21
+ description?: ReactNode;
22
+ children?: ReactNode;
23
+ initiallyOpen?: boolean;
24
+ mountAsSibling?: boolean;
25
+ }
26
+
27
+ export const AlertDialog = ({
28
+ title,
29
+ titleVisuallyHidden,
30
+ description,
31
+ openTrigger,
32
+ cancelTrigger,
33
+ confirmTrigger,
34
+ destructiveConfirmString,
35
+ destructiveConfirmInputProps,
36
+ children,
37
+ initiallyOpen,
38
+ mountAsSibling
39
+ }: AlertDialogProps) => {
40
+ const [isOpen, setIsOpen] = useState(!!initiallyOpen);
41
+ const [confirmDisabled, setConfirmDisabled] = useState(!!destructiveConfirmString);
42
+ const [confirmStringValue, setConfirmStringValue] = useState('');
43
+
44
+ useEffect(() => {
45
+ if (destructiveConfirmString) {
46
+ setConfirmDisabled(confirmStringValue !== destructiveConfirmString);
47
+ }
48
+ }, [confirmStringValue]);
49
+
50
+ const dialogOverlayAndContent = (
51
+ <Transition.Root show={isOpen}>
52
+ <Transition.Child
53
+ as={Fragment}
54
+ enter='ease-out duration-300'
55
+ enterFrom='opacity-0'
56
+ enterTo='opacity-100'
57
+ leave='ease-in duration-200'
58
+ leaveFrom='opacity-100'
59
+ leaveTo='opacity-0'
60
+ >
61
+ <AlertDialogPrimitive.Overlay forceMount className='fixed inset-0 z-20 bg-black/50' />
62
+ </Transition.Child>
63
+ <Transition.Child
64
+ as={Fragment}
65
+ enter='ease-out duration-300'
66
+ enterFrom='opacity-0 scale-95'
67
+ enterTo='opacity-100 scale-100'
68
+ leave='ease-in duration-200'
69
+ leaveFrom='opacity-100 scale-100'
70
+ leaveTo='opacity-0 scale-95'
71
+ >
72
+ <AlertDialogPrimitive.Content
73
+ forceMount
74
+ className={cx(
75
+ 'fixed z-50',
76
+ 'w-[95vw] max-w-md rounded-xl p-4 md:w-full',
77
+ 'top-[50%] left-[50%] -translate-x-[50%] -translate-y-[50%]',
78
+ 'shadow-2xl bg-white dark:bg-neutral-800 elevated-buttons',
79
+ defaultFocus
80
+ )}
81
+ >
82
+ <AlertDialogPrimitive.Title
83
+ className={cx(
84
+ 'text-2xl font-display font-medium text-neutral-900 dark:text-neutral-100 rounded-md',
85
+ titleVisuallyHidden && 'sr-only',
86
+ defaultFocus
87
+ )}
88
+ tabIndex={0}
89
+ >
90
+ {title}
91
+ </AlertDialogPrimitive.Title>
92
+ {description && (
93
+ <AlertDialogPrimitive.Description className={cx('mt-2', defaultDescription)}>
94
+ {description}
95
+ </AlertDialogPrimitive.Description>
96
+ )}
97
+
98
+ {children}
99
+
100
+ {destructiveConfirmInputProps && <Input {...destructiveConfirmInputProps} onChange={setConfirmStringValue} />}
101
+
102
+ <div className='flex flex-wrap justify-end gap-4'>
103
+ {cancelTrigger && (
104
+ <AlertDialogPrimitive.Cancel asChild={typeof cancelTrigger !== 'string'}>
105
+ {cancelTrigger}
106
+ </AlertDialogPrimitive.Cancel>
107
+ )}
108
+ <AlertDialogPrimitive.Action asChild>
109
+ {cloneElement(confirmTrigger, { disabled: confirmDisabled })}
110
+ </AlertDialogPrimitive.Action>
111
+ </div>
112
+ </AlertDialogPrimitive.Content>
113
+ </Transition.Child>
114
+ </Transition.Root>
115
+ );
116
+
117
+ return (
118
+ <AlertDialogPrimitive.Root open={isOpen} onOpenChange={setIsOpen}>
119
+ {openTrigger && <AlertDialogPrimitive.Trigger asChild>{openTrigger}</AlertDialogPrimitive.Trigger>}
120
+ {mountAsSibling ? (
121
+ dialogOverlayAndContent
122
+ ) : (
123
+ <AlertDialogPrimitive.Portal>{dialogOverlayAndContent}</AlertDialogPrimitive.Portal>
124
+ )}
125
+ </AlertDialogPrimitive.Root>
126
+ );
127
+ };
@@ -0,0 +1,5 @@
1
+ //
2
+ // Copyright 2022 DXOS.org
3
+ //
4
+
5
+ export * from './AlertDialog';
@@ -61,7 +61,7 @@ export const Avatar = forwardRef(
61
61
  )}
62
62
  <AvatarPrimitive.Fallback
63
63
  className={cx(
64
- 'flex h-full w-full items-center justify-center bg-white dark:bg-neutral-800 overflow-hidden',
64
+ 'shrink-0 flex h-full w-full items-center justify-center bg-white dark:bg-neutral-800 overflow-hidden',
65
65
  shapeStyles[variant]
66
66
  )}
67
67
  delayMs={0}
@@ -8,13 +8,15 @@ import React, { forwardRef } from 'react';
8
8
  import { ButtonProps } from './ButtonProps';
9
9
  import { buttonStyles } from './buttonStyles';
10
10
 
11
- export const Button = forwardRef<HTMLButtonElement, ButtonProps>(({ children, ...props }, ref) => (
12
- <button
13
- ref={ref}
14
- {...props}
15
- className={cx(buttonStyles(props), props.className)}
16
- {...(props.disabled && { disabled: true })}
17
- >
18
- {children}
19
- </button>
20
- ));
11
+ export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
12
+ ({ children, compact, variant, rounding, ...props }, ref) => (
13
+ <button
14
+ ref={ref}
15
+ {...props}
16
+ className={cx(buttonStyles({ compact, variant, rounding, disabled: props.disabled }), props.className)}
17
+ {...(props.disabled && { disabled: true })}
18
+ >
19
+ {children}
20
+ </button>
21
+ )
22
+ );
@@ -6,5 +6,7 @@ import { ComponentProps } from 'react';
6
6
 
7
7
  export interface ButtonProps extends ComponentProps<'button'> {
8
8
  variant?: 'default' | 'primary' | 'outline';
9
+ compact?: boolean;
10
+ rounding?: string;
9
11
  disabled?: boolean;
10
12
  }
@@ -13,7 +13,9 @@ export const defaultButtonColors = 'bg-white text-neutral-900 dark:bg-neutral-75
13
13
  export const buttonStyles = (props: ButtonProps) => {
14
14
  const resolvedVariant = props.variant || 'default';
15
15
  return cx(
16
- 'inline-flex select-none items-center justify-center rounded-md px-4 py-2 text-sm font-medium',
16
+ 'inline-flex select-none items-center justify-center text-sm font-medium',
17
+ props.rounding ?? 'rounded-md',
18
+ props.compact ? 'p-1.5' : 'pli-4 plb-2',
17
19
  'transition-color duration-100',
18
20
  defaultHover(props),
19
21
  resolvedVariant === 'default' &&
@@ -22,7 +24,7 @@ export const buttonStyles = (props: ButtonProps) => {
22
24
  resolvedVariant === 'primary' && 'border border-primary-550 hover:border-transparent',
23
25
  resolvedVariant === 'primary' && primaryButtonColors,
24
26
  resolvedVariant === 'outline' &&
25
- 'text-neutral-700 border border-neutral-600 font-medium rounded-lg text-sm text-center dark:border-neutral-300 dark:text-neutral-150',
27
+ 'text-neutral-700 border border-neutral-600 dark:border-neutral-300 dark:text-neutral-150',
26
28
  defaultFocus,
27
29
  props.disabled ? defaultDisabled : resolvedVariant !== 'outline' && 'button-elevation',
28
30
  // Register all radix states
@@ -6,6 +6,7 @@ import cx from 'classnames';
6
6
  import React, { ReactNode } from 'react';
7
7
 
8
8
  import { useId } from '../../hooks';
9
+ import { defaultGroup } from '../../styles/group';
9
10
  import { Heading, HeadingProps } from '../Heading';
10
11
 
11
12
  export interface GroupProps extends React.ComponentProps<'div'> {
@@ -15,32 +16,10 @@ export interface GroupProps extends React.ComponentProps<'div'> {
15
16
  children?: ReactNode;
16
17
  }
17
18
 
18
- const elevationClassNameMap = new Map<number, string>([
19
- [0, 'shadow-none'],
20
- [1, 'shadow-sm'],
21
- [2, 'shadow'],
22
- [3, 'shadow-md'],
23
- [4, 'shadow-lg'],
24
- [5, 'shadow-xl'],
25
- [6, 'shadow-2xl']
26
- ]);
27
-
28
- export const Group = ({ elevation, children, label, labelVisuallyHidden, className, ...props }: GroupProps) => {
19
+ export const Group = ({ elevation = 3, children, label, labelVisuallyHidden, className, ...props }: GroupProps) => {
29
20
  const labelId = useId('groupLabel');
30
21
  return (
31
- <div
32
- role='group'
33
- aria-labelledby={labelId}
34
- className={cx(
35
- 'rounded-lg p-4',
36
- elevation === 0
37
- ? 'bg-transparent border border-neutral-200 dark:border-neutral-700'
38
- : 'bg-white dark:bg-neutral-800 elevated-buttons',
39
- elevationClassNameMap.get(typeof elevation === 'undefined' ? 3 : elevation),
40
- className
41
- )}
42
- {...props}
43
- >
22
+ <div role='group' aria-labelledby={labelId} className={cx(defaultGroup({ elevation }), className)} {...props}>
44
23
  <Heading {...label} id={labelId} className={cx(labelVisuallyHidden && 'sr-only', 'mb-2', label?.className)} />
45
24
  {children}
46
25
  </div>
@@ -6,7 +6,7 @@ import * as NavigationMenuPrimitive from '@radix-ui/react-navigation-menu';
6
6
  import cx from 'classnames';
7
7
  import React, { ComponentProps, ForwardedRef, forwardRef, ReactNode } from 'react';
8
8
 
9
- import { defaultFocus, defaultHover } from '../../styles';
9
+ import { defaultFocus, defaultHover, defaultInlineSeparator } from '../../styles';
10
10
  import { defaultButtonColors, primaryButtonColors } from '../Button';
11
11
  import { Tooltip, TooltipProps } from '../Tooltip';
12
12
 
@@ -122,7 +122,7 @@ const NavMenuTooltipLinkItem = forwardRef(
122
122
  export const NavMenuLink = NavigationMenuPrimitive.Link;
123
123
 
124
124
  export const NavMenuSeparatorItem = (_props: NavMenuSeparatorProps) => {
125
- return <span role='none' className='h-5 border-l border-neutral-300 dark:border-neutral-700' />;
125
+ return <span role='none' className={cx(defaultInlineSeparator, 'bs-5')} />;
126
126
  };
127
127
 
128
128
  const isTooltipLinkItem = (o: any): o is NavMenuTooltipLinkItemProps => 'tooltip' in o;
@@ -132,7 +132,7 @@ const isSeparator = (o: any): o is NavMenuSeparatorProps => 'separator' in o;
132
132
  export const NavMenu = ({ items, ...rootProps }: NavMenuProps) => {
133
133
  return (
134
134
  <NavigationMenuPrimitive.Root {...rootProps} className={cx('flex justify-center', rootProps.className)}>
135
- <NavigationMenuPrimitive.List className='relative flex flex-row items-center gap-2 rounded-lg bg-white dark:bg-neutral-800 p-2 button-elevation overflow-x-auto'>
135
+ <NavigationMenuPrimitive.List className='relative flex flex-row items-center gap-1 rounded-lg bg-white dark:bg-neutral-750 p-1 button-elevation overflow-x-auto'>
136
136
  {items.map((item: NavMenuItem, i) => {
137
137
  return isTooltipLinkItem(item) ? (
138
138
  <NavMenuTooltipLinkItem key={i} {...item} />
@@ -154,7 +154,7 @@ export const NavMenu = ({ items, ...rootProps }: NavMenuProps) => {
154
154
  'transition-[width_transform] duration-[250ms] ease-[ease]'
155
155
  )}
156
156
  >
157
- <div className='top-1 relative bg-white dark:bg-neutral-800 w-2 h-2 rotate-45' />
157
+ <div className='top-1 relative bg-white dark:bg-neutral-750 w-2 h-2 rotate-45' />
158
158
  </NavigationMenuPrimitive.Indicator>
159
159
  </NavigationMenuPrimitive.List>
160
160
 
@@ -166,7 +166,7 @@ export const NavMenu = ({ items, ...rootProps }: NavMenuProps) => {
166
166
  >
167
167
  <NavigationMenuPrimitive.Viewport
168
168
  className={cx(
169
- 'relative mt-2 shadow-lg rounded-md bg-white dark:bg-neutral-800 overflow-hidden',
169
+ 'relative mt-2 shadow-lg rounded-md bg-white dark:bg-neutral-750 overflow-hidden',
170
170
  'w-radix-navigation-menu-viewport',
171
171
  'h-radix-navigation-menu-viewport',
172
172
  'radix-state-open:animate-scale-in-content',
@@ -28,8 +28,9 @@ export const QrCode = ({ value, label, size, side, sideOffset, collisionPadding,
28
28
  return (
29
29
  <Tooltip content={label} {...{ side, sideOffset, collisionPadding }}>
30
30
  <Button
31
+ compact
31
32
  {...buttonProps}
32
- className={cx('py-0 px-0 overflow-hidden', getSize(size ?? 32), buttonProps.className)}
33
+ className={cx('overflow-hidden p-0', getSize(size ?? 32), buttonProps.className)}
33
34
  onClick={copyValue}
34
35
  >
35
36
  <QRCodeSVG value={value} includeMargin role='none' className='w-full h-auto' />
@@ -0,0 +1,23 @@
1
+ //
2
+ // Copyright 2022 DXOS.org
3
+ //
4
+
5
+ import '@dxosTheme';
6
+ import React from 'react';
7
+
8
+ import { templateForComponent } from '../../testing';
9
+ import { Tag, TagProps } from './Tag';
10
+
11
+ export default {
12
+ title: 'react-ui/Tag',
13
+ component: Tag
14
+ };
15
+
16
+ const Template = ({ children, ...props }: TagProps) => {
17
+ return <Tag {...props}>{children}</Tag>;
18
+ };
19
+
20
+ const defaultProps = {};
21
+
22
+ export const Default = templateForComponent(Template)(defaultProps);
23
+ Default.args = { children: 'Hello' };
@@ -0,0 +1,32 @@
1
+ //
2
+ // Copyright 2022 DXOS.org
3
+ //
4
+
5
+ import cx from 'classnames';
6
+ import React, { PropsWithChildren, ReactNode } from 'react';
7
+
8
+ import { MessageValence } from '../../props';
9
+
10
+ export interface TagProps extends React.ComponentProps<'span'> {
11
+ valence?: MessageValence;
12
+ children?: ReactNode;
13
+ }
14
+
15
+ const valenceColorMap: Record<MessageValence, string> = {
16
+ neutral: 'bg-neutral-100 text-neutral-800 dark:bg-neutral-700 dark:text-neutral-300',
17
+ success: 'bg-success-100 text-success-800 dark:bg-success-700 dark:text-success-300',
18
+ info: 'bg-info-100 text-info-800 dark:bg-info-700 dark:text-info-300',
19
+ warning: 'bg-warning-100 text-warning-800 dark:bg-warning-700 dark:text-warning-300',
20
+ error: 'bg-error-100 text-error-800 dark:bg-error-700 dark:text-error-300'
21
+ };
22
+
23
+ export const Tag = ({ children, valence = 'neutral', ...props }: PropsWithChildren<TagProps>) => {
24
+ return (
25
+ <span
26
+ {...props}
27
+ className={cx('text-xs font-semibold px-2.5 py-0.5 rounded', valenceColorMap[valence], props.className)}
28
+ >
29
+ {children}
30
+ </span>
31
+ );
32
+ };
@@ -2,4 +2,4 @@
2
2
  // Copyright 2022 DXOS.org
3
3
  //
4
4
 
5
- export * from './Main';
5
+ export * from './Tag';
@@ -3,6 +3,7 @@
3
3
  //
4
4
 
5
5
  export * from './Alert';
6
+ export * from './AlertDialog';
6
7
  export * from './Avatar';
7
8
  export * from './Button';
8
9
  export * from './CompoundButton';
@@ -11,10 +12,10 @@ export * from './Group';
11
12
  export * from './Heading';
12
13
  export * from './Loading';
13
14
  export * from './Input';
14
- export * from './Main';
15
15
  export * from './NavMenu';
16
16
  export * from './Popover';
17
17
  export * from './QrCode';
18
+ export * from './Tag';
18
19
  export * from './Toast';
19
20
  export * from './Tooltip';
20
21
  export * from './UiProvider';
package/src/plugin.ts CHANGED
@@ -6,6 +6,7 @@ import tailwindcssForms from '@tailwindcss/forms';
6
6
  import autoprefixer from 'autoprefixer';
7
7
  import { resolve } from 'path';
8
8
  import tailwindcss from 'tailwindcss';
9
+ import tailwindcssLogical from 'tailwindcss-logical';
9
10
  import tailwindcssRadix from 'tailwindcss-radix';
10
11
  import tailwindColors from 'tailwindcss/colors';
11
12
  import defaultConfig from 'tailwindcss/stubs/defaultConfig.stub.js';
@@ -251,7 +252,7 @@ export const themePlugin = (options: VitePluginTailwindOptions) => {
251
252
  }
252
253
  }
253
254
  },
254
- plugins: [tailwindcssForms, tailwindcssRadix()],
255
+ plugins: [tailwindcssLogical, tailwindcssForms, tailwindcssRadix()],
255
256
  ...(env.mode === 'development' && { mode: 'jit' }),
256
257
  content: [resolve(root || './', 'node_modules/@dxos/react-ui/dist/**/*.js'), ...config.content]
257
258
  }),
@@ -0,0 +1,5 @@
1
+ //
2
+ // Copyright 2022 DXOS.org
3
+ //
4
+
5
+ export type Elevation = 0 | 1 | 2 | 3 | 4 | 5 | 6;
@@ -2,4 +2,4 @@
2
2
  // Copyright 2022 DXOS.org
3
3
  //
4
4
 
5
- export type MessageValence = 'success' | 'info' | 'warning' | 'error';
5
+ export type MessageValence = 'success' | 'info' | 'warning' | 'error' | 'neutral';
@@ -2,5 +2,6 @@
2
2
  // Copyright 2022 DXOS.org
3
3
  //
4
4
 
5
+ export * from './Elevation';
5
6
  export * from './MessageValence';
6
7
  export * from './Size';
@@ -0,0 +1,27 @@
1
+ //
2
+ // Copyright 2022 DXOS.org
3
+ //
4
+
5
+ import cx from 'classnames';
6
+
7
+ import { Elevation } from '../props';
8
+
9
+ const elevationClassNameMap = new Map<number, string>([
10
+ [0, 'shadow-none'],
11
+ [1, 'shadow-sm'],
12
+ [2, 'shadow'],
13
+ [3, 'shadow-md'],
14
+ [4, 'shadow-lg'],
15
+ [5, 'shadow-xl'],
16
+ [6, 'shadow-2xl']
17
+ ]);
18
+
19
+ export const defaultGroup = ({ elevation }: { elevation: Elevation }) => {
20
+ return cx(
21
+ 'rounded-lg p-4',
22
+ elevation === 0
23
+ ? 'bg-transparent border border-neutral-200 dark:border-neutral-700'
24
+ : 'bg-white dark:bg-neutral-800 elevated-buttons',
25
+ elevationClassNameMap.get(elevation)
26
+ );
27
+ };
@@ -5,7 +5,9 @@
5
5
  export * from './active';
6
6
  export * from './disabled';
7
7
  export * from './focus';
8
+ export * from './group';
8
9
  export * from './hover';
10
+ export * from './ornament';
9
11
  export * from './size';
10
12
  export * from './text';
11
13
  export * from './valence';
@@ -0,0 +1,6 @@
1
+ //
2
+ // Copyright 2022 DXOS.org
3
+ //
4
+
5
+ export const defaultInlineSeparator = 'border-is border-neutral-300 dark:border-neutral-700';
6
+ export const defaultBlockSeparator = 'border-bs border-neutral-300 dark:border-neutral-700';
package/src/typings.d.ts CHANGED
@@ -4,4 +4,5 @@
4
4
 
5
5
  declare module 'tailwindcss/stubs/defaultConfig.stub.js';
6
6
  declare module 'tailwindcss-radix';
7
+ declare module 'tailwindcss-logical';
7
8
  declare module 'react-jdenticon';
@@ -1,14 +0,0 @@
1
- //
2
- // Copyright 2022 DXOS.org
3
- //
4
-
5
- import cx from 'classnames';
6
- import React, { ComponentProps, PropsWithChildren } from 'react';
7
-
8
- export const Main = ({ children, className, ...mainProps }: PropsWithChildren<ComponentProps<'main'>>) => {
9
- return (
10
- <main {...mainProps} className={cx('mt-8 px-8 space-y-4', className)}>
11
- {children}
12
- </main>
13
- );
14
- };