Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: Combine Icon Buttons with Primary, Secondary and Tertiary #1477

Merged
Show file tree
Hide file tree
Changes from 96 commits
Commits
Show all changes
106 commits
Select commit Hold shift + click to select a range
b50db84
feat: Merge icon buttons with our regular buttons
Feb 14, 2022
8faf7e4
chore: Migrate icon buttons into primary
Feb 15, 2022
5707ba9
fix: Update border styles
Feb 16, 2022
5ab73e6
Merge branch 'prerelease/major' of github.com:Workday/canvas-kit into…
Feb 16, 2022
ecf7fc3
fix: Update paths after merge from major
Feb 16, 2022
5ecaf7e
fix: Update to remove extra span
Feb 16, 2022
12c51a1
fix: Refactoro out button container
Feb 17, 2022
b564219
fix: Further clean up on buttons
Feb 17, 2022
f999f07
fix: Remove cx function
Feb 22, 2022
524a6fc
Update modules/react/button/lib/PrimaryButtonKing.tsx
mannycarrera4 Feb 22, 2022
40cb31e
fix: Clean up base button and work on tertiary
Feb 22, 2022
715095c
fix: Update tertiary button styles
Mar 1, 2022
3804999
Merge branch 'prerelease/major' of github.com:Workday/canvas-kit into…
Mar 1, 2022
2687e1d
fix: Add secondary icon to testing
Mar 1, 2022
77030c0
fix: Adjust colors and padding
Mar 1, 2022
26b4b27
docs: Added docs to on buttons
Mar 1, 2022
e868b68
fix: Work on pagination button
Mar 2, 2022
0ae7ee8
fix: Update pagination buttons
Mar 2, 2022
36faf56
fix: Refactor icon button and refacotr segmented control
Mar 2, 2022
bd049bb
fix: Clean up segemented control
Mar 3, 2022
32cbef0
fix: Update tests and imports
Mar 3, 2022
c9b0bfb
fix: Replace old with new
Mar 3, 2022
4a6f87a
fix: Clean up typecheck
Mar 4, 2022
e0a4da9
fix: Update buttons to be rendered as element
Mar 7, 2022
6a9bea1
fix: Update button label to use create component
Mar 7, 2022
4447e3a
fix: Remove icon button stories
Mar 7, 2022
5b0ab98
chore: Remove icon button references and stories and code
Mar 7, 2022
17fcb59
fix: Converted svg to box element under the hood
Mar 7, 2022
72ddee0
Merge branch 'prerelease/major' of github.com:Workday/canvas-kit into…
Mar 7, 2022
ccd96fa
fix: Add fillicon to styles and add classname
Mar 7, 2022
f7b33b4
fix: Remove button label data classname
Mar 7, 2022
6320826
fix: Update prop names
Mar 7, 2022
946e313
fix: Update typings for label icon
Mar 7, 2022
cdfde41
fix: Update size for system icon
Mar 7, 2022
f7bf186
fix: Update icon size
Mar 7, 2022
b7a92ce
fix: Update migration guide and system icon
Mar 8, 2022
8688521
fix: Refactor icon components to use create component
Mar 8, 2022
cf843fd
fix: Update types
Mar 8, 2022
62bf7f8
fix: Add back in button size
Mar 8, 2022
b6c7926
fix: Update styles to match chromatic
Mar 9, 2022
577c7cd
fix: Update hover color for tertiary icon
Mar 9, 2022
3e802a3
fix: Update styles for status indicator
Mar 9, 2022
372376b
fix: Update types
Mar 9, 2022
3cc8c66
fix: Update segmented control styles
Mar 9, 2022
a5b3e2c
fix: Clean up padding for tertiary
Mar 9, 2022
f719d8c
fix: Update small icon button
Mar 9, 2022
c899dba
fix: Update styles that were found during qa
Mar 9, 2022
a467631
fix: Update tertiary width to auto
Mar 9, 2022
f531387
fix: Update color for tertiary
Mar 9, 2022
e46d4d9
fix: Update focus color for tertiary
Mar 9, 2022
9cf7a30
fix: Update disabled for tertiary
Mar 9, 2022
bae558a
fix: Update migration guide
Mar 9, 2022
88b6561
docs: Added section for other breaking changes
Mar 9, 2022
0845aff
fix: Calculate padding better
Mar 10, 2022
bcb1b10
fix: Update type for padding function
Mar 10, 2022
c34fbc0
fix: Figure out failing chromatic
Mar 10, 2022
856cdb9
fix: Test failing tests
Mar 11, 2022
e533c82
fix: Remove console
Mar 11, 2022
729ae1d
fix: Remove data label
Mar 14, 2022
b074ece
fix: Try to optimize button styles
Mar 14, 2022
94cbddb
fix: Use boxStylefn and update readme
Mar 15, 2022
c9daee0
test: Update test
Mar 15, 2022
bf1b49c
test: Add codemod for icon position and icon package
Mar 16, 2022
6d5a661
fix: Update test name
Mar 16, 2022
3410926
test: Add codemod for segmented control
Mar 16, 2022
6eefa80
fix: Update migration guide
Mar 16, 2022
4a40f02
fix: Start working on icon button codemod
Mar 16, 2022
208f49d
test: Add more test for codemod
Mar 17, 2022
b9fd158
docs: Add info regarding base button
Mar 17, 2022
b4d14de
fix: Update codemod
Mar 18, 2022
acc2935
fix: Upate codemod to handle styled icon button
Mar 21, 2022
3a83c79
test: Add more coverage for codemod
Mar 22, 2022
cd8e894
fix: Update comment for codemod
Mar 22, 2022
21ba4b3
fix: Update migration guide
Mar 22, 2022
0a532b8
fix: Update doc
Mar 23, 2022
ab660b7
fix: Update migration guide to add info on side panel
Mar 23, 2022
f4af232
fix: Update typo
Mar 23, 2022
1fe4bcc
fix: Clean up some codemod
Mar 24, 2022
50e75b6
Update modules/react/button/stories/button/examples/Primary.tsx
mannycarrera4 Mar 25, 2022
99f375c
Update modules/react/button/stories/button/examples/PrimaryInverse.tsx
mannycarrera4 Mar 25, 2022
35aacde
Update modules/react/button/stories/button/examples/Secondary.tsx
mannycarrera4 Mar 25, 2022
7035a63
Update modules/react/button/stories/button/examples/SecondaryInverse.tsx
mannycarrera4 Mar 25, 2022
61999de
Update modules/react/button/stories/button/examples/Tertiary.tsx
mannycarrera4 Mar 25, 2022
8504e6f
Update modules/react/button/stories/button/examples/TertiaryInverse.tsx
mannycarrera4 Mar 25, 2022
3b4bd38
Update modules/react/button/stories/visual-testing/stories_PrimaryBut…
mannycarrera4 Mar 25, 2022
eae6121
Update modules/react/button/stories/visual-testing/stories_TertiaryBu…
mannycarrera4 Mar 25, 2022
f09c844
Update modules/react/layout/stories/Stack.stories.mdx
mannycarrera4 Mar 25, 2022
701d417
Update modules/docs/mdx/7.0-MIGRATION-GUIDE.mdx
mannycarrera4 Mar 25, 2022
cff868e
fix: Update pr per comments, clean up code
Mar 25, 2022
6b228f3
fix: Clean up codemod per PR
Mar 29, 2022
502cca7
fix: Updat codemod per recs
Mar 29, 2022
b641722
Update modules/docs/mdx/7.0-MIGRATION-GUIDE.mdx
mannycarrera4 Mar 31, 2022
7f7dfb4
Update modules/docs/mdx/7.0-MIGRATION-GUIDE.mdx
mannycarrera4 Mar 31, 2022
fda512c
Update modules/docs/mdx/7.0-MIGRATION-GUIDE.mdx
mannycarrera4 Mar 31, 2022
66c6a92
Update modules/react/button/stories/button/examples/Secondary.tsx
mannycarrera4 Mar 31, 2022
7f74944
fix: Clean up stories
Mar 31, 2022
b6ff3e2
fix: Update migration guide
Mar 31, 2022
2a82979
Update modules/codemod/lib/v7/recategorizeIconButtons.ts
mannycarrera4 Mar 31, 2022
8b077e3
fix: Clean up code and add toggle button for breadcrumbs
Mar 31, 2022
331b997
fix: Update icon sizes for button label icon
Mar 31, 2022
cea263b
fix: Update return for codemod
Mar 31, 2022
21ec0ec
fix: Update styles for popup and breadcrumbs
Apr 1, 2022
252f067
fix: Update breadcrumbs
Apr 1, 2022
f867ab2
fix: Update padding for tertiary button
Apr 4, 2022
2b9ce1c
fix: Update teriary text
Apr 4, 2022
e0adc10
fix: Update button padding
Apr 4, 2022
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
1 change: 0 additions & 1 deletion .storybook/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ const routes = {
'/tokens/type/': 'tokens-tokens-react--type',
'/components/buttons/button/': 'components-buttons-button-react--primary',
'/components/buttons/action-bar/': 'components-buttons-action-bar-react--basic',
'/components/buttons/icon-button/': 'components-buttons-button-react-icon-button--circle',
'/components/containers/card/': 'components-containers-card-react--basic',
'/components/containers/side-panel/': 'preview-side-panel-react--basic',
'/components/containers/table/': 'components-containers-table-react--basic',
Expand Down
6 changes: 3 additions & 3 deletions cypress/integration/ColorPicker.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,10 +114,10 @@ describe('ColorPicker', () => {
cy.viewport(800, 1000);
});

describe('Icon Button ColorPicker Popup', () => {
context('when the IconButton is clicked', () => {
describe('Icon button ColorPicker Popup', () => {
context('when the SecondaryButton is clicked', () => {
beforeEach(() => {
h.stories.load(colorPickerStory, 'Icon Button Popup');
h.stories.load(colorPickerStory, 'Icon button Popup');
getOpenButton().click();
});

Expand Down
160 changes: 160 additions & 0 deletions modules/codemod/lib/v7/recategorizeIconButtons.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
import {
API,
FileInfo,
Options,
StringLiteral,
JSXIdentifier,
JSXAttribute,
ASTPath,
JSXElement,
} from 'jscodeshift';
import {getImportRenameMap} from './utils/getImportRenameMap';

const updateJSXTag = (nodePath: ASTPath<JSXElement>, newTag: string) => {
const {name: componentName} = nodePath.value.openingElement.name as JSXIdentifier;
if (componentName === 'IconButton') {
(nodePath.value.openingElement.name as JSXIdentifier).name = newTag;
if (nodePath.value.closingElement) {
(nodePath.value.closingElement.name as JSXIdentifier).name = newTag;
}
}
};

export default function transformer(file: FileInfo, api: API, options: Options) {
const j = api.jscodeshift;
const root = j(file.source);
const requiredImportSpecifiers: string[] = [];

/**
* 1. Find button imports
*/
const {containsCanvasImports, importMap, styledMap} = getImportRenameMap(
j,
root,
'@workday/canvas-kit-react/button'
);
if (!containsCanvasImports) {
return file.source;
}

let buttonType = 'TertiaryButton'; //default button if no variant is specified

// Button Mapping
// circle -> tertiary
// circle-filled -> secondary
// inverse -> tertiary inverse
// inverse-filled -> secondary inverse
// plain/square -> not supported
// square-filled -> not supported

/**
* 2. Find `IconButton`
* - If it has no variant, it means it's "circle" which is the default
* - Swap to `TertiaryButton`
* - Add `TertiaryButton` import if it doesn't exist.
* - If not
* - check the variant of the IconButton
* - Swap it out for the appropriate mapping
*/
root
.find(
j.JSXElement,
(value: JSXElement) =>
value.openingElement.name.type === 'JSXIdentifier' &&
(value.openingElement.name.name === importMap.IconButton ||
value.openingElement.name.name === styledMap.IconButton)
)
.forEach(nodePath => {
const attrs = nodePath.value.openingElement.attributes;

const variantProp = attrs?.find(
attr => attr.type === 'JSXAttribute' && attr.name.name === 'variant'
);

// Default IconButton variant is `circle`
if (!variantProp) {
updateJSXTag(nodePath, buttonType);
requiredImportSpecifiers.push(buttonType);
} else {
const variantPropValue = ((variantProp as JSXAttribute).value as StringLiteral)?.value;

buttonType = /filled/gi.test(variantPropValue) ? 'SecondaryButton' : 'TertiaryButton';
if (!variantPropValue.includes('inverse')) {
nodePath.value.openingElement.attributes?.splice(attrs?.indexOf(variantProp)!, 1);
}

updateJSXTag(nodePath, buttonType);
requiredImportSpecifiers.push(buttonType);
}
});
mannycarrera4 marked this conversation as resolved.
Show resolved Hide resolved

// Find all instances of IconButton within a style function
// const StyledIconButton = styled(IconButton) gets renamed to
// const StyledIconButton = styled(CorrectButtonMapping)
root.find(j.VariableDeclarator).forEach(nodePath => {
if (
nodePath.value.init?.type === 'CallExpression' &&
nodePath.value.init.callee.type === 'CallExpression' &&
nodePath.value.init.callee.arguments[0].type === 'Identifier'
) {
nodePath.value.init.callee.arguments[0].name = buttonType;
requiredImportSpecifiers.push(buttonType);
}
});

/**
* Remove old imports: `IconButton`
* Add new required imports
*/
const buttonImports = root.find(j.ImportDeclaration, {
source: {value: (value: string) => value.includes('@workday/canvas-kit-react')},
});

if (!buttonImports.length) {
// Add new specifiers to a new import
const allImports = root.find(j.ImportDeclaration);

const lastImport = allImports.at(allImports.length);
if (lastImport) {
lastImport.insertAfter(
j.importDeclaration(
requiredImportSpecifiers.map(specifier => j.importSpecifier(j.identifier(specifier))),
j.stringLiteral('@workday/canvas-kit-react/button')
)
);
}
} else {
buttonImports.forEach(({node}) => {
const specifiersToRemove = ['IconButton'];

// Remove old specifiers
if (
typeof node.source.value === 'string' &&
node.source.value.includes('@workday/canvas-kit-react')
) {
node.specifiers?.forEach(specifier => {
if (
specifier.type === 'ImportSpecifier' &&
specifiersToRemove.includes(specifier.imported.name)
) {
// delete specifier
node.specifiers?.splice(node.specifiers?.indexOf(specifier)!, 1);
}
});
}

// Add new specifiers to existing import
requiredImportSpecifiers.forEach(specifier => {
if (
!node.specifiers?.find(
existing => existing.type === 'ImportSpecifier' && existing.imported.name === specifier
)
) {
node.specifiers?.push(j.importSpecifier(j.identifier(specifier)));
}
});
});
}

return root.toSource();
}
57 changes: 57 additions & 0 deletions modules/codemod/lib/v7/renameIconPosition.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import {API, FileInfo, Options, JSXElement, JSXAttribute, JSXSpreadAttribute} from 'jscodeshift';

import {getImportRenameMap} from './utils/getImportRenameMap';

export default function transformer(file: FileInfo, api: API, options: Options) {
const j = api.jscodeshift;

const root = j(file.source);

const {containsCanvasImports, importMap, styledMap} = getImportRenameMap(
j,
root,
'@workday/canvas-kit-react/button'
);

if (!containsCanvasImports) {
return file.source;
}

root
.find(
j.JSXElement,
(value: JSXElement) =>
value.openingElement.name.type === 'JSXIdentifier' &&
(value.openingElement.name.name ===
(importMap.PrimaryButton || importMap.SecondaryButton) ||
value.openingElement.name.name === (styledMap.PrimaryButton || styledMap.SecondaryButton))
)
.forEach(nodePath => {
const findAttribute = (name: string) => (item: JSXAttribute | JSXSpreadAttribute) => {
if (
item.type === 'JSXAttribute' &&
item.name.type === 'JSXIdentifier' &&
item.name.name === name
) {
return true;
}
return false;
};
mannycarrera4 marked this conversation as resolved.
Show resolved Hide resolved
const attributes = nodePath.value.openingElement.attributes;
if (attributes) {
const iconPosition = attributes.find(findAttribute('iconPosition')) as
| JSXAttribute
| undefined;

if (iconPosition?.value?.type === 'StringLiteral') {
if (iconPosition.value.value === 'left') {
iconPosition.value.value = 'start';
} else {
iconPosition.value.value = 'end';
}
}
}
});

return root.toSource();
}
82 changes: 82 additions & 0 deletions modules/codemod/lib/v7/renameIconRef.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import {API, FileInfo, Options, JSXIdentifier} from 'jscodeshift';
import {getImportRenameMap} from './utils/getImportRenameMap';

const inputsMap: {
[packageName: string]: string[];
} = {
'@workday/canvas-kit-react/icon': [
'AccentIcon',
'AppletIcon',
'SystemIcon',
'SystemIconCircle',
'Graphic',
'Svg',
],
};

export default function transformer(file: FileInfo, api: API, options: Options) {
const j = api.jscodeshift;

const root = j(file.source);

// defaultImports should be an array of local names that were imported using
// a default import from any of the modules listed in inputsMap. For example,
// given...
//
// ```
// import Checkbox from '@workday/canvas-kit-react/checkbox';
// import CanvasTextArea from '@workday/canvas-kit-react/text-area';
// import {TextInput} from '@workday/canvas-kit-react/text-input';
// import StatusIndicator from '@workday/canvas-kit-react/status-indicator';
// ```
//
// ... defaultImports should be set to `['Checkbox', 'CanvasTextArea']`
const defaultImports: string[] = [];
root.find(j.ImportDefaultSpecifier).forEach(nodePath => {
const packageName = nodePath.parent.node.source.value;
const localName = nodePath.value.local?.name;
if (packageName in inputsMap && localName) {
defaultImports.push(localName);
}
});

let runningSource = file.source;
for (const inputPackageName of Object.keys(inputsMap)) {
const currentRoot = j(runningSource);

const {containsCanvasImports, importMap, styledMap} = getImportRenameMap(
j,
currentRoot,
inputPackageName
);

if (containsCanvasImports) {
const inputNames = inputsMap[inputPackageName];
currentRoot
.find(j.JSXIdentifier, (value: JSXIdentifier) => value.name === 'iconRef')
.replaceWith(nodePath => {
const elementName = nodePath.parent?.parent?.value?.name?.name;
// Rewrite inputRef to ref if any of the following are true:
// (a) elementName was the name used in a default import of the current
// input being processed (e.g., `import TextInput ...`)
// (b) elementName was the name used in a named import of the current
// input being processed (e.g., `import {TextInput} ...` or
// `import {TextInput as CanvasTextInput} ...`)
// (c) elementName was created by calling `styled` on the current input
// being processed (e.g., `const StyledTextInput = styled(TextInput)`)
if (
defaultImports.includes(elementName) ||
inputNames.map(n => importMap[n]).includes(elementName) ||
inputNames.map(n => styledMap[n]).includes(elementName)
) {
return j.jsxIdentifier('ref');
}
return nodePath.value;
});

runningSource = currentRoot.toSource();
}
}

return runningSource;
}
Loading