-
Notifications
You must be signed in to change notification settings - Fork 60
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
Add new Table component #129
Merged
Merged
Changes from 7 commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
5423153
feat: add helper functions for
square-li 47ff45b
feat: add the main table component
square-li ce9422d
fix: remove generic types for TableProps
square-li 0585556
fix: add size to loading spinner
square-li a480de6
Merge branch 'feature-table' into feature-table
square-li 4b3861a
fix: remove unnecessary TS compiler options
square-li 2d5e133
update a few things based on comments from PR.
square-li 0595b12
Fix: remove full file eslint disable. Switch to minimal eslint disable.
square-li File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,6 @@ | ||
// eslint-disable-next-line import/no-extraneous-dependencies | ||
/* eslint-disable */ | ||
import 'jest-extended'; | ||
|
||
export declare global { | ||
var IS_REACT_ACT_ENVIRONMENT: boolean; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,2 @@ | ||
// export * from './table'; WIP | ||
export * from './table'; | ||
export * from './utils'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import React, { FunctionComponent } from 'react'; | ||
import { PropertyFilter, Table as AWSUITable } from '@awsui/components-react'; | ||
import { useCollection } from '@awsui/collection-hooks'; | ||
import { TableProps } from '../utils'; | ||
import { defaultI18nStrings, getDefaultColumnDefinitions } from '../utils/tableHelpers'; | ||
|
||
export const Table: FunctionComponent<TableProps> = (props) => { | ||
const { items, useCollectionOption = { sorting: {} }, columnDefinitions } = props; | ||
const { collectionProps, propertyFilterProps } = useCollection(items, useCollectionOption); | ||
return ( | ||
<AWSUITable | ||
{...props} | ||
{...collectionProps} | ||
columnDefinitions={getDefaultColumnDefinitions(columnDefinitions)} | ||
filter={<PropertyFilter {...propertyFilterProps} i18nStrings={defaultI18nStrings} />} | ||
/> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
import { STATUS_ICONS, StatusIcon } from '@synchro-charts/core'; | ||
import { getIcons } from './iconUtils'; | ||
|
||
describe('sets default pixel size', () => { | ||
it.each(STATUS_ICONS)('renders %p at correct default size', (iconName) => { | ||
const icon = getIcons(iconName)!; | ||
expect(icon?.props.width).toBe('16px'); | ||
expect(icon?.props.height).toBe('16px'); | ||
}); | ||
}); | ||
|
||
describe('sets customized color', () => { | ||
it.each(STATUS_ICONS)('renders %p with customized color or stroke', (iconName) => { | ||
const icon = getIcons(iconName, '#fffff')!; | ||
expect(icon?.props.fill || icon?.props.stroke).toBe('#fffff'); | ||
}); | ||
}); | ||
|
||
describe('sets icon size', () => { | ||
it.each(STATUS_ICONS)('renders %p at the correct size', (iconName) => { | ||
const size = 100; | ||
const icon = getIcons(iconName, undefined, size)!; | ||
expect(icon.props.width).toBe(`${size}px`); | ||
expect(icon.props.height).toBe(`${size}px`); | ||
}); | ||
}); | ||
|
||
it('returns normal icon from StatusIcon.ACKNOWLEDGED provided', () => { | ||
const iconName = StatusIcon.ACKNOWLEDGED; | ||
const icon = getIcons(iconName)!; | ||
expect(icon.props.stroke).toEqual('#3184c2'); | ||
}); | ||
|
||
it('returns normal icon from StatusIcon.ACTIVE provided', () => { | ||
const iconName = StatusIcon.ACTIVE; | ||
const icon = getIcons(iconName)!; | ||
expect(icon.props.fill).toEqual('#d13212'); | ||
}); | ||
|
||
it('returns normal icon from StatusIcon.ACKNOWLEDGED provided', () => { | ||
const iconName = StatusIcon.ACKNOWLEDGED; | ||
const icon = getIcons(iconName)!; | ||
expect(icon.props.stroke).toEqual('#3184c2'); | ||
}); | ||
|
||
it('returns normal icon from StatusIcon.DISABLED provided', () => { | ||
const iconName = StatusIcon.DISABLED; | ||
const icon = getIcons(iconName)!; | ||
expect(icon.props.stroke).toEqual('#687078'); | ||
}); | ||
|
||
it('returns normal icon from StatusIcon.LATCHED provided', () => { | ||
const iconName = StatusIcon.LATCHED; | ||
const icon = getIcons(iconName)!; | ||
expect(icon.props.fill).toEqual('#f89256'); | ||
}); | ||
|
||
it('returns normal icon from StatusIcon.SNOOZED provided', () => { | ||
const iconName = StatusIcon.SNOOZED; | ||
const icon = getIcons(iconName)!; | ||
expect(icon.props.stroke).toEqual('#879596'); | ||
}); | ||
|
||
it('returns normal icon from StatusIcon.SNOOZED provided with color', () => { | ||
const iconName = StatusIcon.SNOOZED; | ||
const icon = getIcons(iconName, 'white')!; | ||
expect(icon.props.stroke).toEqual('white'); | ||
}); | ||
|
||
it('returns error icon from StatusIcon.ERROR', () => { | ||
const iconName = StatusIcon.ERROR; | ||
const icon = getIcons(iconName); | ||
expect(icon).not.toBeNull(); | ||
}); | ||
|
||
it('returned undefined when invalid icon requested', () => { | ||
expect(getIcons('fake-icon' as StatusIcon)).toBeUndefined(); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
import React, { ReactElement, SVGAttributes } from 'react'; | ||
import { StatusIcon } from '@synchro-charts/core'; | ||
square-li marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
const DEFAULT_SIZE_PX = 16; | ||
|
||
export const icons = { | ||
normal(color?: string, size: number = DEFAULT_SIZE_PX) { | ||
return ( | ||
<svg width={`${size}px`} height={`${size}px`} viewBox="0 0 16 16" fill={color ? `${color}` : '#1d8102'}> | ||
<path d="M8 0C3.6 0 0 3.6 0 8s3.6 8 8 8 8-3.6 8-8-3.6-8-8-8zm0 14c-3.3 0-6-2.7-6-6s2.7-6 6-6 6 2.7 6 6-2.7 6-6 6z" /> | ||
<path d="M7 8.6l-2-2L3.6 8 7 11.4l4.9-4.9-1.4-1.4z" /> | ||
</svg> | ||
); | ||
}, | ||
active(color?: string, size: number = DEFAULT_SIZE_PX) { | ||
return ( | ||
<svg width={`${size}px`} height={`${size}px`} fill={color ? `${color}` : '#d13212'} viewBox="0 0 16 16"> | ||
<g fill="none" fillRule="evenodd"> | ||
<circle cx="8" cy="8" r="7" stroke={color ? `${color}` : '#d13212'} strokeWidth="2" /> | ||
<g transform="translate(7 4)"> | ||
<mask id="b" fill="#fff"> | ||
<path id="a" d="M2.00129021 6v2h-2V6h2zm0-6v5h-2V0h2z" /> | ||
</mask> | ||
<g mask="url(#b)"> | ||
<path fill={color ? `${color}` : '#d13212'} d="M-7-5H9v16H-7z" /> | ||
</g> | ||
</g> | ||
</g> | ||
</svg> | ||
); | ||
}, | ||
acknowledged(color?: string, size: number = DEFAULT_SIZE_PX) { | ||
return ( | ||
<svg width={`${size}px`} height={`${size}px`} viewBox="0 0 16 16" stroke={color ? `${color}` : '#3184c2'}> | ||
<path | ||
fill="none" | ||
strokeLinecap="round" | ||
strokeLinejoin="round" | ||
strokeWidth="2" | ||
d="M2 12.286h5.143L8.857 14l1.714-1.714H14V2H2v10.286z" | ||
/> | ||
<path | ||
fill="none" | ||
strokeLinecap="round" | ||
strokeWidth="2" | ||
strokeMiterlimit="10" | ||
d="M4.99 7H5v.01h-.01zM7.99 7H8v.01h-.01zM10.99 7H11v.01h-.01z" | ||
/> | ||
</svg> | ||
); | ||
}, | ||
disabled(color?: string, size: number = DEFAULT_SIZE_PX) { | ||
return ( | ||
<svg width={`${size}px`} height={`${size}px`} viewBox="0 0 16 16" stroke={color ? `${color}` : '#687078'}> | ||
<g fill="none" strokeWidth="2"> | ||
<circle cx="8" cy="8" r="7" strokeLinejoin="round" /> | ||
<path strokeLinecap="square" strokeMiterlimit="10" d="M11 8H5" /> | ||
</g> | ||
</svg> | ||
); | ||
}, | ||
latched(color?: string, size: number = DEFAULT_SIZE_PX) { | ||
return ( | ||
<svg width={`${size}px`} height={`${size}px`} viewBox="0 0 16 16" fill={color ? `${color}` : '#f89256'}> | ||
<path d="M15.9 14.6l-7-14c-.3-.7-1.5-.7-1.8 0l-7 14c-.2.3-.1.7 0 1 .2.2.6.4.9.4h14c.3 0 .7-.2.9-.5.1-.3.1-.6 0-.9zM2.6 14L8 3.2 13.4 14H2.6z" /> | ||
<path d="M7 11v2h2v-2zM7 6h2v4H7z" /> | ||
</svg> | ||
); | ||
}, | ||
snoozed(color?: string, size: number = DEFAULT_SIZE_PX) { | ||
return ( | ||
<svg width={`${size}px`} height={`${size}px`} viewBox="0 0 16 16" stroke={color ? `${color}` : '#879596'}> | ||
<g fill="none" strokeWidth="2"> | ||
<circle cx="8" cy="8" r="7" strokeLinejoin="round" /> | ||
<path strokeLinecap="square" strokeMiterlimit="10" d="M8 5v4H5" /> | ||
</g> | ||
</svg> | ||
); | ||
}, | ||
error(color?: string, size: number = DEFAULT_SIZE_PX) { | ||
return ( | ||
<svg | ||
width={`${size}px`} | ||
height={`${size}px`} | ||
viewBox="0 0 16 16" | ||
fill={color ? `${color}` : '#FF0000'} | ||
data-test-tag="error" | ||
> | ||
<path | ||
className="st4" | ||
d="M13.7 2.3C12.1.8 10.1 0 8 0S3.9.8 2.3 2.3C.8 3.9 0 5.9 0 8s.8 4.1 2.3 5.7C3.9 15.2 5.9 16 8 16s4.1-.8 5.7-2.3C15.2 12.1 16 10.1 16 8s-.8-4.1-2.3-5.7zm-1.5 9.9C11.1 13.4 9.6 14 8 14s-3.1-.6-4.2-1.8S2 9.6 2 8s.6-3.1 1.8-4.2S6.4 2 8 2s3.1.6 4.2 1.8S14 6.4 14 8s-.6 3.1-1.8 4.2z" | ||
/> | ||
<path | ||
className="st4" | ||
d="M10.1 4.5L8 6.6 5.9 4.5 4.5 5.9 6.6 8l-2.1 2.1 1.4 1.4L8 9.4l2.1 2.1 1.4-1.4L9.4 8l2.1-2.1z" | ||
/> | ||
</svg> | ||
); | ||
}, | ||
}; | ||
|
||
export const getIcons: ( | ||
name: StatusIcon, | ||
color?: string, | ||
size?: number | ||
) => ReactElement<SVGAttributes<unknown>> | undefined = (name: StatusIcon, color?: string, size?: number) => { | ||
if (icons[name]) { | ||
return icons[name](color, size); | ||
} | ||
/* eslint-disable-next-line no-console */ | ||
console.warn(`Invalid status icon requested: ${name}`); | ||
square-li marked this conversation as resolved.
Show resolved
Hide resolved
|
||
return undefined; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,2 @@ | ||
export { createTableItems } from './createTableItems'; | ||
export { CellItem, Item, ItemRef, TableItem } from './types'; | ||
export { CellItem, Item, ItemRef, TableItem, TableProps, ColumnDefinition, CellItemProps } from './types'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
import React from 'react'; | ||
square-li marked this conversation as resolved.
Show resolved
Hide resolved
|
||
import { createRoot, Root } from 'react-dom/client'; | ||
import { act } from 'react-dom/test-utils'; | ||
import { LoadingSpinner } from './spinner'; | ||
|
||
globalThis.IS_REACT_ACT_ENVIRONMENT = true; | ||
describe('size', () => { | ||
let container: HTMLDivElement; | ||
let root: Root; | ||
|
||
beforeEach(() => { | ||
container = document.createElement('div'); | ||
document.body.appendChild(container); | ||
root = createRoot(container); | ||
}); | ||
|
||
afterEach(() => { | ||
act(() => { | ||
root.unmount(); | ||
container.remove(); | ||
}); | ||
}); | ||
|
||
it('does not specify height and width when no size provided', async () => { | ||
act(() => { | ||
root.render(<LoadingSpinner />); | ||
}); | ||
|
||
const svgElement = container.getElementsByTagName('svg').item(0)!; | ||
|
||
expect(svgElement.style.height).toBe(''); | ||
expect(svgElement.style.width).toBe(''); | ||
}); | ||
|
||
it('does specify height and width when size provided', async () => { | ||
const SIZE = 34; | ||
act(() => { | ||
root.render(<LoadingSpinner size={SIZE} />); | ||
}); | ||
const svgElement = container.getElementsByTagName('svg').item(0)!; | ||
expect(svgElement.style.height).toBe(`${SIZE}px`); | ||
expect(svgElement.style.width).toBe(`${SIZE}px`); | ||
}); | ||
}); | ||
|
||
describe('dark mode', () => { | ||
let container: HTMLDivElement; | ||
let root: Root; | ||
|
||
beforeEach(() => { | ||
container = document.createElement('div'); | ||
document.body.appendChild(container); | ||
root = createRoot(container); | ||
}); | ||
|
||
afterEach(() => { | ||
act(() => { | ||
root.unmount(); | ||
container.remove(); | ||
}); | ||
}); | ||
|
||
it('does not have the dark class present when dark is false', async () => { | ||
act(() => { | ||
root.render(<LoadingSpinner />); | ||
}); | ||
const svgElement = container.getElementsByTagName('svg').item(0)!; | ||
expect(svgElement.classList).not.toContain('dark'); | ||
}); | ||
|
||
it('does not have the dark class present when dark is false', async () => { | ||
act(() => { | ||
root.render(<LoadingSpinner dark />); | ||
}); | ||
const svgElement = container.getElementsByTagName('svg').item(0)!; | ||
expect(svgElement.classList).toContain('dark'); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
// Copied from Synchro-charts "ScLoadingSpinner" | ||
import React from 'react'; | ||
|
||
export const LoadingSpinner: React.FunctionComponent<{ size?: number; dark?: boolean } | Record<string, never>> = ( | ||
props | ||
) => { | ||
const { size, dark = false } = props; | ||
|
||
return ( | ||
<svg | ||
className={dark ? 'dark' : undefined} | ||
style={size != null ? { width: `${size}px`, height: `${size}px` } : {}} | ||
data-testid="loading" | ||
viewBox="0 0 200 200" | ||
> | ||
<defs> | ||
<clipPath id="a"> | ||
<path d="M200 100a100 100 0 11-2.19-20.79l-9.78 2.08A90 90 0 10190 100z" /> | ||
</clipPath> | ||
<filter id="b" x="0" y="0"> | ||
<feGaussianBlur in="SourceGraphic" stdDeviation="3" /> | ||
</filter> | ||
<path id="c" d="M250 100a150 150 0 01-3.28 31.19L100 100z" /> | ||
</defs> | ||
<g clipPath="url(#a)"> | ||
<g filter="url(#b)" transform="rotate(-6 100 100)"> | ||
<use xlinkHref="#c" fillOpacity="0" /> | ||
<use xlinkHref="#c" fillOpacity=".03" transform="rotate(12 100 100)" /> | ||
<use xlinkHref="#c" fillOpacity=".07" transform="rotate(24 100 100)" /> | ||
<use xlinkHref="#c" fillOpacity=".1" transform="rotate(36 100 100)" /> | ||
<use xlinkHref="#c" fillOpacity=".14" transform="rotate(48 100 100)" /> | ||
<use xlinkHref="#c" fillOpacity=".17" transform="rotate(60 100 100)" /> | ||
<use xlinkHref="#c" fillOpacity=".2" transform="rotate(72 100 100)" /> | ||
<use xlinkHref="#c" fillOpacity=".24" transform="rotate(84 100 100)" /> | ||
<use xlinkHref="#c" fillOpacity=".28" transform="rotate(96 100 100)" /> | ||
<use xlinkHref="#c" fillOpacity=".31" transform="rotate(108 100 100)" /> | ||
<use xlinkHref="#c" fillOpacity=".34" transform="rotate(120 100 100)" /> | ||
<use xlinkHref="#c" fillOpacity=".38" transform="rotate(132 100 100)" /> | ||
<use xlinkHref="#c" fillOpacity=".41" transform="rotate(144 100 100)" /> | ||
<use xlinkHref="#c" fillOpacity=".45" transform="rotate(156 100 100)" /> | ||
<use xlinkHref="#c" fillOpacity=".48" transform="rotate(168 100 100)" /> | ||
<use xlinkHref="#c" fillOpacity=".52" transform="rotate(180 100 100)" /> | ||
<use xlinkHref="#c" fillOpacity=".55" transform="rotate(192 100 100)" /> | ||
<use xlinkHref="#c" fillOpacity=".59" transform="rotate(204 100 100)" /> | ||
<use xlinkHref="#c" fillOpacity=".62" transform="rotate(216 100 100)" /> | ||
<use xlinkHref="#c" fillOpacity=".66" transform="rotate(228 100 100)" /> | ||
<use xlinkHref="#c" fillOpacity=".69" transform="rotate(240 100 100)" /> | ||
<use xlinkHref="#c" fillOpacity=".7" transform="rotate(252 100 100)" /> | ||
<use xlinkHref="#c" fillOpacity=".72" transform="rotate(264 100 100)" /> | ||
<use xlinkHref="#c" fillOpacity=".76" transform="rotate(276 100 100)" /> | ||
<use xlinkHref="#c" fillOpacity=".79" transform="rotate(288 100 100)" /> | ||
<use xlinkHref="#c" fillOpacity=".83" transform="rotate(300 100 100)" /> | ||
<use xlinkHref="#c" fillOpacity=".86" transform="rotate(312 100 100)" /> | ||
<use xlinkHref="#c" fillOpacity=".93" transform="rotate(324 100 100)" /> | ||
<use xlinkHref="#c" fillOpacity=".97" transform="rotate(336 100 100)" /> | ||
<use xlinkHref="#c" transform="rotate(348 100 100)" /> | ||
</g> | ||
</g> | ||
</svg> | ||
); | ||
}; |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why switch to full disable? Better to disable just what we need to