主題式元件
了解如何在主題層級將自訂樣式套用至元件。
元件識別符
如果您之前使用過 Material UI,您可能對此技術很熟悉。若要在主題中自訂特定元件,請在 components
節點內指定元件識別符 (Joy{ComponentImportName}
)。
- 使用
defaultProps
變更元件的預設 React props。 - 使用
styleOverrides
將樣式套用至每個元件插槽。- 每個 Joy UI 元件都包含
root
插槽。
- 每個 Joy UI 元件都包含
請造訪 components.d.ts
檔案以查看所有元件識別符。
import { CssVarsProvider, extendTheme } from '@mui/joy/styles';
const theme = extendTheme({
components: {
JoyChip: {
defaultProps: {
size: 'sm',
},
styleOverrides: {
root: {
borderRadius: '4px',
},
},
},
},
});
function App() {
return <CssVarsProvider theme={theme}>...</CssVarsProvider>;
}
主題預設 props
在主題中指定為 defaultProps
的值會影響元件的所有執行個體
extendTheme({
components: {
JoyIconButton: {
defaultProps: {
variant: 'outlined',
color: 'neutral',
},
},
},
});
// This is the same as:
// <IconButton variant="outlined" color="neutral">
<IconButton>...</IconButton>;
主題樣式覆寫
根據 props 變更樣式
若要變更指定 prop 的樣式,請使用回呼作為樣式覆寫的值。引數包含 theme
和 ownerState
(props)。
extendTheme({
components: {
JoyChip: {
styleOverrides: {
// `ownerState` contains the component props and internal state
root: ({ ownerState, theme }) => ({
...(ownerState.size === 'sm' && {
borderRadius: theme.vars.radius.xs,
}),
}),
},
},
},
});
我們建議使用來自 theme.vars.*
的 CSS 變數,因為它具有更佳的偵錯體驗,而且在某些情況下效能更高。
樣式也可以包含任何 CSS 選取器 (支援巢狀選取器),如下所示
extendTheme({
components: {
JoyChip: {
styleOverrides: {
root: ({ ownerState, theme }) => ({
...(ownerState.variant === 'solid' &&
ownerState.clickable && {
color: 'rgba(255 255 255 / 0.72)',
'&:hover': {
color: '#fff',
},
}),
}),
},
},
},
});
根據狀態變更樣式
當 Joy UI 元件處於給定狀態 (例如 selected
、disabled
、focusVisible
等) 時,會增加樣式的 CSS 優先順序。
若要覆寫特定狀態的樣式,請使用元件類別選取器,方法是匯入元件名稱,並以駝峰式命名,後面加上 Classes
。
import { listItemButtonClasses } from '@mui/joy/ListItemButton';
extendTheme({
components: {
JoyListItemButton: {
styleOverrides: {
root: {
[`&.${listItemButtonClasses.selected}`]: {
color: 'rgba(255 255 255 / 0.7)',
},
},
},
},
},
});
可用的狀態為:active
、checked
、completed
、disabled
、error
、expanded
、focused
、focusVisible
、readOnly
、required
、selected
。
擴充色彩
以下程式碼片段說明如何在 primary
、success
、info
、danger
、neutral
和 warning
之外,為元件提供其他色彩。
請注意,建立新色彩時,您會自動選擇退出全域變體功能,這可讓您精細控制 CSS 屬性,例如 color
、background
和 border
。
以下範例擴充 Button 色彩以包含 secondary
值
extendTheme({
components: {
JoyButton: {
styleOverrides: {
root: ({ ownerState, theme }) => ({
...(ownerState.color === 'secondary' && {
color: theme.vars.palette.text.secondary,
backgroundColor: theme.vars.palette.background.level1,
}),
}),
},
},
},
});
一旦這些值如上定義,您就可以直接在 Button 元件的執行個體上使用它們
<Button color="secondary">Secondary color</Button>
<Button color="tertiary">Tertiary color</Button>
TypeScript
需要模組擴充才能將值傳遞至元件的 color
prop。
介面格式為 {ComponentName}PropsColorOverrides
,這對所有 Joy UI 元件都相同
// This part could be declared in your theme file
declare module '@mui/joy/Button' {
interface ButtonPropsColorOverrides {
secondary: true;
tertiary: true;
}
}
// typed-safe
<Button color="secondary" />
<Button color="tertiary" />
擴充尺寸
以下程式碼片段說明如何在 sm
、md
和 lg
之外,為元件提供其他尺寸。我們建議遵循已建立的「T 恤尺寸」命名慣例 (例如 xs
、xl
、xxl
等),以維持與所有其他 props 的一致性。
以下範例擴充 Button 尺寸以包含 xs
和 xl
值
extendTheme({
components: {
JoyButton: {
styleOverrides: {
root: ({ ownerState, theme }) => ({
...(ownerState.size === 'xs' && {
'--Icon-fontSize': '1rem',
'--Button-gap': '0.25rem',
minHeight: 'var(--Button-minHeight, 1.75rem)',
fontSize: theme.vars.fontSize.xs,
paddingBlock: '2px',
paddingInline: '0.5rem',
}),
...(ownerState.size === 'xl' && {
'--Icon-fontSize': '2rem',
'--Button-gap': '1rem',
minHeight: 'var(--Button-minHeight, 4rem)',
fontSize: theme.vars.fontSize.xl,
paddingBlock: '0.5rem',
paddingInline: '2rem',
}),
}),
},
},
},
});
一旦這些值如上定義,您就可以直接在 Button 元件的執行個體上使用它們
<Button size="xs">Extra small</Button>
<Button size="xl">Extra large</Button>
用於擴充尺寸的屬性應僅與元件的密度或尺寸相關。若要了解如何擴充變體屬性,請查看本文文件中的擴充變體章節。
TypeScript
需要模組擴充才能將值傳遞至元件的 size
prop。
介面格式為 {ComponentName}PropsSizeOverrides
,這對所有 Joy UI 元件都相同
// This part could be declared in your theme file
declare module '@mui/joy/Button' {
interface ButtonPropsSizeOverrides {
xs: true;
xl: true;
}
}
// typed-safe
<Button size="xs" />
<Button size="xl" />
擴充變體
以下程式碼片段顯示如何擴充色彩屬性的元件變體。請注意,建立新變體時,您會自動選擇退出全域變體功能,這可讓您精細控制 CSS 屬性,例如 color
、background
和 border
。
此範例擴充 Sheet 變體以包含名為 glass
的自訂值
extendTheme({
components: {
JoySheet: {
styleOverrides: {
root: ({ ownerState, theme }) => ({
...(ownerState.variant === 'glass' && {
color: theme.vars.palette.text.primary,
background: 'rgba(255, 255, 255, 0.14)',
backdropFilter: 'blur(5px)',
border: '1px solid rgba(255, 255, 255, 0.3)',
boxShadow: '0 4px 30px rgba(0, 0, 0, 0.1)',
}),
}),
},
},
},
});
一旦值如上定義,您就可以直接在 Sheet 元件的執行個體上使用它
<Sheet variant="glass">Glassmorphism</Sheet>
TypeScript
需要模組擴充才能將值傳遞至元件的 variant
prop。
介面格式為 {ComponentName}PropsSizeOverrides
,這對所有 Joy UI 元件都相同
// This part could be declared in your theme file
declare module '@mui/joy/Sheet' {
interface SheetPropsVariantOverrides {
glass: true;
}
}
// typed-safe
<Sheet variant="glass" />;
每個模式的不同樣式
若要為每個模式 (淺色和深色) 指定與預設主題中定義的值不同的值,請使用 CSS 屬性選取器。
Joy UI 會將具有目前色彩配置的 data-*
屬性附加至 DOM (預設為 HTML)。您可以使用 theme.getColorSchemeSelector
公用程式來變更元件樣式。
以下範例說明如何在淺色模式中變更 boxShadow
符記的強度,同時在深色模式中完全移除它
extendTheme({
components: {
JoyChip: {
styleOverrides: {
root: ({ ownerState, theme }) => ({
// for the default color scheme (light)
boxShadow: theme.vars.shadow.sm,
// the result is `[data-joy-color-scheme="dark"] &`
[theme.getColorSchemeSelector('dark')]: {
boxShadow: 'none',
},
}),
},
},
},
});
如果您有定義自訂色彩配置,此方法也適用。但是,請注意,它會建立額外的 CSS 優先順序,當父元件想要覆寫其子元件樣式時,可能會很麻煩。