diff --git a/platform/app/tailwind.config.js b/platform/app/tailwind.config.js index 8837fff20..1ba323991 100644 --- a/platform/app/tailwind.config.js +++ b/platform/app/tailwind.config.js @@ -39,16 +39,18 @@ module.exports = { mono: ['Menlo', 'Monaco', 'Consolas', '"Liberation Mono"', '"Courier New"', 'monospace'], }, fontSize: { - xxs: '0.6875rem', // 11px - xs: '0.75rem', // 12px - sm: '0.8125rem', // 13px - base: '0.875rem', // 14px - lg: '1rem', // 16px - xl: '1.125rem', // 18px - '2xl': '1.25rem', // 20px - '3xl': '1.375rem', // 22px - '4xl': '1.5rem', // 24px - '5xl': '1.875rem', // 30px + xxs: '0.625rem', // 10px + xs: '0.6875rem', // 11px + sm: '0.75rem', // 12px + base: '0.8125rem', // 13px + lg: '0.875rem', // 14px + xl: '1rem', // 16px + // 2xl and above will be updated in an upcoming version + '2xl': '1.5rem', + '3xl': '1.875rem', + '4xl': '2.25rem', + '5xl': '3rem', + '6xl': '4rem', }, }, }; diff --git a/platform/docs/docusaurus.config.js b/platform/docs/docusaurus.config.js index 092b18377..e52508796 100644 --- a/platform/docs/docusaurus.config.js +++ b/platform/docs/docusaurus.config.js @@ -157,12 +157,6 @@ module.exports = { srcDark: 'img/ohif-logo.svg', }, items: [ - { - href: 'https://ohif.org/showcase', - label: 'Showcase', - target: '_blank', - position: 'left', - }, { position: 'left', to: '/', @@ -170,25 +164,28 @@ module.exports = { docId: 'Introduction', label: 'Docs', }, + { + to: '/components', + label: 'Components', + position: 'left', + }, + { + href: 'https://ohif.org/showcase', + label: 'Showcase', + target: '_blank', + position: 'left', + }, { href: 'https://ohif.org/collaborate', label: 'Collaborate', target: '_blank', position: 'left', }, - /* - { - to: '/playground', - label: 'UI Playground', - position: 'left', - className: 'new-badge', - }, - */ { to: '/help', //activeBaseRegex: '(^/help$)|(/help)', label: 'Help', - position: 'right', + position: 'left', }, { type: 'docsVersionDropdown', diff --git a/platform/docs/src/css/custom.css b/platform/docs/src/css/custom.css index 5d7b1b8eb..75b488090 100644 --- a/platform/docs/src/css/custom.css +++ b/platform/docs/src/css/custom.css @@ -233,7 +233,9 @@ input[type='number'] { } .navbar__item svg { - margin-left: 5px; + margin-right: 5px; + display: inline-block; + vertical-align: middle; } /* stylelint-disable docusaurus/copyright-header */ diff --git a/platform/docs/src/pages/colors-and-type.tsx b/platform/docs/src/pages/colors-and-type.tsx new file mode 100644 index 000000000..8aad79e03 --- /dev/null +++ b/platform/docs/src/pages/colors-and-type.tsx @@ -0,0 +1,418 @@ +import React, { useState } from 'react'; +import '../css/custom.css'; + +import Layout from '@theme/Layout'; +import { Label } from '../../../ui-next/src/components/Label'; +import { Input } from '../../../ui-next/src/components/Input'; +import { Separator } from '../../../ui-next/src/components/Separator'; +import { Tabs, TabsList, TabsTrigger } from '../../../ui-next/src/components/Tabs'; +import { + Select, + SelectTrigger, + SelectContent, + SelectItem, + SelectValue, +} from '../../../ui-next/src/components/Select'; +import { Button } from '../../../ui-next/src/components/Button'; +import { Switch } from '../../../ui-next/src/components/Switch'; +import { Checkbox } from '../../../ui-next/src/components/Checkbox'; +import { Toggle } from '../../../ui-next/src/components/Toggle'; +import { Slider } from '../../../ui-next/src/components/Slider'; +import { ScrollArea } from '../../../ui-next/src/components/ScrollArea'; +import { + DropdownMenu, + DropdownMenuTrigger, + DropdownMenuContent, + DropdownMenuItem, +} from '../../../ui-next/src/components/DropdownMenu'; +import { Icons } from '../../../ui-next/src/components/Icons'; +import { Toaster, toast } from '../../../ui-next/src/components/Sonner'; +import { + Card, + CardHeader, + CardFooter, + CardTitle, + CardDescription, + CardContent, +} from '../../../ui-next/src/components/Card'; + +interface ShowcaseRowProps { + title: string; + description?: string; + children: React.ReactNode; + code: string; +} + +export default function ComponentShowcase() { + // Handlers to trigger different types of toasts + const triggerSuccess = () => { + toast.success('This is a success toast!'); + }; + + const triggerError = () => { + toast.error('This is an error toast!'); + }; + + const triggerInfo = () => { + toast.info('This is an info toast!'); + }; + + const triggerWarning = () => { + toast.warning('This is a warning toast!'); + }; + + // Handler to trigger a toast.promise example + const triggerPromiseToast = () => { + const promise = () => + new Promise<{ name: string }>(resolve => + setTimeout(() => resolve({ name: 'Segmentation 1' }), 3000) + ); + + toast.promise(promise(), { + loading: 'Loading Segmentation...', + success: data => `${data.name} has been added`, + error: 'Error', + }); + }; + + // Handler to trigger a toast with description + const triggerDescriptionToast = () => { + toast.success('Success heading', { + description: 'This is a detailed description of the success message.', + }); + }; + + // Handler to trigger a toast with an action button + const triggerActionButtonToast = () => { + toast.info('No active segmentation detected', { + description: 'Create a segmentation before using the Brush', + }); + }; + + // Handler to trigger a toast with a cancel button + const triggerCancelButtonToast = () => { + toast.error('No active segmentation detected', { + description: 'Create a segmentation before using the Brush', + }); + }; + + // Handler to trigger a toast with both action and cancel buttons + const triggerCombinedToast = () => { + toast.warning('Warning!', { + description: 'This is a warning with both action and cancel buttons.', + action: ( + + ), + cancel: ( + + ), + }); + }; + + // Handler to trigger a loading toast using Toaster's default loading icon + const showLoadingToast = () => { + toast.loading('Loading your data...'); + }; + + return ( + +
+
+
+ + + + + + Colors & Typography + + + Color Palette and Typography Guidelines + + + + + + + + + + Components + + + Essential UI Components with Variants + + + + + + + + + + Patterns + + + Component-Based Layout Examples + + + + +
+
+ +
+

Colors & Typography

+ + +
+
+
+
+ highlight +
+
+
+
+ Used for active or selected elements in the Viewer. +
+
+ +
+
+
+
+ primary +
+
+
+
+ Used for Actions. Icons use 'primary' at 100% opacity while various components will + use a reduced opacity. Hover and other states increase the opacity. +
+
+ +
+
+
+
+ popover +
+
+
+ muted +
+
+
+ background +
+
+
+ These three colors are used as background colors. For the lowest level above black + use 'background'. For normal panel backgrounds and other interactive components, use + 'muted'. For elements such as menus and popovers, use 'popover'. +
+
+ +
+
+
+
+ foreground +
+
+
+ muted-foreground +
+
+
+ For primary and important text, use 'foreground'. When secondary text is available, + use 'muted-foreground' to create separation and readability. +
+
+
+ + +
+
+
+ text-base + 13px +
+
+
+
+ text-base is used as the base font size of the Viewer interface. Use when putting + text in panels or other interface elements next to medical images. +
+
+ +
+
+
+ text-lg + 14px +
+
+
+
+ text-lg can be used for dialog text or important messaging text within the Viewer. + Use this font size for easier reading on other standard text pages. +
+
+ +
+
+
+ text-xl + 16px +
+
+
+
+ text-xl can be used as headings within dialogs or messaging. +
+
+ +
+
+
+ text-2xl + 18px +
+
+
+
+ text-2xl can be used for page headers in the Viewer application or as dialog titles. +
+
+ +
+
+
+ text-3xl + 20px +
+
+
+
+ text-3xl can be used for extra large text size in the application. +
+
+ +
+
+
+ text-sm + 12px +
+
+
+
+ text-sm can be used for details that do not need to be standard sizes in the Viewer. +
+
+
+
+
+
+ ); +} + +function ShowcaseRow({ title, description, children, code }: ShowcaseRowProps) { + const [showCode, setShowCode] = useState(false); + + return ( +
+
+
+

{title}

+
+ +
+
+
+ {description &&

{description}

} +
+
+
{children}
+
+
+ {showCode && ( +
+          {code}
+        
+ )} +
+ ); +} + +// function ShowcaseRow({ title, description, children, code }: ShowcaseRowProps) { +// const [showCode, setShowCode] = useState(false); + +// return ( +//
+//
+//
+//

