-
Notifications
You must be signed in to change notification settings - Fork 326
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Showing
39 changed files
with
2,888 additions
and
537 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
67 changes: 67 additions & 0 deletions
67
app/ide-desktop/lib/dashboard/src/components/AriaComponents/Button/Button.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
/** | ||
* @file Button.tsx | ||
* | ||
* Button component | ||
*/ | ||
import clsx from 'clsx' | ||
import * as reactAriaComponents from 'react-aria-components' | ||
import * as tailwindMerge from 'tailwind-merge' | ||
|
||
import SvgMask from '#/components/SvgMask' | ||
|
||
/** | ||
* Props for the Button component | ||
*/ | ||
export interface ButtonProps extends reactAriaComponents.ButtonProps { | ||
readonly variant: 'icon' | ||
readonly icon?: string | ||
/** | ||
* FIXME: This is not yet implemented | ||
* The position of the icon in the button | ||
* @default 'start' | ||
*/ | ||
readonly iconPosition?: 'end' | 'start' | ||
} | ||
|
||
const DEFAULT_CLASSES = | ||
'flex cursor-pointer rounded-sm border border-transparent transition-opacity duration-200 ease-in-out' | ||
const FOCUS_CLASSES = | ||
'focus-visible:outline-offset-2 focus:outline-none focus-visible:outline focus-visible:outline-primary' | ||
const ICON_CLASSES = 'opacity-50 hover:opacity-100' | ||
const EXTRA_CLICK_ZONE_CLASSES = 'flex relative before:inset-[-12px] before:absolute before:z-10' | ||
const DISABLED_CLASSES = 'disabled:opacity-50 disabled:cursor-not-allowed' | ||
|
||
/** | ||
* A button allows a user to perform an action, with mouse, touch, and keyboard interactions. | ||
*/ | ||
export function Button(props: ButtonProps) { | ||
const { className, children, icon, ...ariaButtonProps } = props | ||
|
||
const classes = clsx(DEFAULT_CLASSES, DISABLED_CLASSES, FOCUS_CLASSES, ICON_CLASSES) | ||
|
||
const childrenFactory = () => { | ||
return icon != null ? ( | ||
<> | ||
<div className={EXTRA_CLICK_ZONE_CLASSES}> | ||
<SvgMask src={icon} /> | ||
</div> | ||
</> | ||
) : ( | ||
children | ||
) | ||
} | ||
|
||
return ( | ||
<reactAriaComponents.Button | ||
className={values => | ||
tailwindMerge.twMerge( | ||
classes, | ||
typeof className === 'function' ? className(values) : className | ||
) | ||
} | ||
{...ariaButtonProps} | ||
> | ||
{childrenFactory()} | ||
</reactAriaComponents.Button> | ||
) | ||
} |
86 changes: 86 additions & 0 deletions
86
app/ide-desktop/lib/dashboard/src/components/AriaComponents/Dialog/Dialog.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
/** | ||
* @file | ||
* A dialog is an overlay shown above other content in an application. | ||
* Can be used to display alerts, confirmations, or other content. | ||
*/ | ||
import * as React from 'react' | ||
|
||
import * as reactAriaComponents from 'react-aria-components' | ||
import * as tailwindMerge from 'tailwind-merge' | ||
|
||
import Dismiss from 'enso-assets/dismiss.svg' | ||
|
||
import * as ariaComponents from '#/components/AriaComponents' | ||
import * as portal from '#/components/Portal' | ||
|
||
import type * as types from './types' | ||
|
||
const MODAL_CLASSES = | ||
'fixed z-1 top-0 left-0 right-0 bottom-0 bg-black/[15%] flex items-center justify-center text-center' | ||
const DIALOG_CLASSES = | ||
'relative flex flex-col overflow-hidden rounded-xl text-left align-middle text-slate-700 shadow-2xl bg-clip-padding border border-black/10 before:absolute before:inset before:h-full before:w-full before:rounded-default before:bg-selected-frame before:backdrop-blur-default' | ||
|
||
const MODAL_CLASSES_BY_TYPE = { | ||
modal: 'p-4', | ||
popover: '', | ||
fullscreen: 'p-4', | ||
} satisfies Record<types.DialogType, string> | ||
|
||
const DIALOG_CLASSES_BY_TYPE = { | ||
modal: 'w-full max-w-md min-h-[200px] h-[90vh] max-h-[90vh]', | ||
popover: 'rounded-lg', | ||
fullscreen: 'w-full h-full max-w-full max-h-full bg-clip-border', | ||
} satisfies Record<types.DialogType, string> | ||
|
||
/** | ||
* A dialog is an overlay shown above other content in an application. | ||
* Can be used to display alerts, confirmations, or other content. | ||
*/ | ||
export function Dialog(props: types.DialogProps) { | ||
const { | ||
children, | ||
title, | ||
type = 'modal', | ||
isDismissible = true, | ||
isKeyboardDismissDisabled = false, | ||
className, | ||
...ariaDialogProps | ||
} = props | ||
|
||
const root = portal.useStrictPortalContext() | ||
|
||
return ( | ||
<reactAriaComponents.Modal | ||
className={tailwindMerge.twMerge(MODAL_CLASSES, [MODAL_CLASSES_BY_TYPE[type]])} | ||
isDismissable={isDismissible} | ||
isKeyboardDismissDisabled={isKeyboardDismissDisabled} | ||
UNSTABLE_portalContainer={root.current} | ||
> | ||
<reactAriaComponents.Dialog | ||
className={tailwindMerge.twMerge(DIALOG_CLASSES, [DIALOG_CLASSES_BY_TYPE[type]], className)} | ||
{...ariaDialogProps} | ||
> | ||
{opts => ( | ||
<> | ||
{typeof title === 'string' && ( | ||
<reactAriaComponents.Header className="center sticky flex flex-none border-b px-3.5 py-2.5 text-primary shadow"> | ||
<h2 className="text-l my-0 font-semibold leading-6">{title}</h2> | ||
|
||
<ariaComponents.Button | ||
variant="icon" | ||
className="my-auto ml-auto" | ||
onPress={opts.close} | ||
icon={Dismiss} | ||
/> | ||
</reactAriaComponents.Header> | ||
)} | ||
|
||
<div className="flex-1 shrink-0"> | ||
{typeof children === 'function' ? children(opts) : children} | ||
</div> | ||
</> | ||
)} | ||
</reactAriaComponents.Dialog> | ||
</reactAriaComponents.Modal> | ||
) | ||
} |
45 changes: 45 additions & 0 deletions
45
app/ide-desktop/lib/dashboard/src/components/AriaComponents/Dialog/DialogTrigger.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
/** | ||
* @file | ||
* | ||
* A DialogTrigger opens a dialog when a trigger element is pressed. | ||
*/ | ||
import * as React from 'react' | ||
|
||
import * as reactAriaComponents from 'react-aria-components' | ||
|
||
import * as modalProvider from '#/providers/ModalProvider' | ||
|
||
import type * as types from './types' | ||
|
||
const PLACEHOLDER = <div /> | ||
|
||
/** | ||
* A DialogTrigger opens a dialog when a trigger element is pressed. | ||
*/ | ||
export function DialogTrigger(props: types.DialogTriggerProps) { | ||
const { children, onOpenChange, ...triggerProps } = props | ||
|
||
const { setModal, unsetModal } = modalProvider.useSetModal() | ||
|
||
const onOpenChangeInternal = React.useCallback( | ||
(isOpened: boolean) => { | ||
if (isOpened) { | ||
// we're using a placeholder here just to let the rest of the code know that the modal is open | ||
setModal(PLACEHOLDER) | ||
} else { | ||
unsetModal() | ||
} | ||
|
||
onOpenChange?.(isOpened) | ||
}, | ||
[setModal, unsetModal, onOpenChange] | ||
) | ||
|
||
return ( | ||
<reactAriaComponents.DialogTrigger | ||
children={children} | ||
onOpenChange={onOpenChangeInternal} | ||
{...triggerProps} | ||
/> | ||
) | ||
} |
8 changes: 8 additions & 0 deletions
8
app/ide-desktop/lib/dashboard/src/components/AriaComponents/Dialog/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
/** | ||
* @file | ||
* | ||
* Re-exports the Dialog component. | ||
*/ | ||
export * from './Dialog' | ||
export * from './types' | ||
export * from './DialogTrigger' |
Oops, something went wrong.