Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file added a.out
Empty file.
22 changes: 21 additions & 1 deletion docs/guides/upgrade-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ The following variant values have been **deprecated** and will be removed in a f
- `'inline-small'`
- `'standalone-small'`


### Theme variable changes

- theme variable `fontSize` is now removed
Expand Down Expand Up @@ -211,6 +210,27 @@ type: example
- theme variable `requiredInvalidColor` is now removed
- `error` or `success` messages are no longer displayed when the component is '`readOnly` or `disabled`

### Tabs.Panel

- theme variable `color` is now renamed to `textColor`
- theme variable `focusOutlineColor` is now removed and the style uses the `sharedTokens.focusOutline.infoColor`

### Tabs.Tab

- theme variable `defaultColor` is now renamed to `defaultTextColor`
- theme variable `defaultHoverBorderColor` is now removed as it was unused

### Tray

- theme variable `background` is now renamed to `backgroundColor`
- theme variable `xSmallWidth` is now renamed to `widthXs`
- theme variable `smallWidth` is now renamed to `widthSm`
- theme variable `regularWidth` is now renamed to `widthMg`
- theme variable `mediumWidth` is now renamed to `widthLg`
- theme variable `largeWidth` is now renamed to `widthXl`
- theme variable `borderStyle` is now removed
- theme variable `position` is now removed

## Codemods