{title}

+// {description &&

{description}

} +//
+// +//
+//
{children}
+// {showCode && ( +//
+//           {code}
+//         
+// )} +//
+// ); +// } diff --git a/platform/docs/src/pages/components-list.tsx b/platform/docs/src/pages/components-list.tsx new file mode 100644 index 000000000..3888fc0b9 --- /dev/null +++ b/platform/docs/src/pages/components-list.tsx @@ -0,0 +1,651 @@ +import React, { useState } from 'react'; +import '../css/custom.css'; + +import Layout from '@theme/Layout'; +import { Label } from '../../../ui-next/src/components/Label'; +import { Input } from '../../../ui-next/src/components/Input'; +import { Separator } from '../../../ui-next/src/components/Separator'; +import { Tabs, TabsList, TabsTrigger } from '../../../ui-next/src/components/Tabs'; +import { + Select, + SelectTrigger, + SelectContent, + SelectItem, + SelectValue, +} from '../../../ui-next/src/components/Select'; +import { Button } from '../../../ui-next/src/components/Button'; +import { Switch } from '../../../ui-next/src/components/Switch'; +import { Checkbox } from '../../../ui-next/src/components/Checkbox'; +import { Toggle } from '../../../ui-next/src/components/Toggle'; +import { Slider } from '../../../ui-next/src/components/Slider'; +import { ScrollArea } from '../../../ui-next/src/components/ScrollArea'; +import { + DropdownMenu, + DropdownMenuTrigger, + DropdownMenuContent, + DropdownMenuItem, +} from '../../../ui-next/src/components/DropdownMenu'; +import { Icons } from '../../../ui-next/src/components/Icons'; +import { Toaster, toast } from '../../../ui-next/src/components/Sonner'; +import { DataRow } from '../../../ui-next/src/components/DataRow'; +import DataRowExample from './patterns/DataRowExample'; +import { + Card, + CardHeader, + CardFooter, + CardTitle, + CardDescription, + CardContent, +} from '../../../ui-next/src/components/Card'; + +interface ShowcaseRowProps { + title: string; + description?: string; + children: React.ReactNode; + code: string; +} + +export default function ComponentShowcase() { + // Handlers to trigger different types of toasts + const triggerSuccess = () => { + toast.success('This is a success toast!'); + }; + + const triggerError = () => { + toast.error('This is an error toast!'); + }; + + const triggerInfo = () => { + toast.info('This is an info toast!'); + }; + + const triggerWarning = () => { + toast.warning('This is a warning toast!'); + }; + + // Handler to trigger a toast.promise example + const triggerPromiseToast = () => { + const promise = () => + new Promise<{ name: string }>(resolve => + setTimeout(() => resolve({ name: 'Segmentation 1' }), 3000) + ); + + toast.promise(promise(), { + loading: 'Loading Segmentation...', + success: data => `${data.name} has been added`, + error: 'Error', + }); + }; + + // Handler to trigger a toast with description + const triggerDescriptionToast = () => { + toast.success('Completed', { + description: 'This is a detailed description of the success message.', + }); + }; + + // Handler to trigger a toast with an action button + const triggerActionButtonToast = () => { + toast.info('No active segmentation detected', { + description: 'Create a segmentation before using the Brush', + }); + }; + + // Handler to trigger a toast with a cancel button + const triggerCancelButtonToast = () => { + toast.error('No active segmentation detected', { + description: 'Create a segmentation before using the Brush', + }); + }; + + // Handler to trigger a toast with both action and cancel buttons + const triggerCombinedToast = () => { + toast.warning('Warning!', { + description: 'This is a warning with both action and cancel buttons.', + action: ( + + ), + cancel: ( + + ), + }); + }; + + // Handler to trigger a loading toast using Toaster's default loading icon + const showLoadingToast = () => { + toast.loading('Loading your data...'); + }; + + return ( + +
+
+
+ + + + + + Colors & Typography + + + Color Palette and Typography Guidelines + + + + + + + + + + Components + + + Essential UI Components with Variants + + + + + + + + + + Patterns + + + Component-Based Layout Examples + + + + +
+
+ +
+
+

