From 409f1d1e1745f85bcc10f1a14df6b5bef2917ca9 Mon Sep 17 00:00:00 2001 From: Tamas Kovacs Date: Tue, 3 Feb 2026 14:34:14 +0100 Subject: [PATCH] feat(ui-toggle-details): rework ToggleDetails INSTUI-4815 --- docs/guides/upgrade-guide.md | 16 ++++ .../src/ToggleDetails/README.md | 4 +- .../src/ToggleDetails/index.tsx | 18 +++-- .../src/ToggleDetails/styles.ts | 30 ++++--- .../src/ToggleDetails/theme.ts | 80 ------------------- 5 files changed, 42 insertions(+), 106 deletions(-) delete mode 100644 packages/ui-toggle-details/src/ToggleDetails/theme.ts diff --git a/docs/guides/upgrade-guide.md b/docs/guides/upgrade-guide.md index 23330921da..84ed63af8f 100644 --- a/docs/guides/upgrade-guide.md +++ b/docs/guides/upgrade-guide.md @@ -698,6 +698,22 @@ type: embed ``` +### ToggleDetails + +```js +--- +type: embed +--- + + +``` + ### View ```js diff --git a/packages/ui-toggle-details/src/ToggleDetails/README.md b/packages/ui-toggle-details/src/ToggleDetails/README.md index 36819a886c..c10256b629 100644 --- a/packages/ui-toggle-details/src/ToggleDetails/README.md +++ b/packages/ui-toggle-details/src/ToggleDetails/README.md @@ -205,9 +205,9 @@ const Example = () => { size={size} variant={variant} > - + I am controlled and expanded!I am controlled and expanded!I am controlled and expanded!I am controlled and expanded!I am controlled and expanded!I am controlled and expanded!I am controlled and expanded!I am controlled and expanded!I am controlled and expanded!I am controlled and expanded!I am controlled and expanded!I am controlled and expanded!I am controlled and expanded!I am controlled and expanded!I am controlled and expanded!I am controlled and expanded!I am controlled and expanded!I am controlled and expanded!I am controlled and expanded!I am controlled and expanded!I am controlled and expanded!I am controlled and expanded!I am controlled and expanded!I am controlled and expanded!I am controlled and expanded! - + ); diff --git a/packages/ui-toggle-details/src/ToggleDetails/index.tsx b/packages/ui-toggle-details/src/ToggleDetails/index.tsx index 6f674f3969..0fd3f5064b 100644 --- a/packages/ui-toggle-details/src/ToggleDetails/index.tsx +++ b/packages/ui-toggle-details/src/ToggleDetails/index.tsx @@ -25,16 +25,15 @@ import { Component, createRef } from 'react' import { Button } from '@instructure/ui-buttons' import { - IconArrowOpenEndSolid, - IconArrowOpenDownSolid + ChevronRightInstUIIcon, + ChevronDownInstUIIcon } from '@instructure/ui-icons' import { Expandable } from '@instructure/ui-expandable' import { omitProps, pickProps } from '@instructure/ui-react-utils' import { isActiveElement } from '@instructure/ui-dom-utils' -import { withStyleRework as withStyle } from '@instructure/emotion' +import { withStyle } from '@instructure/emotion' import generateStyle from './styles' -import generateComponentTheme from './theme' import type { ToggleDetailsProps } from './props' import { allowedProps } from './props' import type { ExpandableToggleProps } from '@instructure/ui-expandable' @@ -45,7 +44,7 @@ import type { ViewProps } from '@instructure/ui-view' category: components --- **/ -@withStyle(generateStyle, generateComponentTheme) +@withStyle(generateStyle) class ToggleDetails extends Component { static readonly componentId = 'ToggleDetails' static allowedProps = allowedProps @@ -54,8 +53,8 @@ class ToggleDetails extends Component { variant: 'default', size: 'medium', fluidWidth: false, - icon: IconArrowOpenEndSolid, - iconExpanded: IconArrowOpenDownSolid, + icon: ChevronRightInstUIIcon, + iconExpanded: ChevronDownInstUIIcon, iconPosition: 'start', defaultExpanded: false, children: null @@ -145,10 +144,13 @@ class ToggleDetails extends Component { renderIcon(expanded: boolean) { const Icon = expanded ? this.props.iconExpanded : this.props.icon + const iconSize = this.props.size === 'large' ? 'lg' : 'md' + const iconColor = + this.props.variant === 'filled' ? 'actionSecondaryBaseColor' : 'baseColor' return this.props.children && Icon ? ( - + ) : null } diff --git a/packages/ui-toggle-details/src/ToggleDetails/styles.ts b/packages/ui-toggle-details/src/ToggleDetails/styles.ts index 014ca2f9bc..d05e75bfb3 100644 --- a/packages/ui-toggle-details/src/ToggleDetails/styles.ts +++ b/packages/ui-toggle-details/src/ToggleDetails/styles.ts @@ -24,7 +24,7 @@ import { keyframes } from '@instructure/emotion' -import type { ToggleDetailsTheme } from '@instructure/shared-types' +import type { NewComponentTypes, SharedTokens } from '@instructure/ui-themes' import type { ToggleDetailsProps, ToggleDetailsStyleProps, @@ -43,12 +43,14 @@ const contentAnimation = keyframes` * Generates the style object from the theme and provided additional information * @param {Object} componentTheme The theme variable object. * @param {Object} props the props of the component, the style is applied to + * @param {Object} sharedTokens the shared tokens of the component * @param {Object} state the state of the component, the style is applied to * @return {Object} The final style object, which will be used in the component */ const generateStyle = ( - componentTheme: ToggleDetailsTheme, + componentTheme: NewComponentTypes['ToggleDetails'], props: ToggleDetailsProps, + sharedTokens: SharedTokens, _state: ToggleDetailsStyleProps ): ToggleDetailsStyle => { const { fluidWidth, iconPosition, size, variant } = props @@ -74,25 +76,19 @@ const generateStyle = ( large: { fontSize: componentTheme.fontSizeLarge } } - const iconSizeStyles = { - small: { fontSize: componentTheme.smallIconSize }, - medium: { fontSize: componentTheme.mediumIconSize }, - large: { fontSize: componentTheme.largeIconSize } - } - const indentDetailsStyles = iconPosition === 'start' && !fluidWidth ? { small: { - paddingInlineStart: `calc(${componentTheme.smallIconSize} + ${componentTheme.togglePadding})`, + paddingInlineStart: `calc(${componentTheme.contentPaddingSmall} + ${componentTheme.togglePadding})`, paddingInlineEnd: '0' }, medium: { - paddingInlineStart: `calc(${componentTheme.mediumIconSize} + ${componentTheme.togglePadding})`, + paddingInlineStart: `calc(${componentTheme.contentPaddingMedium} + ${componentTheme.togglePadding})`, paddingInlineEnd: '0' }, large: { - paddingInlineStart: `calc(${componentTheme.largeIconSize} + ${componentTheme.togglePadding})`, + paddingInlineStart: `calc(${componentTheme.contentPaddingLarge} + ${componentTheme.togglePadding})`, paddingInlineEnd: '0' } } @@ -106,8 +102,7 @@ const generateStyle = ( toggleDetails: { label: 'toggleDetails', fontFamily: componentTheme.fontFamily, - fontWeight: componentTheme.fontWeight, - lineHeight: componentTheme.lineHeight + fontWeight: componentTheme.fontWeight }, summary: { label: 'toggleDetails__summary', @@ -126,6 +121,7 @@ const generateStyle = ( toggle: { label: 'toggleDetails__toggle', fontFamily: componentTheme.fontFamily, + lineHeight: componentTheme.lineHeight, appearance: 'none', cursor: 'pointer', userSelect: 'none', @@ -147,7 +143,7 @@ const generateStyle = ( left: '-0.375rem', right: '-0.375rem', bottom: '-0.375rem', - border: `${componentTheme.toggleBorderWidth} ${componentTheme.toggleBorderStyle} ${componentTheme.toggleFocusBorderColor}`, + border: `${componentTheme.toggleBorderWidth} ${componentTheme.toggleBorderStyle} ${sharedTokens.focusOutline.infoColor}`, borderRadius: `calc(${componentTheme.toggleBorderRadius} * 1.5)`, opacity: 0, pointerEvents: 'none' @@ -163,17 +159,19 @@ const generateStyle = ( }, icon: { label: 'toggleDetails__icon', + display: 'flex', + alignItems: 'center', '& > svg': { display: 'block' /* fix vertical alignment of icon */ }, - ...iconPositionStyles[iconPosition!], - ...iconSizeStyles[size!] + ...iconPositionStyles[iconPosition!] }, details: { label: 'toggleDetails__details', boxSizing: 'border-box', paddingTop: componentTheme.togglePadding, color: componentTheme.textColor, + lineHeight: componentTheme.lineHeight, ...fontSizeStyles[size!], ...indentDetailsStyles[size!] }, diff --git a/packages/ui-toggle-details/src/ToggleDetails/theme.ts b/packages/ui-toggle-details/src/ToggleDetails/theme.ts deleted file mode 100644 index fcdbe0dcf7..0000000000 --- a/packages/ui-toggle-details/src/ToggleDetails/theme.ts +++ /dev/null @@ -1,80 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2015 - present Instructure, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -import type { Theme, ThemeSpecificStyle } from '@instructure/ui-themes' -import { ToggleDetailsTheme } from '@instructure/shared-types' - -/** - * Generates the theme object for the component from the theme and provided additional information - * @param {Object} theme The actual theme object. - * @return {Object} The final theme object with the overrides and component variables - */ -const generateComponentTheme = (theme: Theme): ToggleDetailsTheme => { - const { colors, spacing, borders, typography, key: themeName } = theme - - const themeSpecificStyle: ThemeSpecificStyle = { - canvas: { - toggleFocusBorderColor: theme['ic-brand-primary'], - iconColor: theme['ic-brand-font-color-dark'], - textColor: theme['ic-brand-font-color-dark'] - } - } - - const componentVariables: ToggleDetailsTheme = { - fontFamily: typography?.fontFamily, - fontWeight: typography?.fontWeightNormal, - lineHeight: typography?.lineHeight, - textColor: colors?.contrasts?.grey125125, - - fontSizeSmall: typography?.fontSizeSmall, - fontSizeMedium: typography?.fontSizeMedium, - fontSizeLarge: typography?.fontSizeLarge, - - smallIconSize: '0.5rem', - mediumIconSize: '0.75rem', - largeIconSize: '1rem', - iconMargin: spacing?.xxSmall, - iconColor: colors?.contrasts?.grey125125, - - togglePadding: spacing?.xxSmall, - toggleBorderRadius: borders?.radiusMedium, - toggleBorderWidth: borders?.widthMedium, - toggleBorderStyle: borders?.style, - toggleFocusBorderColor: colors?.contrasts?.blue4570, - - filledBackgroundColor: colors?.contrasts?.grey1111, - filledBorderWidth: borders?.widthSmall, - filledBorderStyle: borders?.style, - filledBorderColor: colors?.contrasts?.grey1424, - filledBorderRadius: borders?.radiusMedium, - filledPadding: spacing?.small - } - - return { - ...componentVariables, - ...themeSpecificStyle[themeName] - } -} - -export default generateComponentTheme