To ease the upgrade, we provide codemods that will automate most of the changes. Pay close attention to its output, it cannot refactor complex code! The codemod scripts can be run via the following commands:
Expand Down
4 changes: 3 additions & 1 deletion packages/emotion/src/withStyle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,8 @@ const withStyle = decorator(
) => {
const displayName = ComposedComponent.displayName || ComposedComponent.name

const componentId = ComposedComponent.componentId?.replace('.', '')

const WithStyle: ForwardRefExoticComponent<
PropsWithoutRef<Props> & RefAttributes<any>
> & {
Expand Down Expand Up @@ -182,7 +184,7 @@ const withStyle = decorator(
...defaultValues
}

const componentWithTokensId = useTokensFrom ?? displayName
const componentWithTokensId = useTokensFrom ?? componentId

const baseComponentTheme =
theme.newTheme.components[
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,12 @@ export const resolveReferences = (semantics, key) => {
if (typeof value[key] === 'object') {
return (
acc +
`"${key}": {${resolveReferences(value, key)}}${
`${key}: {${resolveReferences(value, key)}}${
index + 1 === Object.keys(value).length ? '' : ',\n'
}`
)
}
return acc + `"${key}": ${resolveReferences(value, key)}`
return acc + `${key}: ${resolveReferences(value, key)}`
}, '')
}
if (isReference(value)) {
Expand Down
149 changes: 84 additions & 65 deletions packages/ui-scripts/lib/build/buildThemes/setupThemes.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ const setupThemes = async (targetPath, input) => {
input,
themeData[theme].semantic
)
// console.log(JSON.stringify(mergedSemanticData));

const semantics = generateSemantics(mergedSemanticData)
const semanticsTypes = generateSemanticsType(mergedSemanticData)
const semanticsFileContent = `
Expand All @@ -109,19 +109,44 @@ const setupThemes = async (targetPath, input) => {
`
await createFile(`${themePath}/semantics.ts`, semanticsFileContent)

const componentAndSubcomponentNames = []
//components
for (const componentpath of themeData[theme].components) {
const rawComponentName =
componentpath.split('/')[componentpath.split('/').length - 1]
const componentName =
const mainComponentName =
rawComponentName[0].toLowerCase() + rawComponentName.slice(1)

const component = generateComponent(input[componentpath][componentName])
const componentTypes = generateComponentType(
input[componentpath][componentName]
//figma needs prefixed subcomponents, e.g.: for modal => modalHeader, modalBody, etc... and we need only the name of the subcomponent, so we access the data with the subcomponent object, containing the prefixed version and making a non-prefixed list of the same components to produce files, variable, theme names
const subcomponents = Object.keys(input[componentpath])
const subcomponentNames = subcomponents.reduce(
(acc, subcomponent) => [
...acc,
...(subcomponent.startsWith(acc[0]) &&
subcomponent.length > acc[0].length
? [unCapitalize(subcomponent.slice(acc[0].length))]
: [])
],
[subcomponents[0]]
)

const componentFileContent = `
subcomponents.forEach(async (subcomponent, subcomponentIndex) => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should use here a for...of, so the return value of the promises is not ignored

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this should be an issue in this case. What return value do I attempt to use anyways?
My main reason not to change this is that I need the index as well and if I use the for-of pattern, I need to set up a counter.

Please tell me if I misunderstand something

const subcomponentName = subcomponentNames[subcomponentIndex]

const componentName =
subcomponent === mainComponentName
? mainComponentName
: `${mainComponentName}${capitalize(subcomponentName)}`

componentAndSubcomponentNames.push(componentName)

const component = generateComponent(input[componentpath][subcomponent])

const componentTypes = generateComponentType(
input[componentpath][subcomponent]
)

const componentFileContent = `
import semantics from "../semantics"
import type { ${capitalize(
componentName
Expand All @@ -131,28 +156,28 @@ const setupThemes = async (targetPath, input) => {
export default ${componentName}
`

await createFile(
`${themePath}/components/${componentName}.ts`,
componentFileContent
)
if (themeIndex === 0) {
let importSemantics = ''
if (componentTypes.includes(`Semantics[`)) {
importSemantics = `import type { Semantics } from "../${theme}/semantics"`
}
let importBoxShadow = ''
if (componentTypes.includes('TokenBoxshadowValueInst')) {
importBoxShadow = `import type { TokenBoxshadowValueInst } from '../commonTypes'`
}
let importBorder = ''
if (componentTypes.includes('TokenBorderValue')) {
importBorder = `import type { TokenBorderValue } from '@tokens-studio/types'`
}
let importTypography = ''
if (componentTypes.includes('TokenTypographyValueInst')) {
importTypography = `import type { TokenTypographyValueInst } from '../commonTypes'`
}
const typeFileContent = `
await createFile(
`${themePath}/components/${componentName}.ts`,
componentFileContent
)
if (themeIndex === 0) {
let importSemantics = ''
if (componentTypes.includes(`Semantics[`)) {
importSemantics = `import type { Semantics } from "../${theme}/semantics"`
}
let importBoxShadow = ''
if (componentTypes.includes('TokenBoxshadowValueInst')) {
importBoxShadow = `import type { TokenBoxshadowValueInst } from '../commonTypes'`
}
let importBorder = ''
if (componentTypes.includes('TokenBorderValue')) {
importBorder = `import type { TokenBorderValue } from '@tokens-studio/types'`
}
let importTypography = ''
if (componentTypes.includes('TokenTypographyValueInst')) {
importTypography = `import type { TokenTypographyValueInst } from '../commonTypes'`
}
const typeFileContent = `
${importSemantics}
${importBoxShadow}
${importBorder}
Expand All @@ -162,30 +187,28 @@ const setupThemes = async (targetPath, input) => {

export default ${capitalize(componentName)}
`
await createFile(
`${targetPath}/componentTypes/${componentName}.ts`,
typeFileContent
)
}
await createFile(
`${targetPath}/componentTypes/${componentName}.ts`,
typeFileContent
)
}
})
}

//index file
const componentImports = themeData[theme].components
.map((componentpath) => {
const componentName =
componentpath.split('/')[componentpath.split('/').length - 1]

return `import ${unCapitalize(
componentName
)} from "./components/${unCapitalize(componentName)}"`
})
const componentImports = componentAndSubcomponentNames
.map(
(componentName) =>
`import ${unCapitalize(
componentName
)} from "./components/${unCapitalize(componentName)}"`
)
.join('\n')
const componentNames = themeData[theme].components
.map((componentpath) => {
const componentName =
componentpath.split('/')[componentpath.split('/').length - 1]
return `${componentName}: ${unCapitalize(componentName)}`
})
const componentNames = componentAndSubcomponentNames
.map(
(componentName) =>
`${capitalize(componentName)}: ${unCapitalize(componentName)}`
)
.join(',\n')
const indexFileContent = `
import primitives, {type Primitives} from "./primitives";
Expand All @@ -209,23 +232,19 @@ const setupThemes = async (targetPath, input) => {

//index type file
if (themeIndex === 0) {
const componentTypeImports = themeData[theme].components
.map((componentpath) => {
const componentName =
componentpath.split('/')[componentpath.split('/').length - 1]

return `import type ${capitalize(
componentName
)} from './${unCapitalize(componentName)}'`
})
const componentTypeImports = componentAndSubcomponentNames
.map(
(componentName) =>
`import type ${capitalize(componentName)} from './${unCapitalize(
componentName
)}'`
)
.join('\n')
const componentTypeExport = themeData[theme].components
.map((componentpath) => {
const componentName =
componentpath.split('/')[componentpath.split('/').length - 1]

return `${capitalize(componentName)}:${capitalize(componentName)}`
})
const componentTypeExport = componentAndSubcomponentNames
.map(
(componentName) =>
`${capitalize(componentName)}:${capitalize(componentName)}`
)
.join(',\n')

const componentsTypesFileContent = `
Expand Down Expand Up @@ -270,7 +289,7 @@ const setupThemes = async (targetPath, input) => {
textDecoration?: TokenTextDecorationValue
}

export type BaseTheme<P extends Record<string, any> = Record<string, any>, S extends Record<string, any> = Record<string, any>> = {
export type BaseTheme<P extends Record<string, any> = Record<string, any>, S extends Record<string, any> = Record<string, any>> = {
primitives: P
semantics: S
components: ComponentTypes
Expand Down
5 changes: 2 additions & 3 deletions packages/ui-tabs/src/Tabs/Panel/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,9 @@ import { View } from '@instructure/ui-view'
import { passthroughProps } from '@instructure/ui-react-utils'
import { Transition } from '@instructure/ui-motion'

import { withStyleRework as withStyle } from '@instructure/emotion'
import { withStyle } from '@instructure/emotion'

import generateStyle from './styles'
import generateComponentTheme from './theme'
import type { TabsPanelProps } from './props'
import { allowedProps } from './props'

Expand All @@ -41,7 +40,7 @@ parent: Tabs
id: Tabs.Panel
---
**/
@withStyle(generateStyle, generateComponentTheme)
@withStyle(generateStyle)
class Panel extends Component<TabsPanelProps> {
static readonly componentId = 'Tabs.Panel'

Expand Down
26 changes: 15 additions & 11 deletions packages/ui-tabs/src/Tabs/Panel/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,26 +22,30 @@
* SOFTWARE.
*/

import type { TabsPanelTheme } from '@instructure/shared-types'
import type { TabsPanelProps, TabsPanelStyle } from './props'
import type { NewComponentTypes, SharedTokens } from '@instructure/ui-themes'

type StyleParams = {
maxHeight: TabsPanelProps['maxHeight']
isSelected: TabsPanelProps['isSelected']
isHidden: boolean
}

/**
* ---
* private: true
* ---
* 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} state the state of the component, the style is applied to
* @param {Object} params the props and passed through data of the component, the style is applied to
* @return {Object} The final style object, which will be used in the component
*/
const generateStyle = (
componentTheme: TabsPanelTheme,
props: TabsPanelProps,
state: { isHidden: boolean }
componentTheme: NewComponentTypes['TabsPanel'],
params: StyleParams,
sharedTokens: SharedTokens
): TabsPanelStyle => {
const { maxHeight, isSelected } = props
const { isHidden } = state
const { maxHeight, isSelected, isHidden } = params

return {
panel: {
Expand All @@ -61,7 +65,7 @@ const generateStyle = (
display: 'none'
}),
'&:focus': {
outlineColor: componentTheme.focusOutlineColor
outlineColor: sharedTokens.focusOutline.infoColor
}
},
content: {
Expand All @@ -70,10 +74,10 @@ const generateStyle = (
width: '100%',
height: '100%',
borderWidth: componentTheme.borderWidth,
borderStyle: componentTheme.borderStyle,
borderStyle: 'solid',
background: componentTheme.background,
borderColor: componentTheme.borderColor,
color: componentTheme.color,
color: componentTheme.textColor,
borderLeft: 'none',
borderRight: 'none',
borderBottom: 'none',
Expand Down
Loading
Loading