Components

+
+ + {/* Alphabetically Sorted ShowcaseRows */} + Primary Button + + + + + + + + + `} + > +
+ + + + + +
+
+ + +
+
+ + + +
+ +
+
+ `} + > +
+ +
+ +
+
+ + + + {/* Render the DataRowExample component */} + + + + + + + + + Item 1 + Item 2 + Long name Item 3 + + + + + + + + + Item 1 + Item 2 + Long name Item 3 + + + + + + + + + Item 1 + Item 2 + Long name Item 3 + + + + + + + + + console.debug('Item 1')}>Item 1 + console.debug('Item 2')}>Item 2 + console.debug('Item 3')}>Long name Item 3 + + + `} + > +
+ + + + + + Item 1 + Item 2 + Long name Item 3 + + + + + + + + Item 1 + Item 2 + Long name Item 3 + + + + + + + + Item 1 + Item 2 + Long name Item 3 + + + + + + + + console.debug('Item 1')}> + Item 1 + + console.debug('Item 2')}> + Item 2 + + console.debug('Item 3')}> + Long name Item 3 + + + +
+
+ + +
+ +
+
+ +
+
+ `} + > +
+
+ +
+
+ +
+
+ + + + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco + laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat + non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore + magna aliqua. + + `} + > + + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor + incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud + exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure + dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. + Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt + mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipiscing elit, + sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. + + + + + + + + + Light + Dark + System + + + `} + > + + + + + + + `} + > +
+ +
+
+ + + `} + > + + + + + + + Circle + + Sphere + + Square + + + `} + > + + + Circle + + Sphere + + Square + + + + + + {/* Toast Examples Section */} + Simple message: +
+ + + + + +
+ Message with details: +
+ + + + +
+ {/* Render the Toaster component */} + +
+ + +
+ ); +} + +function ShowcaseRow({ title, description, children, code }: ShowcaseRowProps) { + const [showCode, setShowCode] = useState(false); + + return ( +
+
+
+

{title}

+
+ +
+
+
+ {description &&

{description}

} +
+
+
{children}
+
+
+ {showCode && ( +
+          {code}
+        
+ )} +
+ ); +} + +// function ShowcaseRow({ title, description, children, code }: ShowcaseRowProps) { +// const [showCode, setShowCode] = useState(false); + +// return ( +//
+//
+//
+//

{title}

+// {description &&

{description}

} +//
+// +//
+//
{children}
+// {showCode && ( +//
+//           {code}
+//         
+// )} +//
+// ); +// } diff --git a/platform/docs/src/pages/components.tsx b/platform/docs/src/pages/components.tsx new file mode 100644 index 000000000..ae2267035 --- /dev/null +++ b/platform/docs/src/pages/components.tsx @@ -0,0 +1,265 @@ +import React, { useState } from 'react'; +import '../css/custom.css'; + +import Layout from '@theme/Layout'; +import { Label } from '../../../ui-next/src/components/Label'; +import { Input } from '../../../ui-next/src/components/Input'; +import { Separator } from '../../../ui-next/src/components/Separator'; +import { Tabs, TabsList, TabsTrigger } from '../../../ui-next/src/components/Tabs'; +import { + Select, + SelectTrigger, + SelectContent, + SelectItem, + SelectValue, +} from '../../../ui-next/src/components/Select'; +import { Button } from '../../../ui-next/src/components/Button'; +import { Switch } from '../../../ui-next/src/components/Switch'; +import { Checkbox } from '../../../ui-next/src/components/Checkbox'; +import { Toggle } from '../../../ui-next/src/components/Toggle'; +import { Slider } from '../../../ui-next/src/components/Slider'; +import { ScrollArea } from '../../../ui-next/src/components/ScrollArea'; +import { + DropdownMenu, + DropdownMenuTrigger, + DropdownMenuContent, + DropdownMenuItem, +} from '../../../ui-next/src/components/DropdownMenu'; +import { Icons } from '../../../ui-next/src/components/Icons'; +import { Toaster, toast } from '../../../ui-next/src/components/Sonner'; +import { + Card, + CardHeader, + CardFooter, + CardTitle, + CardDescription, + CardContent, +} from '../../../ui-next/src/components/Card'; + +interface ShowcaseRowProps { + title: string; + description?: string; + children: React.ReactNode; + code: string; +} + +export default function ComponentShowcase() { + // Handlers to trigger different types of toasts + const triggerSuccess = () => { + toast.success('This is a success toast!'); + }; + + const triggerError = () => { + toast.error('This is an error toast!'); + }; + + const triggerInfo = () => { + toast.info('This is an info toast!'); + }; + + const triggerWarning = () => { + toast.warning('This is a warning toast!'); + }; + + // Handler to trigger a toast.promise example + const triggerPromiseToast = () => { + const promise = () => + new Promise<{ name: string }>(resolve => + setTimeout(() => resolve({ name: 'Segmentation 1' }), 3000) + ); + + toast.promise(promise(), { + loading: 'Loading Segmentation...', + success: data => `${data.name} has been added`, + error: 'Error', + }); + }; + + // Handler to trigger a toast with description + const triggerDescriptionToast = () => { + toast.success('Success heading', { + description: 'This is a detailed description of the success message.', + }); + }; + + // Handler to trigger a toast with an action button + const triggerActionButtonToast = () => { + toast.info('No active segmentation detected', { + description: 'Create a segmentation before using the Brush', + }); + }; + + // Handler to trigger a toast with a cancel button + const triggerCancelButtonToast = () => { + toast.error('No active segmentation detected', { + description: 'Create a segmentation before using the Brush', + }); + }; + + // Handler to trigger a toast with both action and cancel buttons + const triggerCombinedToast = () => { + toast.warning('Warning!', { + description: 'This is a warning with both action and cancel buttons.', + action: ( + + ), + cancel: ( + + ), + }); + }; + + // Handler to trigger a loading toast using Toaster's default loading icon + const showLoadingToast = () => { + toast.loading('Loading your data...'); + }; + + return ( + +
+
+
+ + + + + + Colors & Typography + + + Color Palette and Typography Guidelines + + + + + + + + + + Components + + + Essential UI Components with Variants + + + + + + + + + + Patterns + + + Component-Based Layout Examples + + + + +
+
+
+
+
+
+
+ ); +} + +function ShowcaseRow({ title, description, children, code }: ShowcaseRowProps) { + const [showCode, setShowCode] = useState(false); + + return ( +
+ {/* Header Section */} +
+
+

{title}

+
+ +
+ + {/* Content Section: 1/3 Left, 2/3 Right */} +
+ {/* Left Side: Title and Description */} +
+ {description &&

{description}

} +
+ + {/* Right Side: Example */} +
+
{children}
+
+
+ + {/* Code Section */} + {showCode && ( +
+          {code}
+        
+ )} +
+ ); +} + +// function ShowcaseRow({ title, description, children, code }: ShowcaseRowProps) { +// const [showCode, setShowCode] = useState(false); + +// return ( +//
+//
+//
+//

{title}

+// {description &&

{description}

} +//
+// +//
+//
{children}
+// {showCode && ( +//
+//           {code}
+//         
+// )} +//
+// ); +// } diff --git a/platform/docs/src/pages/patterns.tsx b/platform/docs/src/pages/patterns.tsx new file mode 100644 index 000000000..31958ba8b --- /dev/null +++ b/platform/docs/src/pages/patterns.tsx @@ -0,0 +1,321 @@ +import React, { useState } from 'react'; +import '../css/custom.css'; + +import Layout from '@theme/Layout'; +import { Label } from '../../../ui-next/src/components/Label'; +import { Input } from '../../../ui-next/src/components/Input'; +import { Separator } from '../../../ui-next/src/components/Separator'; +import { Tabs, TabsList, TabsTrigger } from '../../../ui-next/src/components/Tabs'; +import { + Select, + SelectTrigger, + SelectContent, + SelectItem, + SelectValue, +} from '../../../ui-next/src/components/Select'; +import { Button } from '../../../ui-next/src/components/Button'; +import { Switch } from '../../../ui-next/src/components/Switch'; +import { Checkbox } from '../../../ui-next/src/components/Checkbox'; +import { Toggle } from '../../../ui-next/src/components/Toggle'; +import { Slider } from '../../../ui-next/src/components/Slider'; +import { ScrollArea } from '../../../ui-next/src/components/ScrollArea'; +import { + DropdownMenu, + DropdownMenuTrigger, + DropdownMenuContent, + DropdownMenuItem, +} from '../../../ui-next/src/components/DropdownMenu'; +import { Icons } from '../../../ui-next/src/components/Icons'; +import { Toaster, toast } from '../../../ui-next/src/components/Sonner'; +import { + Card, + CardHeader, + CardFooter, + CardTitle, + CardDescription, + CardContent, +} from '../../../ui-next/src/components/Card'; + +interface ShowcaseRowProps { + title: string; + description?: string; + children: React.ReactNode; + code: string; +} + +export default function ComponentShowcase() { + // Function to open links in a new window + const openLinkInNewWindow = url => { + window.open(url, '_blank', 'noopener,noreferrer'); + }; + + // Handlers to trigger different types of toasts + const triggerSuccess = () => { + toast.success('This is a success toast!'); + }; + + const triggerError = () => { + toast.error('This is an error toast!'); + }; + + const triggerInfo = () => { + toast.info('This is an info toast!'); + }; + + const triggerWarning = () => { + toast.warning('This is a warning toast!'); + }; + + // Handler to trigger a toast.promise example + const triggerPromiseToast = () => { + const promise = () => + new Promise<{ name: string }>(resolve => + setTimeout(() => resolve({ name: 'Segmentation 1' }), 3000) + ); + + toast.promise(promise(), { + loading: 'Loading Segmentation...', + success: data => `${data.name} has been added`, + error: 'Error', + }); + }; + + // Handler to trigger a toast with description + const triggerDescriptionToast = () => { + toast.success('Success heading', { + description: 'This is a detailed description of the success message.', + }); + }; + + // Handler to trigger a toast with an action button + const triggerActionButtonToast = () => { + toast.info('No active segmentation detected', { + description: 'Create a segmentation before using the Brush', + }); + }; + + // Handler to trigger a toast with a cancel button + const triggerCancelButtonToast = () => { + toast.error('No active segmentation detected', { + description: 'Create a segmentation before using the Brush', + }); + }; + + // Handler to trigger a toast with both action and cancel buttons + const triggerCombinedToast = () => { + toast.warning('Warning!', { + description: 'This is a warning with both action and cancel buttons.', + action: ( + + ), + cancel: ( + + ), + }); + }; + + // Handler to trigger a loading toast using Toaster's default loading icon + const showLoadingToast = () => { + toast.loading('Loading your data...'); + }; + + return ( + +
+
+
+ + + + + + Colors & Typography + + + Color Palette and Typography Guidelines + + + + + + + + + + Components + + + Essential UI Components with Variants + + + + + + + + + + Patterns + + + Component-Based Layout Examples + + + + +
+
+ +
+

Patterns

+ + +
+ Uses the Data Row component to displays a list of segments. The current + "Segmentation" is chosen with a Select above the current list. +
+ +
+ } + code={` +aaa + `} + > +
+
+ Segmentation Panel +
+ + + +
+ Uses the Data Row component to displays a list of measurements. A custom "Label" + starts each row with measurement data appearing on the secondary row +
+ +
+ } + code={` +aaa + `} + > +
+
+ Measurements Panel +
+ + + +
+ ); +} + +function ShowcaseRow({ title, description, children, code }: ShowcaseRowProps) { + const [showCode, setShowCode] = useState(false); + + return ( +
+
+
+

{title}

+
+ +
+
+
+ {description &&

{description}

} +
+
+
{children}
+
+
+ {showCode && ( +
+          {code}
+        
+ )} +
+ ); +} + +// function ShowcaseRow({ title, description, children, code }: ShowcaseRowProps) { +// const [showCode, setShowCode] = useState(false); + +// return ( +//
+//
+//
+//

{title}

+// {description &&

{description}

} +//
+// +//
+//
{children}
+// {showCode && ( +//
+//           {code}
+//         
+// )} +//
+// ); +// } diff --git a/platform/docs/src/pages/patterns/DataRowExample.tsx b/platform/docs/src/pages/patterns/DataRowExample.tsx new file mode 100644 index 000000000..16127bf35 --- /dev/null +++ b/platform/docs/src/pages/patterns/DataRowExample.tsx @@ -0,0 +1,91 @@ +import React from 'react'; +import { DataRow } from '../../../../ui-next/src/components/DataRow'; +import { Button } from '../../../../ui-next/src/components/Button'; +import { Icons } from '../../../../ui-next/src/components/Icons'; + +// Mock data to demonstrate DataRow usage +const mockData = [ + { + id: 1, + title: 'Segment 1', + description: 'Description for Segment 1', + optionalField: 'Optional Info 1', + colorHex: '#FF5733', + details: 'Secondary details or text', + }, + { + id: 2, + title: 'Segment 2', + description: 'Description for Segment 2', + optionalField: 'Optional Info 2', + colorHex: '#33C1FF', + details: 'Secondary details or text', + }, + { + id: 3, + title: 'Segment 3', + description: 'Description for Segment 3', + optionalField: 'Optional Info 3', + colorHex: '#5533FF', + details: 'Secondary details or text', + }, +]; + +// Mock action options map +const actionOptionsMap = { + 'ROI Tools': ['Edit', 'Delete', 'View'], +}; + +interface DataItem { + id: number; + title: string; + description: string; + optionalField?: string; + colorHex?: string; + details?: string; + series?: string; +} + +interface ListGroup { + type: string; + items: DataItem[]; +} + +const DataRowExample: React.FC = () => { + const [selectedRowId, setSelectedRowId] = React.useState(null); + + const handleAction = (id: string, action: string) => { + console.log(`Action "${action}" triggered for item with id: ${id}`); + // Implement actual action logic here + }; + + const handleRowSelect = (id: string) => { + setSelectedRowId(prevSelectedId => (prevSelectedId === id ? null : id)); + }; + + return ( +
+ {mockData.map((item, index) => { + const compositeId = `ROI Tools-${item.id}-panel`; // Ensure unique composite ID + return ( + handleAction(compositeId, action)} + isSelected={selectedRowId === compositeId} + onSelect={() => handleRowSelect(compositeId)} + /> + ); + })} +
+ ); +}; + +export default DataRowExample; diff --git a/platform/docs/src/pages/patterns/patterns-measurements.tsx b/platform/docs/src/pages/patterns/patterns-measurements.tsx index 343bd908d..1daf39a6b 100644 --- a/platform/docs/src/pages/patterns/patterns-measurements.tsx +++ b/platform/docs/src/pages/patterns/patterns-measurements.tsx @@ -10,6 +10,7 @@ import { import { DataRow } from '../../../../ui-next/src/components/DataRow'; import { actionOptionsMap, dataList } from '../../../../ui-next/assets/data'; import BrowserOnly from '@docusaurus/BrowserOnly'; +import { TooltipProvider } from '../../../../ui-next/src/components/Tooltip'; interface DataItem { id: number; @@ -48,82 +49,84 @@ export default function Measurements() { return ( {() => ( -
- {/* Simulated Panel List for "Segmentation" */} -
- - {/* Segmentation Tools */} - - - Measurements - - -
-
2024-Jan-01
-
- Study title lorem ipsum +
+ + {/* Simulated Panel List for "Segmentation" */} +
+ + {/* Segmentation Tools */} + + + Measurements + + +
+
2024-Jan-01
+
+ Study title lorem ipsum +
-
-
-
- - +
+
+ + +
-
-
- {roiToolsGroup.items.map((item, index) => { - const compositeId = `${roiToolsGroup.type}-${item.id}-panel`; // Ensure unique composite ID - return ( - handleAction(compositeId, action)} - isSelected={selectedRowId === compositeId} - onSelect={() => handleRowSelect(compositeId)} - /> - ); - })} -
- - +
+ {roiToolsGroup.items.map((item, index) => { + const compositeId = `${roiToolsGroup.type}-${item.id}-panel`; // Ensure unique composite ID + return ( + handleAction(compositeId, action)} + isSelected={selectedRowId === compositeId} + onSelect={() => handleRowSelect(compositeId)} + /> + ); + })} +
+ + - {/* Additional Findings */} - - - Additional Findings - - -
-
-
- -
+ {/* Additional Findings */} + + + Additional Findings + + +
+
+
+ +
+
)} diff --git a/platform/docs/src/pages/patterns/patterns-segmentation.tsx b/platform/docs/src/pages/patterns/patterns-segmentation.tsx index 04d0088f7..c78b6c226 100644 --- a/platform/docs/src/pages/patterns/patterns-segmentation.tsx +++ b/platform/docs/src/pages/patterns/patterns-segmentation.tsx @@ -75,7 +75,7 @@ export default function SegmentationPanel() { } return ( -
+
{() => ( -
+
- - - - ); -} diff --git a/platform/docs/src/pages/ui-playground.tsx b/platform/docs/src/pages/ui-playground.tsx deleted file mode 100644 index c6161a6a4..000000000 --- a/platform/docs/src/pages/ui-playground.tsx +++ /dev/null @@ -1,699 +0,0 @@ -import React, { useState } from 'react'; -import '../css/custom.css'; - -import { Label } from '../../../ui-next/src/components/Label'; -import { Input } from '../../../ui-next/src/components/Input'; -import { Separator } from '../../../ui-next/src/components/Separator'; -import { Tabs, TabsList, TabsTrigger } from '../../../ui-next/src/components/Tabs'; -import { - Select, - SelectTrigger, - SelectContent, - SelectItem, - SelectValue, -} from '../../../ui-next/src/components/Select'; -import { Button } from '../../../ui-next/src/components/Button'; -import { Switch } from '../../../ui-next/src/components/Switch'; -import { Checkbox } from '../../../ui-next/src/components/Checkbox'; -import { Toggle } from '../../../ui-next/src/components/Toggle'; -import { Slider } from '../../../ui-next/src/components/Slider'; -import { ScrollArea } from '../../../ui-next/src/components/ScrollArea'; -import { - DropdownMenu, - DropdownMenuTrigger, - DropdownMenuContent, - DropdownMenuItem, -} from '../../../ui-next/src/components/DropdownMenu'; -import { Icons } from '../../../ui-next/src/components/Icons'; -import { Toaster, toast } from '../../../ui-next/src/components/Sonner'; - -interface ShowcaseRowProps { - title: string; - description?: string; - children: React.ReactNode; - code: string; -} - -export default function ComponentShowcase() { - // Handlers to trigger different types of toasts - const triggerSuccess = () => { - toast.success('This is a success toast!'); - }; - - const triggerError = () => { - toast.error('This is an error toast!'); - }; - - const triggerInfo = () => { - toast.info('This is an info toast!'); - }; - - const triggerWarning = () => { - toast.warning('This is a warning toast!'); - }; - - // Handler to trigger a toast.promise example - const triggerPromiseToast = () => { - const promise = () => - new Promise<{ name: string }>(resolve => - setTimeout(() => resolve({ name: 'Segmentation 1' }), 3000) - ); - - toast.promise(promise(), { - loading: 'Loading Segmentation...', - success: data => `${data.name} has been added`, - error: 'Error', - }); - }; - - // Handler to trigger a toast with description - const triggerDescriptionToast = () => { - toast.success('Success heading', { - description: 'This is a detailed description of the success message.', - }); - }; - - // Handler to trigger a toast with an action button - const triggerActionButtonToast = () => { - toast.info('Info heading', { - description: 'This is an info message with an action button.', - action: ( - - ), - }); - }; - - // Handler to trigger a toast with a cancel button - const triggerCancelButtonToast = () => { - toast.error('Error!', { - description: 'This is an error message with a cancel button.', - cancel: ( - - ), - }); - }; - - // Handler to trigger a toast with both action and cancel buttons - const triggerCombinedToast = () => { - toast.warning('Warning!', { - description: 'This is a warning with both action and cancel buttons.', - action: ( - - ), - cancel: ( - - ), - }); - }; - - // Handler to trigger a loading toast using Toaster's default loading icon - const showLoadingToast = () => { - toast.loading('Loading your data...'); - }; - - return ( -
-
- Primary Button - - - - - - - - - `} - > -
- - - - - -
-
- - Primary Button - - - - - `} - > -
- - - - - -
-
- - Primary Button - - - - - `} - > -
- - - - - -
-
- - -
- -
-
- -
-
- `} - > -
-
- -
-
- -
-
- - -
-
-
-
-
-
- `} - > -
-
-
-
-
-
-
-
- - - - `} - > -
- -
-
- - Standard text size (text-base) 14px
-
Small text size (text-sm) 13px
-
Extra small text size (text-xs) 12px
- `} - > -
-
Standard text size (text-base) 14px
-
Small text size (text-sm) 13px
-
Extra small text size (text-xs) 12px
-
- - - Large text size (text-lg) 16px
-
Extra large text size (text-xl) 18px
-
Double extra large text size (text-2xl) 20px
- `} - > -
-
Large text size (text-lg) 16px
-
Extra large text size (text-xl) 18px
-
Double extra large text size (text-2xl) 20px
-
- - - - - Circle - - Sphere - - Square - - - `} - > - - - Circle - - Sphere - - Square - - - - - - - - - - Light - Dark - System - - - `} - > - - - - - - - - - Item 1 - Item 2 - Long name Item 3 - - - - - - - - - Item 1 - Item 2 - Long name Item 3 - - - - - - - - - Item 1 - Item 2 - Long name Item 3 - - - - - - - - - console.debug('Item 1')}>Item 1 - console.debug('Item 2')}>Item 2 - console.debug('Item 3')}>Long name Item 3 - - - `} - > -
- - - - - - Item 1 - Item 2 - Long name Item 3 - - - - - - - - Item 1 - Item 2 - Long name Item 3 - - - - - - - - Item 1 - Item 2 - Long name Item 3 - - - - - - - - console.debug('Item 1')}>Item 1 - console.debug('Item 2')}>Item 2 - console.debug('Item 3')}> - Long name Item 3 - - - -
-
- - - `} - > - - - - - -
- -
-
- `} - > -
- -
- -
-
- - - Hello - `} - > - Hello - - - - -
- `} - > -
- -
- - - - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco - laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat - non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore - magna aliqua. - - `} - > - - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor - incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud - exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure - dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. - Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt - mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed - do eiusmod tempor incididunt ut labore et dolore magna aliqua. - - - - {/* Toast Examples Section */} -
- - - - - -
-
- - - - - - - - - - - {/* Render the Toaster component */} - - -
-
- ); -} - -function ShowcaseRow({ title, description, children, code }: ShowcaseRowProps) { - const [showCode, setShowCode] = useState(false); - - return ( -
-
-
-

{title}

- {description &&

{description}

} -
- -
-
{children}
- {showCode && ( -
-          {code}
-        
- )} -
- ); -} diff --git a/platform/docs/static/img/patterns-measurements.png b/platform/docs/static/img/patterns-measurements.png new file mode 100644 index 000000000..5c1870ec9 Binary files /dev/null and b/platform/docs/static/img/patterns-measurements.png differ diff --git a/platform/docs/static/img/patterns-segmentation.png b/platform/docs/static/img/patterns-segmentation.png new file mode 100644 index 000000000..8eec0d4a0 Binary files /dev/null and b/platform/docs/static/img/patterns-segmentation.png differ diff --git a/platform/docs/tailwind.config.js b/platform/docs/tailwind.config.js index f36b44a65..7e858df22 100644 --- a/platform/docs/tailwind.config.js +++ b/platform/docs/tailwind.config.js @@ -16,16 +16,18 @@ module.exports = { inter: ['Inter', 'sans-serif'], }, fontSize: { - xxs: '0.6875rem', // 11px - xs: '0.75rem', // 12px - sm: '0.8125rem', // 13px - base: '0.875rem', // 14px - lg: '1rem', // 16px - xl: '1.125rem', // 18px - '2xl': '1.25rem', // 20px - '3xl': '1.375rem', // 22px - '4xl': '1.5rem', // 24px - '5xl': '1.875rem', // 30px + xxs: '0.625rem', // 10px + xs: '0.6875rem', // 11px + sm: '0.75rem', // 12px + base: '0.8125rem', // 13px + lg: '0.875rem', // 14px + xl: '1rem', // 16px + // 2xl and above will be updated in an upcoming version + '2xl': '1.5rem', + '3xl': '1.875rem', + '4xl': '2.25rem', + '5xl': '3rem', + '6xl': '4rem', }, fontWeight: { hairline: '100', diff --git a/platform/ui-next/src/components/Accordion/Accordion.tsx b/platform/ui-next/src/components/Accordion/Accordion.tsx index bc9d7c2dc..e7e2dc306 100644 --- a/platform/ui-next/src/components/Accordion/Accordion.tsx +++ b/platform/ui-next/src/components/Accordion/Accordion.tsx @@ -28,7 +28,7 @@ const AccordionTrigger = React.forwardRef< svg]:rotate-270', '[&[data-state=closed]>svg]:rotate-90' @@ -48,7 +48,7 @@ const AccordionContent = React.forwardRef< >(({ className, children, ...props }, ref) => (
{children}
diff --git a/platform/ui-next/src/components/Button/Button.tsx b/platform/ui-next/src/components/Button/Button.tsx index e7668874a..48dbcc11f 100644 --- a/platform/ui-next/src/components/Button/Button.tsx +++ b/platform/ui-next/src/components/Button/Button.tsx @@ -5,14 +5,14 @@ import { cva, type VariantProps } from 'class-variance-authority'; import { cn } from '../../lib/utils'; const buttonVariants = cva( - 'inline-flex items-center justify-center whitespace-nowrap rounded text-sm font-normal leading-tight transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50', + 'inline-flex items-center justify-center whitespace-nowrap rounded text-base font-normal leading-tight transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50', { variants: { variant: { default: 'bg-primary/60 text-primary-foreground hover:bg-primary/100', destructive: 'bg-destructive text-destructive-foreground hover:bg-destructive/90', outline: - 'border border-input bg-background hover:bg-primary/25 hover:text-accent-foreground', + 'border border-primary/25 bg-background hover:bg-primary/25 text-primary hover:text-primary', secondary: 'bg-primary/40 text-secondary-foreground hover:bg-primary/60', ghost: 'font-normal text-primary hover:bg-primary/25', link: 'font-normal text-primary underline-offset-4 hover:underline', diff --git a/platform/ui-next/src/components/Calendar/Calendar.tsx b/platform/ui-next/src/components/Calendar/Calendar.tsx index 72ce7501a..8dfbc99f4 100644 --- a/platform/ui-next/src/components/Calendar/Calendar.tsx +++ b/platform/ui-next/src/components/Calendar/Calendar.tsx @@ -32,7 +32,7 @@ function Calendar({ className, classNames, showOutsideDays = true, ...props }: C head_row: 'flex', head_cell: 'text-muted-foreground rounded-md w-9 font-normal text-[0.8rem]', row: 'flex w-full mt-2', - cell: 'h-9 w-9 text-center text-sm p-0 relative [&:has([aria-selected].day-range-end)]:rounded-r-md [&:has([aria-selected].day-outside)]:bg-accent/50 [&:has([aria-selected])]:bg-accent first:[&:has([aria-selected])]:rounded-l-md last:[&:has([aria-selected])]:rounded-r-md focus-within:relative focus-within:z-20', + cell: 'h-9 w-9 text-center text-base p-0 relative [&:has([aria-selected].day-range-end)]:rounded-r-md [&:has([aria-selected].day-outside)]:bg-accent/50 [&:has([aria-selected])]:bg-accent first:[&:has([aria-selected])]:rounded-l-md last:[&:has([aria-selected])]:rounded-r-md focus-within:relative focus-within:z-20', day: cn( buttonVariants({ variant: 'ghost' }), 'h-9 w-9 p-0 font-normal aria-selected:opacity-100' diff --git a/platform/ui-next/src/components/Card/Card.tsx b/platform/ui-next/src/components/Card/Card.tsx new file mode 100644 index 000000000..162bbcb77 --- /dev/null +++ b/platform/ui-next/src/components/Card/Card.tsx @@ -0,0 +1,75 @@ +import * as React from 'react'; + +import { cn } from '../../lib/utils'; + +const Card = React.forwardRef>( + ({ className, ...props }, ref) => ( +
+ ) +); +Card.displayName = 'Card'; + +const CardHeader = React.forwardRef>( + ({ className, ...props }, ref) => ( +
+ ) +); +CardHeader.displayName = 'CardHeader'; + +const CardTitle = React.forwardRef>( + ({ className, ...props }, ref) => ( +

+ ) +); +CardTitle.displayName = 'CardTitle'; + +const CardDescription = React.forwardRef< + HTMLParagraphElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +

+)); +CardDescription.displayName = 'CardDescription'; + +const CardContent = React.forwardRef>( + ({ className, ...props }, ref) => ( +

+ ) +); +CardContent.displayName = 'CardContent'; + +const CardFooter = React.forwardRef>( + ({ className, ...props }, ref) => ( +
+ ) +); +CardFooter.displayName = 'CardFooter'; + +export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent }; diff --git a/platform/ui-next/src/components/Card/index.ts b/platform/ui-next/src/components/Card/index.ts new file mode 100644 index 000000000..7c9b951ca --- /dev/null +++ b/platform/ui-next/src/components/Card/index.ts @@ -0,0 +1,2 @@ +import { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent } from './Card'; +export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent }; diff --git a/platform/ui-next/src/components/Command/Command.tsx b/platform/ui-next/src/components/Command/Command.tsx index 5e4a14caf..1a672a348 100644 --- a/platform/ui-next/src/components/Command/Command.tsx +++ b/platform/ui-next/src/components/Command/Command.tsx @@ -47,7 +47,7 @@ const CommandInput = React.forwardRef< ((props, ref) => ( )); @@ -90,7 +90,7 @@ const CommandGroup = React.forwardRef< ) => { return ( ); diff --git a/platform/ui-next/src/components/DataRow/DataRow.tsx b/platform/ui-next/src/components/DataRow/DataRow.tsx index 1c83b2f57..781855fb3 100644 --- a/platform/ui-next/src/components/DataRow/DataRow.tsx +++ b/platform/ui-next/src/components/DataRow/DataRow.tsx @@ -199,14 +199,14 @@ const DataRow: React.FC = ({ {/* Hover Overlay */}
- {/* Number Box */} -
- {number} -
+ {/* Number Box */} +
+ {number} +
{/* Color Circle (Optional) */} {colorHex && ( @@ -224,7 +224,7 @@ const DataRow: React.FC = ({ @@ -240,7 +240,7 @@ const DataRow: React.FC = ({ ) : ( @@ -315,7 +315,7 @@ const DataRow: React.FC = ({ {details && details.primary?.length > 0 && (
-
+
{renderDetails(details.primary)}
diff --git a/platform/ui-next/src/components/DateRange/DateRange.tsx b/platform/ui-next/src/components/DateRange/DateRange.tsx index 9e2e39810..eebc7b916 100644 --- a/platform/ui-next/src/components/DateRange/DateRange.tsx +++ b/platform/ui-next/src/components/DateRange/DateRange.tsx @@ -90,7 +90,7 @@ export function DatePickerWithRange({ value={start} onChange={e => handleInputChange(e, 'start')} className={cn( - 'border-inputfield-main focus:border-inputfield-focus h-[32px] w-full justify-start rounded border bg-black py-[6.5px] pl-[6.5px] pr-[6.5px] text-left text-sm font-normal hover:bg-black hover:text-white', + 'border-inputfield-main focus:border-inputfield-focus h-[32px] w-full justify-start rounded border bg-black py-[6.5px] pl-[6.5px] pr-[6.5px] text-left text-base font-normal hover:bg-black hover:text-white', !start && 'text-muted-foreground' )} data-cy="input-date-range-start" @@ -127,7 +127,7 @@ export function DatePickerWithRange({ value={end} onChange={e => handleInputChange(e, 'end')} className={cn( - 'border-inputfield-main focus:border-inputfield-focus h-full w-full justify-start rounded border bg-black py-[6.5px] pl-[6.5px] pr-[6.5px] text-left text-sm font-normal hover:bg-black hover:text-white', + 'border-inputfield-main focus:border-inputfield-focus h-full w-full justify-start rounded border bg-black py-[6.5px] pl-[6.5px] pr-[6.5px] text-left text-base font-normal hover:bg-black hover:text-white', !end && 'text-muted-foreground' )} data-cy="input-date-range-end" diff --git a/platform/ui-next/src/components/Dialog/Dialog.tsx b/platform/ui-next/src/components/Dialog/Dialog.tsx index 0b67911aa..8e69250f6 100644 --- a/platform/ui-next/src/components/Dialog/Dialog.tsx +++ b/platform/ui-next/src/components/Dialog/Dialog.tsx @@ -19,7 +19,7 @@ const DialogOverlay = React.forwardRef< (({ className, ...props }, ref) => ( )); @@ -85,7 +85,7 @@ const DialogDescription = React.forwardRef< >(({ className, ...props }, ref) => ( )); diff --git a/platform/ui-next/src/components/DisplaySetMessageListTooltip/DisplaySetMessageListTooltip.tsx b/platform/ui-next/src/components/DisplaySetMessageListTooltip/DisplaySetMessageListTooltip.tsx index 48ec78c38..31f1d0118 100644 --- a/platform/ui-next/src/components/DisplaySetMessageListTooltip/DisplaySetMessageListTooltip.tsx +++ b/platform/ui-next/src/components/DisplaySetMessageListTooltip/DisplaySetMessageListTooltip.tsx @@ -23,9 +23,9 @@ const DisplaySetMessageListTooltip = ({ messages, id }): React.ReactNode => { /> -
+
(({ className, inset, ...props }, ref) => ( )); @@ -165,7 +165,7 @@ DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName; const DropdownMenuShortcut = ({ className, ...props }: React.HTMLAttributes) => { return ( ); diff --git a/platform/ui-next/src/components/Input/Input.tsx b/platform/ui-next/src/components/Input/Input.tsx index e33596c54..9b4da766f 100644 --- a/platform/ui-next/src/components/Input/Input.tsx +++ b/platform/ui-next/src/components/Input/Input.tsx @@ -10,7 +10,7 @@ const Input = React.forwardRef( { const currentStep = Shepherd.activeTour?.getCurrentStep(); if (currentStep) { const progress = document.createElement('span'); - progress.className = 'shepherd-progress text-base text-muted-foreground'; + progress.className = 'shepherd-progress text-lg text-muted-foreground'; progress.innerText = `${Shepherd.activeTour?.steps.indexOf(currentStep) + 1}/${Shepherd.activeTour?.steps.length}`; progress.style.position = 'absolute'; progress.style.left = '13px'; diff --git a/platform/ui-next/src/components/Select/Select.tsx b/platform/ui-next/src/components/Select/Select.tsx index f0178f3fa..f3f0639b1 100644 --- a/platform/ui-next/src/components/Select/Select.tsx +++ b/platform/ui-next/src/components/Select/Select.tsx @@ -17,7 +17,7 @@ const SelectTrigger = React.forwardRef< span]:line-clamp-1 hover:bg-primary/10 flex h-7 w-full items-center justify-between whitespace-nowrap rounded border bg-transparent px-2 py-2 text-sm shadow-sm focus:outline-none focus:ring-1 disabled:cursor-not-allowed disabled:opacity-50', + 'border-input text-foreground ring-offset-background placeholder:text-muted-foreground focus:ring-ring [&>span]:line-clamp-1 hover:bg-primary/10 flex h-7 w-full items-center justify-between whitespace-nowrap rounded border bg-transparent px-2 py-2 text-base shadow-sm focus:outline-none focus:ring-1 disabled:cursor-not-allowed disabled:opacity-50', className )} {...props} @@ -96,7 +96,7 @@ const SelectLabel = React.forwardRef< >(({ className, ...props }, ref) => ( )); @@ -109,7 +109,7 @@ const SelectItem = React.forwardRef< - + {selectedSort.label} diff --git a/platform/ui-next/src/components/StudyBrowserViewOptions/StudyBrowserViewOptions.tsx b/platform/ui-next/src/components/StudyBrowserViewOptions/StudyBrowserViewOptions.tsx index b926f7bbd..3e7a622ff 100644 --- a/platform/ui-next/src/components/StudyBrowserViewOptions/StudyBrowserViewOptions.tsx +++ b/platform/ui-next/src/components/StudyBrowserViewOptions/StudyBrowserViewOptions.tsx @@ -15,7 +15,7 @@ export function StudyBrowserViewOptions({ tabs, onSelectTab, activeTabName }: wi return ( - + {activeTab?.label} diff --git a/platform/ui-next/src/components/Tabs/Tabs.tsx b/platform/ui-next/src/components/Tabs/Tabs.tsx index f054032bb..47b55e59f 100644 --- a/platform/ui-next/src/components/Tabs/Tabs.tsx +++ b/platform/ui-next/src/components/Tabs/Tabs.tsx @@ -27,7 +27,7 @@ const TabsTrigger = React.forwardRef< )} - - {`${t('Number of studies')}: `} - + {numOfStudies > 100 ? '>100' : numOfStudies} + + {`${t('Studies')} `} +
@@ -99,7 +100,9 @@ const StudyListFilter = ({ {numOfStudies > 100 && (
-

{t('Filter list to 100 studies or less to enable sorting')}

+

+ {t('Filter list to 100 studies or less to enable sorting')} +

)} diff --git a/platform/ui/src/components/Typography/Typography.tsx b/platform/ui/src/components/Typography/Typography.tsx index 3f278831d..ed62f4926 100644 --- a/platform/ui/src/components/Typography/Typography.tsx +++ b/platform/ui/src/components/Typography/Typography.tsx @@ -32,7 +32,8 @@ const classes = { h3: 'text-4xl', h4: 'text-3xl', h5: 'text-2xl', - h6: 'text-xl', + // Using px value temporarily until larger fontsize variables are finalized + h6: 'text-[20px]', subtitle: 'text-lg', body: 'text-base', caption: 'text-xs',