);
}
diff --git a/ozone-ui/src/packages/recon/src/index.css b/ozone-ui/packages/recon/src/index.css
similarity index 100%
rename from ozone-ui/src/packages/recon/src/index.css
rename to ozone-ui/packages/recon/src/index.css
diff --git a/ozone-ui/src/packages/recon/src/main.tsx b/ozone-ui/packages/recon/src/main.tsx
similarity index 82%
rename from ozone-ui/src/packages/recon/src/main.tsx
rename to ozone-ui/packages/recon/src/main.tsx
index 1c6bbc3b61e1..814e0415e532 100644
--- a/ozone-ui/src/packages/recon/src/main.tsx
+++ b/ozone-ui/packages/recon/src/main.tsx
@@ -17,11 +17,17 @@
*/
import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
+import { ThemeProvider } from '@ozone-ui/shared';
+import '@fontsource/roboto/400.css';
+import '@fontsource/roboto/500.css';
+import '@fontsource/roboto/700.css';
import './index.css';
import App from './App';
createRoot(document.getElementById('root')!).render(
-
+
+
+
);
diff --git a/ozone-ui/src/packages/recon/src/vite-env.d.ts b/ozone-ui/packages/recon/src/vite-env.d.ts
similarity index 100%
rename from ozone-ui/src/packages/recon/src/vite-env.d.ts
rename to ozone-ui/packages/recon/src/vite-env.d.ts
diff --git a/ozone-ui/src/packages/recon/tsconfig.json b/ozone-ui/packages/recon/tsconfig.json
similarity index 100%
rename from ozone-ui/src/packages/recon/tsconfig.json
rename to ozone-ui/packages/recon/tsconfig.json
diff --git a/ozone-ui/src/packages/recon/vite.config.ts b/ozone-ui/packages/recon/vite.config.ts
similarity index 98%
rename from ozone-ui/src/packages/recon/vite.config.ts
rename to ozone-ui/packages/recon/vite.config.ts
index 9726123e879e..d0ed72b742fa 100644
--- a/ozone-ui/src/packages/recon/vite.config.ts
+++ b/ozone-ui/packages/recon/vite.config.ts
@@ -35,7 +35,7 @@ export default defineConfig({
],
build: {
target: 'es2015',
- outDir: '../../../build/recon',
+ outDir: '../../build/recon',
rollupOptions: {
output: {
chunkFileNames: 'static/js/[name]-[hash].js',
diff --git a/ozone-ui/src/packages/scm/index.html b/ozone-ui/packages/scm/index.html
similarity index 100%
rename from ozone-ui/src/packages/scm/index.html
rename to ozone-ui/packages/scm/index.html
diff --git a/ozone-ui/src/packages/recon/package.json b/ozone-ui/packages/scm/package.json
similarity index 94%
rename from ozone-ui/src/packages/recon/package.json
rename to ozone-ui/packages/scm/package.json
index 653da3d02455..d07ab0bbb4c6 100644
--- a/ozone-ui/src/packages/recon/package.json
+++ b/ozone-ui/packages/scm/package.json
@@ -1,5 +1,5 @@
{
- "name": "@hadoop-ui/ozone-recon",
+ "name": "@ozone-ui/ozone-scm",
"private": true,
"version": "1.0.0",
"scripts": {
@@ -8,7 +8,7 @@
"lint": "eslint ."
},
"dependencies": {
- "@hadoop-ui/shared": "workspace:*",
+ "@ozone-ui/shared": "workspace:*",
"@ant-design/icons": "^5.6.1",
"@fontsource/roboto": "^4.5.8",
"ag-charts-community": "^7.3.0",
diff --git a/ozone-ui/src/packages/scm/src/App.css b/ozone-ui/packages/scm/src/App.css
similarity index 100%
rename from ozone-ui/src/packages/scm/src/App.css
rename to ozone-ui/packages/scm/src/App.css
diff --git a/ozone-ui/src/packages/scm/src/App.tsx b/ozone-ui/packages/scm/src/App.tsx
similarity index 100%
rename from ozone-ui/src/packages/scm/src/App.tsx
rename to ozone-ui/packages/scm/src/App.tsx
diff --git a/ozone-ui/src/packages/scm/src/index.css b/ozone-ui/packages/scm/src/index.css
similarity index 100%
rename from ozone-ui/src/packages/scm/src/index.css
rename to ozone-ui/packages/scm/src/index.css
diff --git a/ozone-ui/src/packages/om/src/main.tsx b/ozone-ui/packages/scm/src/main.tsx
similarity index 82%
rename from ozone-ui/src/packages/om/src/main.tsx
rename to ozone-ui/packages/scm/src/main.tsx
index e5de33f5d7ba..e4b310bf1344 100644
--- a/ozone-ui/src/packages/om/src/main.tsx
+++ b/ozone-ui/packages/scm/src/main.tsx
@@ -17,11 +17,17 @@
*/
import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
+import { ThemeProvider } from '@ozone-ui/shared';
+import '@fontsource/roboto/400.css';
+import '@fontsource/roboto/500.css';
+import '@fontsource/roboto/700.css';
import App from './App';
import './index.css';
createRoot(document.getElementById('root')!).render(
-
+
+
+
);
diff --git a/ozone-ui/src/packages/scm/tsconfig.json b/ozone-ui/packages/scm/tsconfig.json
similarity index 100%
rename from ozone-ui/src/packages/scm/tsconfig.json
rename to ozone-ui/packages/scm/tsconfig.json
diff --git a/ozone-ui/src/packages/scm/vite.config.ts b/ozone-ui/packages/scm/vite.config.ts
similarity index 98%
rename from ozone-ui/src/packages/scm/vite.config.ts
rename to ozone-ui/packages/scm/vite.config.ts
index b817af1296fd..a1b7859a7d26 100644
--- a/ozone-ui/src/packages/scm/vite.config.ts
+++ b/ozone-ui/packages/scm/vite.config.ts
@@ -35,7 +35,7 @@ export default defineConfig({
],
build: {
target: 'es2015',
- outDir: '../../../build/scm',
+ outDir: '../../build/scm',
rollupOptions: {
output: {
chunkFileNames: 'static/js/[name]-[hash].js',
diff --git a/ozone-ui/src/packages/shared/icons/favicon.ico b/ozone-ui/packages/shared/icons/favicon.ico
similarity index 100%
rename from ozone-ui/src/packages/shared/icons/favicon.ico
rename to ozone-ui/packages/shared/icons/favicon.ico
diff --git a/ozone-ui/src/packages/shared/package.json b/ozone-ui/packages/shared/package.json
similarity index 95%
rename from ozone-ui/src/packages/shared/package.json
rename to ozone-ui/packages/shared/package.json
index a8f720c1f296..ba451ac43127 100644
--- a/ozone-ui/src/packages/shared/package.json
+++ b/ozone-ui/packages/shared/package.json
@@ -1,5 +1,5 @@
{
- "name": "@hadoop-ui/shared",
+ "name": "@ozone-ui/shared",
"private": true,
"version": "1.0.0",
"type": "module",
diff --git a/ozone-ui/packages/shared/src/components/Alert/Alert.tsx b/ozone-ui/packages/shared/src/components/Alert/Alert.tsx
new file mode 100644
index 000000000000..67e1b86cd263
--- /dev/null
+++ b/ozone-ui/packages/shared/src/components/Alert/Alert.tsx
@@ -0,0 +1,35 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import React from 'react';
+import { Alert as AntAlert, type AlertProps as AntAlertProps } from 'antd';
+import { radius } from '../../theme/tokens';
+
+export type AlertProps = AntAlertProps;
+
+/**
+ * Inline status banner. Thin wrapper over Ant Design's `Alert` applying the
+ * design-system radius; use the standard `type` (`info` / `success` /
+ * `warning` / `error`), `message`, `description`, `showIcon` and `closable`
+ * props. Matches the "Alert / Standard" component in the mockups.
+ */
+export const Alert: React.FC = ({ showIcon = true, style, ...rest }) => (
+
+);
+
+export default Alert;
diff --git a/ozone-ui/packages/shared/src/components/AppLayout/AppLayout.tsx b/ozone-ui/packages/shared/src/components/AppLayout/AppLayout.tsx
new file mode 100644
index 000000000000..8933c48e3ba1
--- /dev/null
+++ b/ozone-ui/packages/shared/src/components/AppLayout/AppLayout.tsx
@@ -0,0 +1,109 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import React from 'react';
+import { Layout, Typography } from 'antd';
+import { semanticColors, spacing, textStyles } from '../../theme/tokens';
+
+const { Header, Content } = Layout;
+
+export interface AppLayoutProps {
+ /** Navigation rail, typically the shared `Sidebar`. */
+ sider?: React.ReactNode;
+ /** Page/section title rendered in the header. */
+ title?: React.ReactNode;
+ /** Right-aligned header content (actions, user menu, breadcrumbs, ...). */
+ headerExtra?: React.ReactNode;
+ /** Main page content. */
+ children?: React.ReactNode;
+ /** Constrain content width and centre it (useful for form/detail pages). */
+ maxContentWidth?: number;
+}
+
+/**
+ * Application shell: a fixed navigation rail on the left, a top header with a
+ * title and optional actions, and a scrollable content area on the design-system
+ * layout background. Compose with the shared `Sidebar` for the `sider` slot.
+ */
+export const AppLayout: React.FC = ({
+ sider,
+ title,
+ headerExtra,
+ children,
+ maxContentWidth,
+}) => {
+ return (
+
+ {sider}
+
+ {(title || headerExtra) && (
+
+ {typeof title === 'string' ? (
+
+ {title}
+
+ ) : (
+ title
+ )}
+ {headerExtra && (
+
+ {headerExtra}
+
+ )}
+
+ )}
+
+
+ {children}
+
+
+
+
+ );
+};
+
+export default AppLayout;
diff --git a/ozone-ui/packages/shared/src/components/Card/Card.tsx b/ozone-ui/packages/shared/src/components/Card/Card.tsx
new file mode 100644
index 000000000000..a9f9a01b597e
--- /dev/null
+++ b/ozone-ui/packages/shared/src/components/Card/Card.tsx
@@ -0,0 +1,108 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import React, { useState } from 'react';
+import { Button, Card as AntCard, type CardProps as AntCardProps } from 'antd';
+import { DownOutlined, UpOutlined } from '@ant-design/icons';
+import { radius, semanticColors } from '../../theme/tokens';
+
+export interface CardProps extends AntCardProps {
+ /**
+ * Visual emphasis of the card surface.
+ * - `outlined` (default): white surface with a subtle border.
+ * - `elevated`: white surface with a soft shadow and no border.
+ * - `filled`: muted pewter surface, useful for nested/secondary panels.
+ */
+ emphasis?: 'outlined' | 'elevated' | 'filled';
+ /**
+ * Enable the "Card With Header" collapse affordance: a caret toggle in the
+ * header hides/shows the card body. Requires a `title`.
+ */
+ collapsible?: boolean;
+ /** Initial collapsed state when `collapsible` (uncontrolled). */
+ defaultCollapsed?: boolean;
+}
+
+const emphasisStyles: Record, React.CSSProperties> = {
+ outlined: {
+ border: `1px solid ${semanticColors.border}`,
+ boxShadow: 'none',
+ background: semanticColors.bgContainer,
+ },
+ elevated: {
+ border: 'none',
+ boxShadow: '0 1px 2px rgba(35, 43, 48, 0.06), 0 4px 12px rgba(35, 43, 48, 0.08)',
+ background: semanticColors.bgElevated,
+ },
+ filled: {
+ border: `1px solid ${semanticColors.border}`,
+ boxShadow: 'none',
+ background: semanticColors.bgLayout,
+ },
+};
+
+/**
+ * Surface container. Thin wrapper over Ant Design's `Card` that applies the
+ * design-system radius, borders and elevation presets, plus an optional
+ * collapsible header. All standard `Card` props are supported.
+ */
+export const Card: React.FC = ({
+ emphasis = 'outlined',
+ collapsible = false,
+ defaultCollapsed = false,
+ extra,
+ children,
+ style,
+ styles,
+ ...rest
+}) => {
+ const [collapsed, setCollapsed] = useState(defaultCollapsed);
+
+ const collapseToggle = collapsible ? (
+ : }
+ onClick={() => setCollapsed((c) => !c)}
+ />
+ ) : null;
+
+ const mergedExtra = collapsible ? (
+
+ {extra}
+ {collapseToggle}
+
+ ) : (
+ extra
+ );
+
+ return (
+
+ {collapsible && collapsed ? null : children}
+
+ );
+};
+
+export default Card;
diff --git a/ozone-ui/packages/shared/src/components/Chip/Chip.tsx b/ozone-ui/packages/shared/src/components/Chip/Chip.tsx
new file mode 100644
index 000000000000..d6308608de9e
--- /dev/null
+++ b/ozone-ui/packages/shared/src/components/Chip/Chip.tsx
@@ -0,0 +1,143 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import React from 'react';
+import { Tag, type TagProps } from 'antd';
+import { colors, radius } from '../../theme/tokens';
+
+/**
+ * Chip colours. Neutral, Blue, Green and Orange are the ones used across the
+ * Ozone mockups; the rest complete the palette.
+ */
+export type ChipColor = 'neutral' | 'blue' | 'green' | 'orange' | 'red' | 'amber';
+
+/** `full` = solid pill fill; `dot` = pill with a leading status dot. */
+export type ChipVariant = 'full' | 'dot';
+
+/** Chip sizes. */
+export type ChipSize = 'standard' | 'small';
+
+interface ChipPalette {
+ bg: string;
+ fg: string;
+ border: string;
+ dot: string;
+}
+
+const palettes: Record = {
+ neutral: {
+ bg: colors.pewter[50],
+ fg: colors.pewter[700],
+ border: colors.pewter[100],
+ dot: colors.pewter[500],
+ },
+ blue: {
+ bg: colors.blueNova[50],
+ fg: colors.blueNova[700],
+ border: colors.blueNova[100],
+ dot: colors.blueNova[600],
+ },
+ green: {
+ bg: colors.green[50],
+ fg: colors.green[700],
+ border: colors.green[100],
+ dot: colors.green[500],
+ },
+ orange: {
+ bg: colors.orange[50],
+ fg: colors.orange[600],
+ border: colors.orange[100],
+ dot: colors.orange[400],
+ },
+ red: { bg: colors.red[50], fg: colors.red[700], border: colors.red[100], dot: colors.red[500] },
+ amber: {
+ bg: colors.amber[100],
+ fg: colors.amber[700],
+ border: colors.amber[200],
+ dot: colors.amber[300],
+ },
+};
+
+const sizeStyles: Record = {
+ standard: { height: 22, paddingInline: 10, fontSize: 12, lineHeight: '20px' },
+ small: { height: 18, paddingInline: 8, fontSize: 11, lineHeight: '16px' },
+};
+
+export interface ChipProps extends Omit {
+ /** Colour family. Defaults to `neutral`. */
+ color?: ChipColor;
+ /** `full` (solid pill) or `dot` (with a leading status dot). Defaults to `full`. */
+ variant?: ChipVariant;
+ /** Chip size. Defaults to `standard`. */
+ size?: ChipSize;
+ /** Selected state renders a stronger fill. */
+ selected?: boolean;
+}
+
+/**
+ * Chip / status label. A pill-shaped `Tag` mapped to the design-system colours
+ * and sizes, supporting the `full`/`dot` variants, `standard`/`small` sizes, a
+ * `selected` state and Ant Design's `closable` (removable filter chips).
+ */
+export const Chip: React.FC = ({
+ color = 'neutral',
+ variant = 'full',
+ size = 'standard',
+ selected = false,
+ style,
+ children,
+ ...rest
+}) => {
+ const palette = palettes[color];
+ const dims = sizeStyles[size];
+
+ return (
+
+ {variant === 'dot' && (
+
+ )}
+ {children}
+
+ );
+};
+
+export default Chip;
diff --git a/ozone-ui/packages/shared/src/components/Icon/Icon.tsx b/ozone-ui/packages/shared/src/components/Icon/Icon.tsx
new file mode 100644
index 000000000000..4a4de97c39cf
--- /dev/null
+++ b/ozone-ui/packages/shared/src/components/Icon/Icon.tsx
@@ -0,0 +1,230 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import React from 'react';
+
+/**
+ * Names of the icons bundled with the design system. These are generic
+ * line-style glyphs (24x24, `currentColor`) covering the recurring icons in the
+ * Ozone screens. Rendered as inline SVG (no network requests, tree-shakeable).
+ */
+export type IconName =
+ | 'dashboard'
+ | 'health'
+ | 'settings'
+ | 'docs'
+ | 'service'
+ | 'reports'
+ | 'notifications'
+ | 'user'
+ | 'search'
+ | 'close'
+ | 'menu'
+ | 'chevron-right'
+ | 'chevron-left'
+ | 'chevron-down'
+ | 'chevron-up'
+ | 'external-link'
+ | 'copy';
+
+/** SVG path data for each icon, drawn on a 24x24 viewBox with `currentColor`. */
+const paths: Record = {
+ dashboard: ,
+ health: (
+
+ ),
+ settings: (
+
+ ),
+ docs: (
+
+ ),
+ service: (
+
+ ),
+ reports: (
+
+ ),
+ notifications: (
+
+ ),
+ user: (
+
+ ),
+ search: (
+
+ ),
+ close: (
+
+ ),
+ menu: (
+
+ ),
+ 'chevron-right': (
+
+ ),
+ 'chevron-left': (
+
+ ),
+ 'chevron-down': (
+
+ ),
+ 'chevron-up': (
+
+ ),
+ 'external-link': (
+
+ ),
+ copy: (
+
+ ),
+};
+
+export interface IconProps extends Omit, 'name'> {
+ /** Which bundled icon to render. */
+ name: IconName;
+ /** Pixel size (width and height). Defaults to 16. */
+ size?: number;
+}
+
+/**
+ * Renders a design-system icon as inline SVG using `currentColor`, so it
+ * inherits the surrounding text colour and can be sized via the `size` prop.
+ */
+export const Icon: React.FC = ({ name, size = 16, style, ...rest }) => (
+
+);
+
+export default Icon;
diff --git a/ozone-ui/packages/shared/src/components/IconButton/IconButton.tsx b/ozone-ui/packages/shared/src/components/IconButton/IconButton.tsx
new file mode 100644
index 000000000000..078683f207c9
--- /dev/null
+++ b/ozone-ui/packages/shared/src/components/IconButton/IconButton.tsx
@@ -0,0 +1,70 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import React from 'react';
+import { Button, Tooltip, type ButtonProps } from 'antd';
+
+export interface IconButtonProps extends Omit {
+ /** The icon to render (e.g. an `` or an Ant Design icon). */
+ icon: React.ReactNode;
+ /** Accessible label; also used as the tooltip when `tooltip` is not set. */
+ label: string;
+ /** Optional tooltip text (defaults to `label`). Pass `null` to disable. */
+ tooltip?: string | null;
+ /** Button footprint. `large` = 40px, `standard` (default) = 32px. */
+ size?: 'large' | 'standard';
+}
+
+/**
+ * Square icon-only button. Wraps Ant Design's `Button` with a consistent
+ * footprint, an accessible label and an optional tooltip. Matches the
+ * "Icon Button" component used in the top bar, tables and toolbars.
+ */
+export const IconButton: React.FC = ({
+ icon,
+ label,
+ tooltip,
+ size = 'standard',
+ type = 'text',
+ style,
+ ...rest
+}) => {
+ const dimension = size === 'large' ? 40 : 32;
+ const button = (
+
+ );
+
+ const tip = tooltip === undefined ? label : tooltip;
+ return tip ? {button} : button;
+};
+
+export default IconButton;
diff --git a/ozone-ui/packages/shared/src/components/KeyValuePair/KeyValuePair.tsx b/ozone-ui/packages/shared/src/components/KeyValuePair/KeyValuePair.tsx
new file mode 100644
index 000000000000..dba2a175be80
--- /dev/null
+++ b/ozone-ui/packages/shared/src/components/KeyValuePair/KeyValuePair.tsx
@@ -0,0 +1,109 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import React from 'react';
+import { Typography } from 'antd';
+import { semanticColors, spacing, textStyles } from '../../theme/tokens';
+
+export interface KeyValuePairProps {
+ /** The label (key) text. */
+ label: React.ReactNode;
+ /** The value. If `href` is set, it renders as a text link. */
+ value: React.ReactNode;
+ /** Render the value as a link to this destination ("Standard Link" variant). */
+ href?: string;
+ /** Layout direction. `vertical` (default) stacks label over value. */
+ layout?: 'vertical' | 'horizontal';
+ /** Width of the label column when `layout="horizontal"`. */
+ labelWidth?: number | string;
+ /** Allow the value to be copied (adds an inline copy affordance). */
+ copyable?: boolean;
+ style?: React.CSSProperties;
+}
+
+/**
+ * Key-value pair. Displays a small secondary label with its value, matching
+ * the "Key-Value Pair / Standard" and "Standard Link" components used across the
+ * Ozone detail cards.
+ */
+export const KeyValuePair: React.FC = ({
+ label,
+ value,
+ href,
+ layout = 'vertical',
+ labelWidth = 160,
+ copyable = false,
+ style,
+}) => {
+ const isHorizontal = layout === 'horizontal';
+
+ const labelNode = (
+
+ {label}
+
+ );
+
+ const valueNode = href ? (
+
+ {value}
+
+ ) : (
+
+ {value}
+
+ );
+
+ return (
+
+ {labelNode}
+ {valueNode}
+
+ );
+};
+
+export default KeyValuePair;
diff --git a/ozone-ui/packages/shared/src/components/PageHeader/PageHeader.tsx b/ozone-ui/packages/shared/src/components/PageHeader/PageHeader.tsx
new file mode 100644
index 000000000000..7c54c4636713
--- /dev/null
+++ b/ozone-ui/packages/shared/src/components/PageHeader/PageHeader.tsx
@@ -0,0 +1,99 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import React from 'react';
+import { Typography } from 'antd';
+import { semanticColors, spacing, textStyles } from '../../theme/tokens';
+
+export interface PageHeaderProps {
+ /** Page title. */
+ title: React.ReactNode;
+ /** Optional supporting text under the title. */
+ subtitle?: React.ReactNode;
+ /** Optional content rendered above the title (e.g. breadcrumbs). */
+ breadcrumb?: React.ReactNode;
+ /** Right-aligned actions (buttons, filters, ...). */
+ actions?: React.ReactNode;
+ style?: React.CSSProperties;
+}
+
+/**
+ * Page header. Renders the page title with optional breadcrumb, subtitle and
+ * right-aligned actions, matching the "Page Header" component used at the top of
+ * the Ozone content area.
+ */
+export const PageHeader: React.FC = ({
+ title,
+ subtitle,
+ breadcrumb,
+ actions,
+ style,
+}) => {
+ return (
+
+ );
+};
+
+export default PageHeader;
diff --git a/ozone-ui/src/packages/shared/src/components/Sidebar/Sidebar.tsx b/ozone-ui/packages/shared/src/components/Sidebar/Sidebar.tsx
similarity index 100%
rename from ozone-ui/src/packages/shared/src/components/Sidebar/Sidebar.tsx
rename to ozone-ui/packages/shared/src/components/Sidebar/Sidebar.tsx
diff --git a/ozone-ui/packages/shared/src/components/TextLink/TextLink.tsx b/ozone-ui/packages/shared/src/components/TextLink/TextLink.tsx
new file mode 100644
index 000000000000..fcd7a48af648
--- /dev/null
+++ b/ozone-ui/packages/shared/src/components/TextLink/TextLink.tsx
@@ -0,0 +1,66 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import React from 'react';
+import { Typography } from 'antd';
+import type { LinkProps } from 'antd/es/typography/Link';
+import { textStyles } from '../../theme/tokens';
+import Icon from '../Icon/Icon';
+
+export interface TextLinkProps extends LinkProps {
+ /** Render as an external link (opens in a new tab, shows an external icon). */
+ external?: boolean;
+ /** Text size. Defaults to `standard`. */
+ size?: 'standard' | 'small';
+}
+
+/**
+ * Inline text link built on Ant Design's `Typography.Link`, themed with the
+ * design-system link colour and type scale. Set `external` for links that open
+ * in a new tab (adds a trailing external-link glyph).
+ */
+export const TextLink: React.FC = ({
+ external = false,
+ size = 'standard',
+ style,
+ children,
+ ...rest
+}) => {
+ const scale = size === 'small' ? textStyles.bodySmall : textStyles.bodyStandard;
+ const externalProps = external ? { target: '_blank', rel: 'noopener noreferrer' } : {};
+
+ return (
+
+ {children}
+ {external && }
+
+ );
+};
+
+export default TextLink;
diff --git a/ozone-ui/packages/shared/src/components/UtilityBar/UtilityBar.tsx b/ozone-ui/packages/shared/src/components/UtilityBar/UtilityBar.tsx
new file mode 100644
index 000000000000..ebdce680bf47
--- /dev/null
+++ b/ozone-ui/packages/shared/src/components/UtilityBar/UtilityBar.tsx
@@ -0,0 +1,93 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import React from 'react';
+import { colors, fontFamilies, semanticColors, spacing, textStyles } from '../../theme/tokens';
+
+export interface UtilityBarProps {
+ /** Left slot, e.g. an app switcher or menu button. */
+ leading?: React.ReactNode;
+ /** Product / app title shown next to the leading slot. */
+ title?: React.ReactNode;
+ /** Optional centre slot (e.g. global search). */
+ center?: React.ReactNode;
+ /** Right slot, e.g. notification/user icon buttons. */
+ actions?: React.ReactNode;
+ /** Height in px. Defaults to 48. */
+ height?: number;
+ style?: React.CSSProperties;
+}
+
+/**
+ * Global top utility bar (the dark chrome at the very top of every screen).
+ * Provides leading/title, an optional centre slot and right-aligned actions.
+ */
+export const UtilityBar: React.FC = ({
+ leading,
+ title,
+ center,
+ actions,
+ height = 48,
+ style,
+}) => (
+
+
+ {leading}
+ {title && (
+
+ {title}
+
+ )}
+
+
+ {center &&
{center}
}
+
+
+ {actions}
+
+
+);
+
+export default UtilityBar;
diff --git a/ozone-ui/packages/shared/src/index.ts b/ozone-ui/packages/shared/src/index.ts
new file mode 100644
index 000000000000..cae515269616
--- /dev/null
+++ b/ozone-ui/packages/shared/src/index.ts
@@ -0,0 +1,46 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Theme (design tokens + Ant Design theme + provider)
+export * from './theme';
+
+// Components
+export { default as Sidebar } from './components/Sidebar/Sidebar';
+export { default as AppLayout } from './components/AppLayout/AppLayout';
+export type { AppLayoutProps } from './components/AppLayout/AppLayout';
+export { default as UtilityBar } from './components/UtilityBar/UtilityBar';
+export type { UtilityBarProps } from './components/UtilityBar/UtilityBar';
+export { default as PageHeader } from './components/PageHeader/PageHeader';
+export type { PageHeaderProps } from './components/PageHeader/PageHeader';
+export { default as Card } from './components/Card/Card';
+export type { CardProps } from './components/Card/Card';
+export { default as KeyValuePair } from './components/KeyValuePair/KeyValuePair';
+export type { KeyValuePairProps } from './components/KeyValuePair/KeyValuePair';
+export { default as Chip } from './components/Chip/Chip';
+export type { ChipProps, ChipColor, ChipVariant, ChipSize } from './components/Chip/Chip';
+export { default as Alert } from './components/Alert/Alert';
+export type { AlertProps } from './components/Alert/Alert';
+export { default as TextLink } from './components/TextLink/TextLink';
+export type { TextLinkProps } from './components/TextLink/TextLink';
+export { default as IconButton } from './components/IconButton/IconButton';
+export type { IconButtonProps } from './components/IconButton/IconButton';
+export { default as Icon } from './components/Icon/Icon';
+export type { IconProps, IconName } from './components/Icon/Icon';
+
+// Utils
+export * from './utils/menuUtils';
diff --git a/ozone-ui/packages/shared/src/theme/ThemeProvider.tsx b/ozone-ui/packages/shared/src/theme/ThemeProvider.tsx
new file mode 100644
index 000000000000..93b7f52399ca
--- /dev/null
+++ b/ozone-ui/packages/shared/src/theme/ThemeProvider.tsx
@@ -0,0 +1,50 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import React from 'react';
+import { ConfigProvider, type ThemeConfig } from 'antd';
+import { ozoneTheme } from './antdTheme';
+
+export interface ThemeProviderProps {
+ children: React.ReactNode;
+ /**
+ * Optional partial theme merged on top of the base Ozone theme, for
+ * app-specific tweaks. Only the `token`/`components` maps are shallow-merged.
+ */
+ themeOverrides?: ThemeConfig;
+}
+
+/**
+ * Wraps an application subtree with the Ozone UI Ant Design theme. Every Ozone
+ * app should mount this once near its root so all Ant Design components inherit
+ * the design-system colours, typography and radii.
+ */
+export const ThemeProvider: React.FC = ({ children, themeOverrides }) => {
+ const theme: ThemeConfig = themeOverrides
+ ? {
+ ...ozoneTheme,
+ ...themeOverrides,
+ token: { ...ozoneTheme.token, ...themeOverrides.token },
+ components: { ...ozoneTheme.components, ...themeOverrides.components },
+ }
+ : ozoneTheme;
+
+ return {children};
+};
+
+export default ThemeProvider;
diff --git a/ozone-ui/packages/shared/src/theme/antdTheme.ts b/ozone-ui/packages/shared/src/theme/antdTheme.ts
new file mode 100644
index 000000000000..9d573ad4dc75
--- /dev/null
+++ b/ozone-ui/packages/shared/src/theme/antdTheme.ts
@@ -0,0 +1,128 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import type { ThemeConfig } from 'antd';
+import { colors, fontFamilies, radius, semanticColors, textStyles } from './tokens';
+
+/**
+ * Ant Design v5 theme derived from the Ozone UI design tokens.
+ *
+ * Pass this to `` (see `ThemeProvider`) so
+ * every Ant Design component picks up the design-system colours, typography and
+ * radii without per-component overrides.
+ */
+export const ozoneTheme: ThemeConfig = {
+ token: {
+ // Brand / status colours
+ colorPrimary: semanticColors.brand,
+ colorInfo: semanticColors.info,
+ colorSuccess: semanticColors.success,
+ colorWarning: semanticColors.warning,
+ colorError: semanticColors.error,
+ colorLink: semanticColors.info,
+
+ // Neutrals / text
+ colorText: semanticColors.textPrimary,
+ colorTextSecondary: semanticColors.textSecondary,
+ colorTextTertiary: semanticColors.textTertiary,
+ colorTextDisabled: semanticColors.textDisabled,
+ colorBorder: semanticColors.border,
+ colorBorderSecondary: semanticColors.border,
+ colorBgLayout: semanticColors.bgLayout,
+ colorBgContainer: semanticColors.bgContainer,
+ colorBgElevated: semanticColors.bgElevated,
+ colorFillSecondary: semanticColors.fill,
+
+ // Typography
+ fontFamily: fontFamilies.base,
+ fontFamilyCode: fontFamilies.monospace,
+ fontSize: textStyles.bodyStandard.fontSize,
+ fontSizeSM: textStyles.bodySmall.fontSize,
+ fontSizeLG: textStyles.bodyLarge.fontSize,
+ fontSizeHeading1: textStyles.h1.fontSize,
+ fontSizeHeading2: textStyles.h2.fontSize,
+ fontSizeHeading3: textStyles.h3.fontSize,
+ fontSizeHeading4: textStyles.h4.fontSize,
+ fontSizeHeading5: textStyles.h5.fontSize,
+ lineHeight: textStyles.bodyStandard.lineHeight / textStyles.bodyStandard.fontSize,
+
+ // Shape
+ borderRadius: radius.md,
+ borderRadiusLG: radius.lg,
+ borderRadiusSM: radius.sm,
+
+ // Control sizing kept aligned with the 4px spacing rhythm.
+ controlHeight: 32,
+ wireframe: false,
+ },
+ components: {
+ Layout: {
+ headerBg: semanticColors.bgContainer,
+ headerColor: semanticColors.textPrimary,
+ headerHeight: 56,
+ headerPadding: '0 24px',
+ bodyBg: semanticColors.bgLayout,
+ // The navigation rail is a deep pewter surface.
+ siderBg: colors.pewter[900],
+ triggerBg: colors.pewter[800],
+ },
+ Menu: {
+ darkItemBg: colors.pewter[900],
+ darkSubMenuItemBg: colors.pewter[950],
+ darkItemSelectedBg: colors.orange[400],
+ darkItemSelectedColor: 'rgb(255, 255, 255)',
+ darkItemColor: colors.pewter[200],
+ darkItemHoverBg: colors.pewter[800],
+ itemBorderRadius: radius.md,
+ itemSelectedBg: colors.orange[50],
+ itemSelectedColor: colors.orange[500],
+ },
+ Card: {
+ borderRadiusLG: radius.lg,
+ colorBorderSecondary: semanticColors.border,
+ headerFontSize: textStyles.h3.fontSize,
+ paddingLG: 20,
+ },
+ Button: {
+ borderRadius: radius.md,
+ fontWeight: 500,
+ primaryShadow: 'none',
+ defaultShadow: 'none',
+ },
+ Tag: {
+ borderRadiusSM: radius.pill,
+ defaultBg: colors.pewter[50],
+ defaultColor: semanticColors.textSecondary,
+ },
+ Table: {
+ headerBg: colors.pewter[25],
+ headerColor: semanticColors.textSecondary,
+ borderColor: semanticColors.border,
+ rowHoverBg: colors.pewter[25],
+ },
+ Input: {
+ borderRadius: radius.md,
+ colorBorder: semanticColors.borderStrong,
+ },
+ Alert: {
+ borderRadiusLG: radius.md,
+ },
+ },
+};
+
+export default ozoneTheme;
diff --git a/ozone-ui/src/packages/shared/src/index.ts b/ozone-ui/packages/shared/src/theme/index.ts
similarity index 79%
rename from ozone-ui/src/packages/shared/src/index.ts
rename to ozone-ui/packages/shared/src/theme/index.ts
index 209bc46478ef..8b73edf85954 100644
--- a/ozone-ui/src/packages/shared/src/index.ts
+++ b/ozone-ui/packages/shared/src/theme/index.ts
@@ -15,8 +15,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-// Components
-export { default as Sidebar } from './components/Sidebar/Sidebar';
-// Utils
-export * from './utils/menuUtils';
+export * from './tokens';
+export { ozoneTheme, default as ozoneThemeDefault } from './antdTheme';
+export { ThemeProvider } from './ThemeProvider';
+export type { ThemeProviderProps } from './ThemeProvider';
diff --git a/ozone-ui/packages/shared/src/theme/tokens.ts b/ozone-ui/packages/shared/src/theme/tokens.ts
new file mode 100644
index 000000000000..2034d93bd167
--- /dev/null
+++ b/ozone-ui/packages/shared/src/theme/tokens.ts
@@ -0,0 +1,211 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Ozone UI design tokens.
+ *
+ * The single source of truth for colour and typography across the Ozone UI
+ * monorepo. Prefer referencing these tokens (or the derived Ant Design theme in
+ * `antdTheme.ts`) over hard-coding raw colour/size values.
+ */
+
+/** Full colour ramps. The `*` marked step is each family's canonical value. */
+export const colors = {
+ pewter: {
+ 25: 'rgb(244, 247, 249)',
+ 50: 'rgb(225, 234, 240)',
+ 100: 'rgb(206, 219, 228)', // base
+ 200: 'rgb(184, 200, 212)',
+ 300: 'rgb(163, 181, 194)',
+ 400: 'rgb(133, 154, 168)',
+ 500: 'rgb(110, 131, 145)',
+ 600: 'rgb(86, 104, 117)',
+ 700: 'rgb(69, 81, 90)',
+ 800: 'rgb(51, 60, 67)',
+ 900: 'rgb(35, 43, 48)',
+ 950: 'rgb(26, 32, 36)',
+ },
+ blueNova: {
+ 25: 'rgb(249, 249, 255)',
+ 50: 'rgb(240, 240, 255)',
+ 100: 'rgb(220, 220, 252)',
+ 200: 'rgb(199, 199, 253)',
+ 300: 'rgb(172, 172, 252)',
+ 400: 'rgb(144, 144, 252)',
+ 500: 'rgb(115, 115, 250)',
+ 600: 'rgb(85, 85, 249)', // base
+ 700: 'rgb(59, 46, 219)',
+ 800: 'rgb(48, 34, 144)',
+ 900: 'rgb(28, 19, 78)',
+ 950: 'rgb(19, 13, 50)',
+ },
+ orange: {
+ 25: 'rgb(255, 244, 240)',
+ 50: 'rgb(255, 227, 214)',
+ 100: 'rgb(255, 205, 184)',
+ 200: 'rgb(255, 169, 133)',
+ 300: 'rgb(255, 126, 71)',
+ 400: 'rgb(255, 85, 13)', // base (brand primary)
+ 500: 'rgb(224, 67, 0)',
+ 600: 'rgb(179, 53, 0)',
+ 700: 'rgb(133, 39, 0)',
+ 800: 'rgb(92, 27, 0)',
+ 900: 'rgb(46, 14, 0)',
+ 950: 'rgb(20, 6, 0)',
+ },
+ red: {
+ 25: 'rgb(255, 248, 248)',
+ 50: 'rgb(254, 234, 234)',
+ 100: 'rgb(254, 216, 216)',
+ 200: 'rgb(253, 192, 191)',
+ 300: 'rgb(252, 156, 155)',
+ 400: 'rgb(251, 115, 113)',
+ 500: 'rgb(247, 65, 59)',
+ 600: 'rgb(222, 36, 28)',
+ 700: 'rgb(181, 24, 16)', // base
+ 800: 'rgb(126, 13, 8)',
+ 900: 'rgb(74, 4, 3)',
+ 950: 'rgb(48, 2, 1)',
+ },
+ green: {
+ 25: 'rgb(240, 252, 241)',
+ 50: 'rgb(206, 245, 210)',
+ 100: 'rgb(171, 237, 180)',
+ 200: 'rgb(126, 229, 147)',
+ 300: 'rgb(68, 212, 104)',
+ 400: 'rgb(0, 189, 68)',
+ 500: 'rgb(0, 162, 57)',
+ 600: 'rgb(0, 138, 47)',
+ 700: 'rgb(0, 115, 38)', // base
+ 800: 'rgb(0, 78, 23)',
+ 900: 'rgb(0, 43, 9)',
+ 950: 'rgb(0, 27, 4)',
+ },
+ amber: {
+ 50: 'rgb(255, 245, 231)',
+ 100: 'rgb(255, 235, 204)',
+ 200: 'rgb(255, 213, 122)',
+ 300: 'rgb(247, 194, 0)', // base
+ 400: 'rgb(207, 162, 0)',
+ 500: 'rgb(172, 134, 0)',
+ 600: 'rgb(135, 105, 0)',
+ 700: 'rgb(103, 79, 0)',
+ 800: 'rgb(70, 53, 0)',
+ 900: 'rgb(41, 30, 0)',
+ },
+} as const;
+
+/**
+ * Semantic colour aliases. UI code should prefer these over raw ramp steps so
+ * intent is explicit and re-theming stays centralised.
+ */
+export const semanticColors = {
+ brand: colors.orange[400],
+ brandHover: colors.orange[300],
+ brandActive: colors.orange[500],
+ info: colors.blueNova[600],
+ success: colors.green[700],
+ warning: colors.amber[300],
+ error: colors.red[700],
+ textPrimary: colors.pewter[900],
+ textSecondary: colors.pewter[600],
+ textTertiary: colors.pewter[500],
+ textDisabled: colors.pewter[400],
+ border: colors.pewter[100],
+ borderStrong: colors.pewter[200],
+ bgLayout: colors.pewter[25],
+ bgContainer: 'rgb(255, 255, 255)',
+ bgElevated: 'rgb(255, 255, 255)',
+ fill: colors.pewter[50],
+ skeleton: colors.pewter[50],
+} as const;
+
+/** Font families. Roboto is the primary UI face; app titles use Plus Jakarta Sans. */
+export const fontFamilies = {
+ base: "'Roboto', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif",
+ monospace: "'Roboto Mono', 'SFMono-Regular', Consolas, 'Liberation Mono', monospace",
+ appTitle: "'Plus Jakarta Sans', 'Roboto', sans-serif",
+} as const;
+
+export interface TextStyle {
+ fontFamily: string;
+ fontSize: number;
+ fontWeight: number;
+ lineHeight: number;
+}
+
+/** Type scale. Sizes/line-heights are in px. */
+export const textStyles = {
+ displayLarge: { fontFamily: fontFamilies.base, fontSize: 24, fontWeight: 600, lineHeight: 32 },
+ h1: { fontFamily: fontFamilies.base, fontSize: 20, fontWeight: 600, lineHeight: 24 },
+ h2: { fontFamily: fontFamilies.base, fontSize: 18, fontWeight: 600, lineHeight: 24 },
+ h3: { fontFamily: fontFamilies.base, fontSize: 16, fontWeight: 600, lineHeight: 20 },
+ h4: { fontFamily: fontFamilies.base, fontSize: 14, fontWeight: 600, lineHeight: 20 },
+ h5: { fontFamily: fontFamilies.base, fontSize: 12, fontWeight: 600, lineHeight: 16 },
+ h6: { fontFamily: fontFamilies.base, fontSize: 12, fontWeight: 600, lineHeight: 16 },
+ bodyLarge: { fontFamily: fontFamilies.base, fontSize: 16, fontWeight: 400, lineHeight: 24 },
+ bodyLargeBold: { fontFamily: fontFamilies.base, fontSize: 16, fontWeight: 600, lineHeight: 24 },
+ bodyStandard: { fontFamily: fontFamilies.base, fontSize: 14, fontWeight: 400, lineHeight: 20 },
+ bodyStandardBold: {
+ fontFamily: fontFamilies.base,
+ fontSize: 14,
+ fontWeight: 600,
+ lineHeight: 20,
+ },
+ bodySmall: { fontFamily: fontFamilies.base, fontSize: 12, fontWeight: 400, lineHeight: 16 },
+ bodySmallBold: { fontFamily: fontFamilies.base, fontSize: 12, fontWeight: 600, lineHeight: 16 },
+ monospaceStandard: {
+ fontFamily: fontFamilies.monospace,
+ fontSize: 14,
+ fontWeight: 400,
+ lineHeight: 20,
+ },
+ monospaceSmall: {
+ fontFamily: fontFamilies.monospace,
+ fontSize: 12,
+ fontWeight: 400,
+ lineHeight: 16,
+ },
+ appTitle: { fontFamily: fontFamilies.appTitle, fontSize: 16, fontWeight: 500, lineHeight: 24 },
+} as const satisfies Record;
+
+/**
+ * Spacing scale (px). A 4px-based scale aligned with Ant Design's default
+ * sizing and the spacing rhythm used across the Ozone screens.
+ */
+export const spacing = {
+ xxs: 2,
+ xs: 4,
+ sm: 8,
+ md: 12,
+ lg: 16,
+ xl: 24,
+ xxl: 32,
+ xxxl: 48,
+} as const;
+
+/** Corner radii (px). */
+export const radius = {
+ sm: 4,
+ md: 6,
+ lg: 8,
+ pill: 999,
+} as const;
+
+export type ColorFamily = keyof typeof colors;
+export type TextStyleName = keyof typeof textStyles;
diff --git a/ozone-ui/src/packages/shared/src/utils/menuUtils.ts b/ozone-ui/packages/shared/src/utils/menuUtils.ts
similarity index 100%
rename from ozone-ui/src/packages/shared/src/utils/menuUtils.ts
rename to ozone-ui/packages/shared/src/utils/menuUtils.ts
diff --git a/ozone-ui/src/packages/shared/tsconfig.json b/ozone-ui/packages/shared/tsconfig.json
similarity index 100%
rename from ozone-ui/src/packages/shared/tsconfig.json
rename to ozone-ui/packages/shared/tsconfig.json
diff --git a/ozone-ui/src/pnpm-lock.yaml b/ozone-ui/pnpm-lock.yaml
similarity index 96%
rename from ozone-ui/src/pnpm-lock.yaml
rename to ozone-ui/pnpm-lock.yaml
index f85ee915d06b..ca8a8ea6f36e 100644
--- a/ozone-ui/src/pnpm-lock.yaml
+++ b/ozone-ui/pnpm-lock.yaml
@@ -53,7 +53,7 @@ importers:
version: 8.54.0(eslint@9.39.2)(typescript@5.6.3)
'@vitejs/plugin-react-swc':
specifier: ^3.5.0
- version: 3.10.2(vite@5.4.19)
+ version: 3.10.2(vite@6.4.3)
eslint:
specifier: ^9.39.2
version: 9.39.2
@@ -85,14 +85,14 @@ importers:
specifier: 8.54.0
version: 8.54.0(eslint@9.39.2)(typescript@5.6.3)
vite:
- specifier: ^5.4.10
- version: 5.4.19(@types/node@20.19.7)(less@4.3.0)
+ specifier: ^6.4.3
+ version: 6.4.3(@types/node@20.19.7)(less@4.3.0)
vite-plugin-svgr:
specifier: 4.5.0
- version: 4.5.0(typescript@5.6.3)(vite@5.4.19)
+ version: 4.5.0(typescript@5.6.3)(vite@6.4.3)
vite-tsconfig-paths:
specifier: ^3.6.0
- version: 3.6.0(vite@5.4.19)
+ version: 3.6.0(vite@6.4.3)
vitest:
specifier: ^1.6.1
version: 1.6.1(@types/node@20.19.7)(jsdom@24.1.3)(less@4.3.0)
@@ -105,7 +105,7 @@ importers:
'@fontsource/roboto':
specifier: ^4.5.8
version: 4.5.8
- '@hadoop-ui/shared':
+ '@ozone-ui/shared':
specifier: workspace:*
version: link:../shared
ag-charts-community:
@@ -226,7 +226,7 @@ importers:
'@fontsource/roboto':
specifier: ^4.5.8
version: 4.5.8
- '@hadoop-ui/shared':
+ '@ozone-ui/shared':
specifier: workspace:*
version: link:../shared
ag-charts-community:
@@ -347,7 +347,7 @@ importers:
'@fontsource/roboto':
specifier: ^4.5.8
version: 4.5.8
- '@hadoop-ui/shared':
+ '@ozone-ui/shared':
specifier: workspace:*
version: link:../shared
ag-charts-community:
@@ -799,6 +799,15 @@ packages:
dev: true
optional: true
+ /@esbuild/aix-ppc64@0.25.12:
+ resolution: {integrity: sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==}
+ engines: {node: '>=18'}
+ cpu: [ppc64]
+ os: [aix]
+ requiresBuild: true
+ dev: true
+ optional: true
+
/@esbuild/android-arm64@0.21.5:
resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==}
engines: {node: '>=12'}
@@ -808,6 +817,15 @@ packages:
dev: true
optional: true
+ /@esbuild/android-arm64@0.25.12:
+ resolution: {integrity: sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [android]
+ requiresBuild: true
+ dev: true
+ optional: true
+
/@esbuild/android-arm@0.21.5:
resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==}
engines: {node: '>=12'}
@@ -817,6 +835,15 @@ packages:
dev: true
optional: true
+ /@esbuild/android-arm@0.25.12:
+ resolution: {integrity: sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==}
+ engines: {node: '>=18'}
+ cpu: [arm]
+ os: [android]
+ requiresBuild: true
+ dev: true
+ optional: true
+
/@esbuild/android-x64@0.21.5:
resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==}
engines: {node: '>=12'}
@@ -826,6 +853,15 @@ packages:
dev: true
optional: true
+ /@esbuild/android-x64@0.25.12:
+ resolution: {integrity: sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [android]
+ requiresBuild: true
+ dev: true
+ optional: true
+
/@esbuild/darwin-arm64@0.21.5:
resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==}
engines: {node: '>=12'}
@@ -835,6 +871,15 @@ packages:
dev: true
optional: true
+ /@esbuild/darwin-arm64@0.25.12:
+ resolution: {integrity: sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [darwin]
+ requiresBuild: true
+ dev: true
+ optional: true
+
/@esbuild/darwin-x64@0.21.5:
resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==}
engines: {node: '>=12'}
@@ -844,6 +889,15 @@ packages:
dev: true
optional: true
+ /@esbuild/darwin-x64@0.25.12:
+ resolution: {integrity: sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [darwin]
+ requiresBuild: true
+ dev: true
+ optional: true
+
/@esbuild/freebsd-arm64@0.21.5:
resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==}
engines: {node: '>=12'}
@@ -853,6 +907,15 @@ packages:
dev: true
optional: true
+ /@esbuild/freebsd-arm64@0.25.12:
+ resolution: {integrity: sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [freebsd]
+ requiresBuild: true
+ dev: true
+ optional: true
+
/@esbuild/freebsd-x64@0.21.5:
resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==}
engines: {node: '>=12'}
@@ -862,6 +925,15 @@ packages:
dev: true
optional: true
+ /@esbuild/freebsd-x64@0.25.12:
+ resolution: {integrity: sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [freebsd]
+ requiresBuild: true
+ dev: true
+ optional: true
+
/@esbuild/linux-arm64@0.21.5:
resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==}
engines: {node: '>=12'}
@@ -871,6 +943,15 @@ packages:
dev: true
optional: true
+ /@esbuild/linux-arm64@0.25.12:
+ resolution: {integrity: sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [linux]
+ requiresBuild: true
+ dev: true
+ optional: true
+
/@esbuild/linux-arm@0.21.5:
resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==}
engines: {node: '>=12'}
@@ -880,6 +961,15 @@ packages:
dev: true
optional: true
+ /@esbuild/linux-arm@0.25.12:
+ resolution: {integrity: sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==}
+ engines: {node: '>=18'}
+ cpu: [arm]
+ os: [linux]
+ requiresBuild: true
+ dev: true
+ optional: true
+
/@esbuild/linux-ia32@0.21.5:
resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==}
engines: {node: '>=12'}
@@ -889,6 +979,15 @@ packages:
dev: true
optional: true
+ /@esbuild/linux-ia32@0.25.12:
+ resolution: {integrity: sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==}
+ engines: {node: '>=18'}
+ cpu: [ia32]
+ os: [linux]
+ requiresBuild: true
+ dev: true
+ optional: true
+
/@esbuild/linux-loong64@0.21.5:
resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==}
engines: {node: '>=12'}
@@ -898,6 +997,15 @@ packages:
dev: true
optional: true
+ /@esbuild/linux-loong64@0.25.12:
+ resolution: {integrity: sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==}
+ engines: {node: '>=18'}
+ cpu: [loong64]
+ os: [linux]
+ requiresBuild: true
+ dev: true
+ optional: true
+
/@esbuild/linux-mips64el@0.21.5:
resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==}
engines: {node: '>=12'}
@@ -907,6 +1015,15 @@ packages:
dev: true
optional: true
+ /@esbuild/linux-mips64el@0.25.12:
+ resolution: {integrity: sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==}
+ engines: {node: '>=18'}
+ cpu: [mips64el]
+ os: [linux]
+ requiresBuild: true
+ dev: true
+ optional: true
+
/@esbuild/linux-ppc64@0.21.5:
resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==}
engines: {node: '>=12'}
@@ -916,6 +1033,15 @@ packages:
dev: true
optional: true
+ /@esbuild/linux-ppc64@0.25.12:
+ resolution: {integrity: sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==}
+ engines: {node: '>=18'}
+ cpu: [ppc64]
+ os: [linux]
+ requiresBuild: true
+ dev: true
+ optional: true
+
/@esbuild/linux-riscv64@0.21.5:
resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==}
engines: {node: '>=12'}
@@ -925,6 +1051,15 @@ packages:
dev: true
optional: true
+ /@esbuild/linux-riscv64@0.25.12:
+ resolution: {integrity: sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==}
+ engines: {node: '>=18'}
+ cpu: [riscv64]
+ os: [linux]
+ requiresBuild: true
+ dev: true
+ optional: true
+
/@esbuild/linux-s390x@0.21.5:
resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==}
engines: {node: '>=12'}
@@ -934,6 +1069,15 @@ packages:
dev: true
optional: true
+ /@esbuild/linux-s390x@0.25.12:
+ resolution: {integrity: sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==}
+ engines: {node: '>=18'}
+ cpu: [s390x]
+ os: [linux]
+ requiresBuild: true
+ dev: true
+ optional: true
+
/@esbuild/linux-x64@0.21.5:
resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==}
engines: {node: '>=12'}
@@ -943,6 +1087,24 @@ packages:
dev: true
optional: true
+ /@esbuild/linux-x64@0.25.12:
+ resolution: {integrity: sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [linux]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /@esbuild/netbsd-arm64@0.25.12:
+ resolution: {integrity: sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [netbsd]
+ requiresBuild: true
+ dev: true
+ optional: true
+
/@esbuild/netbsd-x64@0.21.5:
resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==}
engines: {node: '>=12'}
@@ -952,6 +1114,24 @@ packages:
dev: true
optional: true
+ /@esbuild/netbsd-x64@0.25.12:
+ resolution: {integrity: sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [netbsd]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /@esbuild/openbsd-arm64@0.25.12:
+ resolution: {integrity: sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [openbsd]
+ requiresBuild: true
+ dev: true
+ optional: true
+
/@esbuild/openbsd-x64@0.21.5:
resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==}
engines: {node: '>=12'}
@@ -961,6 +1141,24 @@ packages:
dev: true
optional: true
+ /@esbuild/openbsd-x64@0.25.12:
+ resolution: {integrity: sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [openbsd]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /@esbuild/openharmony-arm64@0.25.12:
+ resolution: {integrity: sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [openharmony]
+ requiresBuild: true
+ dev: true
+ optional: true
+
/@esbuild/sunos-x64@0.21.5:
resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==}
engines: {node: '>=12'}
@@ -970,6 +1168,15 @@ packages:
dev: true
optional: true
+ /@esbuild/sunos-x64@0.25.12:
+ resolution: {integrity: sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [sunos]
+ requiresBuild: true
+ dev: true
+ optional: true
+
/@esbuild/win32-arm64@0.21.5:
resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==}
engines: {node: '>=12'}
@@ -979,6 +1186,15 @@ packages:
dev: true
optional: true
+ /@esbuild/win32-arm64@0.25.12:
+ resolution: {integrity: sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [win32]
+ requiresBuild: true
+ dev: true
+ optional: true
+
/@esbuild/win32-ia32@0.21.5:
resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==}
engines: {node: '>=12'}
@@ -988,6 +1204,15 @@ packages:
dev: true
optional: true
+ /@esbuild/win32-ia32@0.25.12:
+ resolution: {integrity: sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==}
+ engines: {node: '>=18'}
+ cpu: [ia32]
+ os: [win32]
+ requiresBuild: true
+ dev: true
+ optional: true
+
/@esbuild/win32-x64@0.21.5:
resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==}
engines: {node: '>=12'}
@@ -997,6 +1222,15 @@ packages:
dev: true
optional: true
+ /@esbuild/win32-x64@0.25.12:
+ resolution: {integrity: sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [win32]
+ requiresBuild: true
+ dev: true
+ optional: true
+
/@eslint-community/eslint-utils@4.9.1(eslint@9.39.2):
resolution: {integrity: sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
@@ -2018,6 +2252,18 @@ packages:
- '@swc/helpers'
dev: true
+ /@vitejs/plugin-react-swc@3.10.2(vite@6.4.3):
+ resolution: {integrity: sha512-xD3Rdvrt5LgANug7WekBn1KhcvLn1H3jNBfJRL3reeOIua/WnZOEV5qi5qIBq5T8R0jUDmRtxuvk4bPhzGHDWw==}
+ peerDependencies:
+ vite: ^4 || ^5 || ^6 || ^7.0.0-beta.0
+ dependencies:
+ '@rolldown/pluginutils': 1.0.0-beta.11
+ '@swc/core': 1.12.11
+ vite: 6.4.3(@types/node@20.19.7)(less@4.3.0)
+ transitivePeerDependencies:
+ - '@swc/helpers'
+ dev: true
+
/@vitest/expect@1.6.1:
resolution: {integrity: sha512-jXL+9+ZNIJKruofqXuuTClf44eSpcHlgj3CiuNihUF3Ioujtmc0zIa3UJOW5RjDK1YLBJZnWBlPuqhYycLioog==}
dependencies:
@@ -3372,6 +3618,40 @@ packages:
'@esbuild/win32-x64': 0.21.5
dev: true
+ /esbuild@0.25.12:
+ resolution: {integrity: sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==}
+ engines: {node: '>=18'}
+ hasBin: true
+ requiresBuild: true
+ optionalDependencies:
+ '@esbuild/aix-ppc64': 0.25.12
+ '@esbuild/android-arm': 0.25.12
+ '@esbuild/android-arm64': 0.25.12
+ '@esbuild/android-x64': 0.25.12
+ '@esbuild/darwin-arm64': 0.25.12
+ '@esbuild/darwin-x64': 0.25.12
+ '@esbuild/freebsd-arm64': 0.25.12
+ '@esbuild/freebsd-x64': 0.25.12
+ '@esbuild/linux-arm': 0.25.12
+ '@esbuild/linux-arm64': 0.25.12
+ '@esbuild/linux-ia32': 0.25.12
+ '@esbuild/linux-loong64': 0.25.12
+ '@esbuild/linux-mips64el': 0.25.12
+ '@esbuild/linux-ppc64': 0.25.12
+ '@esbuild/linux-riscv64': 0.25.12
+ '@esbuild/linux-s390x': 0.25.12
+ '@esbuild/linux-x64': 0.25.12
+ '@esbuild/netbsd-arm64': 0.25.12
+ '@esbuild/netbsd-x64': 0.25.12
+ '@esbuild/openbsd-arm64': 0.25.12
+ '@esbuild/openbsd-x64': 0.25.12
+ '@esbuild/openharmony-arm64': 0.25.12
+ '@esbuild/sunos-x64': 0.25.12
+ '@esbuild/win32-arm64': 0.25.12
+ '@esbuild/win32-ia32': 0.25.12
+ '@esbuild/win32-x64': 0.25.12
+ dev: true
+
/escalade@3.2.0:
resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==}
engines: {node: '>=6'}
@@ -7521,7 +7801,7 @@ packages:
- terser
dev: true
- /vite-plugin-svgr@4.5.0(typescript@5.6.3)(vite@5.4.19):
+ /vite-plugin-svgr@4.5.0(typescript@5.6.3)(vite@6.4.3):
resolution: {integrity: sha512-W+uoSpmVkSmNOGPSsDCWVW/DDAyv+9fap9AZXBvWiQqrboJ08j2vh0tFxTD/LjwqwAd3yYSVJgm54S/1GhbdnA==}
peerDependencies:
vite: '>=2.6.0'
@@ -7529,14 +7809,14 @@ packages:
'@rollup/pluginutils': 5.3.0
'@svgr/core': 8.1.0(typescript@5.6.3)
'@svgr/plugin-jsx': 8.1.0(@svgr/core@8.1.0)
- vite: 5.4.19(@types/node@20.19.7)(less@4.3.0)
+ vite: 6.4.3(@types/node@20.19.7)(less@4.3.0)
transitivePeerDependencies:
- rollup
- supports-color
- typescript
dev: true
- /vite-tsconfig-paths@3.6.0(vite@5.4.19):
+ /vite-tsconfig-paths@3.6.0(vite@6.4.3):
resolution: {integrity: sha512-UfsPYonxLqPD633X8cWcPFVuYzx/CMNHAjZTasYwX69sXpa4gNmQkR0XCjj82h7zhLGdTWagMjC1qfb9S+zv0A==}
peerDependencies:
vite: '>2.0.0-0'
@@ -7545,7 +7825,7 @@ packages:
globrex: 0.1.2
recrawl-sync: 2.2.3
tsconfig-paths: 4.2.0
- vite: 5.4.19(@types/node@20.19.7)(less@4.3.0)
+ vite: 6.4.3(@types/node@20.19.7)(less@4.3.0)
transitivePeerDependencies:
- supports-color
dev: true
@@ -7590,6 +7870,58 @@ packages:
fsevents: 2.3.3
dev: true
+ /vite@6.4.3(@types/node@20.19.7)(less@4.3.0):
+ resolution: {integrity: sha512-NTKlcQjlAK7MlQoyb6LgaqHc8sso/pVyUJYWMws3jg21uTJw/LddqIFPcPqP6PzpgbIcZyKI85sFE4HBrQDA8A==}
+ engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
+ hasBin: true
+ peerDependencies:
+ '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0
+ jiti: '>=1.21.0'
+ less: '*'
+ lightningcss: ^1.21.0
+ sass: '*'
+ sass-embedded: '*'
+ stylus: '*'
+ sugarss: '*'
+ terser: ^5.16.0
+ tsx: ^4.8.1
+ yaml: ^2.4.2
+ peerDependenciesMeta:
+ '@types/node':
+ optional: true
+ jiti:
+ optional: true
+ less:
+ optional: true
+ lightningcss:
+ optional: true
+ sass:
+ optional: true
+ sass-embedded:
+ optional: true
+ stylus:
+ optional: true
+ sugarss:
+ optional: true
+ terser:
+ optional: true
+ tsx:
+ optional: true
+ yaml:
+ optional: true
+ dependencies:
+ '@types/node': 20.19.7
+ esbuild: 0.25.12
+ fdir: 6.5.0(picomatch@4.0.3)
+ less: 4.3.0
+ picomatch: 4.0.3
+ postcss: 8.5.6
+ rollup: 4.45.0
+ tinyglobby: 0.2.15
+ optionalDependencies:
+ fsevents: 2.3.3
+ dev: true
+
/vitest@1.6.1(@types/node@20.19.7)(jsdom@24.1.3)(less@4.3.0):
resolution: {integrity: sha512-Ljb1cnSJSivGN0LqXd/zmDbWEM0RNNg2t1QW/XUhYl/qPqyu7CsqeWtqQXHVaJsecLPuDoak2oJcZN2QoRIOag==}
engines: {node: ^18.0.0 || >=20.0.0}
diff --git a/ozone-ui/src/pnpm-workspace.yaml b/ozone-ui/pnpm-workspace.yaml
similarity index 100%
rename from ozone-ui/src/pnpm-workspace.yaml
rename to ozone-ui/pnpm-workspace.yaml
diff --git a/ozone-ui/src/.gitignore b/ozone-ui/src/.gitignore
deleted file mode 100644
index db4c6d9b6797..000000000000
--- a/ozone-ui/src/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-dist
-node_modules
\ No newline at end of file
diff --git a/ozone-ui/src/packages/shared/utils/menuUtils.tsx b/ozone-ui/src/packages/shared/utils/menuUtils.tsx
deleted file mode 100644
index 5d5f1e35f1ae..000000000000
--- a/ozone-ui/src/packages/shared/utils/menuUtils.tsx
+++ /dev/null
@@ -1,17 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
diff --git a/ozone-ui/src/tsconfig.json b/ozone-ui/tsconfig.json
similarity index 100%
rename from ozone-ui/src/tsconfig.json
rename to ozone-ui/tsconfig.json
diff --git a/ozone-ui/src/vite.config.shared.ts b/ozone-ui/vite.config.shared.ts
similarity index 100%
rename from ozone-ui/src/vite.config.shared.ts
rename to ozone-ui/vite.config.shared.ts