Skip to content

Commit

Permalink
Upgrade Salt and replace components
Browse files Browse the repository at this point in the history
  • Loading branch information
joshwooding committed Jun 25, 2024
1 parent 4883f2f commit dcf72a3
Show file tree
Hide file tree
Showing 39 changed files with 374 additions and 382 deletions.
6 changes: 6 additions & 0 deletions docs/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@ sharedConfig:
link: /mosaic/author/index
- title: Publish
link: /mosaic/publish/index
- title: Support
links:
- title: FAQs
link: /mosaic/faqs/index
- title: Contact Us
link: /mosaic/contact-us/index
footer:
description: Coming soon
title: Mosaic BETA
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
},
"scripts": {
"build:site": "turbo run build --filter=@jpmorganchase/mosaic-site",
"build:packages": "turbo run build --filter=!@jpmorganchase/mosaic-site",
"build": "turbo run build",
"clean": "turbo run clean",
"copy:rig:images": "cp -r ./assets/[!.]* ./packages/rig/public/img",
Expand Down
3 changes: 1 addition & 2 deletions packages/components-labs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,7 @@
"dependencies": {
"@jpmorganchase/mosaic-components": "^0.1.0-beta.78",
"@jpmorganchase/mosaic-theme": "^0.1.0-beta.78",
"@salt-ds/core": "^1.26.0",
"@salt-ds/lab": "1.0.0-alpha.42",
"@salt-ds/core": "^1.30.0",
"@vanilla-extract/css": "^1.6.0",
"@vanilla-extract/recipes": "^0.2.1",
"@vanilla-extract/sprinkles": "^1.3.0",
Expand Down
62 changes: 30 additions & 32 deletions packages/components-labs/src/Sitemap/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import React, { RefObject, useEffect, useRef, useState } from 'react';
import React, { RefObject, SyntheticEvent, useEffect, useRef, useState } from 'react';
import * as d3 from 'd3';
import { Spinner } from '@salt-ds/core';
import { Dropdown, DropdownButton, SelectionChangeHandler } from '@salt-ds/lab';
import { Spinner, Dropdown, Option } from '@salt-ds/core';
import warning from 'warning';
import { Icon, Caption2 } from '@jpmorganchase/mosaic-components';

Expand All @@ -19,6 +18,8 @@ export interface SitemapProps {
initialNamespaceFilters?: string[];
}

const dottedFileFilter = (pagePath: string) => /\/[^.]*$/.test(pagePath);

const filterPaths = (slugs: string[], namespaceFilters: string[]) => {
const namespaceFilter = (pagePath: string) => {
if (!namespaceFilters.length) {
Expand All @@ -37,21 +38,6 @@ const filterPaths = (slugs: string[], namespaceFilters: string[]) => {
return filteredPaths;
};

const drawSitemap = (filteredPaths: string[], containerRef: RefObject<HTMLDivElement>) => {
if (!containerRef?.current) {
throw new Error('no container ref defined for sitemap');
}

d3.select(containerRef.current).html('');
d3.select(containerRef.current).append(() =>
drawTree(parseFileSystem(filteredPaths), {
label: node => node.name.substring(node.name.lastIndexOf('/') + 1),
link: node => node.link,
width: 1152
}).node()
);
};

type FileSystemBase = {
name: string;
parent: string | undefined;
Expand Down Expand Up @@ -108,7 +94,20 @@ const parseFileSystem = (fileSystem: any) => {
.parentId((data: FileSystemItem) => data.parent)(hierachyData);
};

const dottedFileFilter = (pagePath: string) => /\/[^.]*$/.test(pagePath);
const drawSitemap = (filteredPaths: string[], containerRef: RefObject<HTMLDivElement>) => {
if (!containerRef?.current) {
throw new Error('no container ref defined for sitemap');
}

d3.select(containerRef.current).html('');
d3.select(containerRef.current).append(() =>
drawTree(parseFileSystem(filteredPaths), {
label: node => node.name.substring(node.name.lastIndexOf('/') + 1),
link: node => node.link,
width: 1152
}).node()
);
};

const filterButtonLabel = (selectedItems: string[] | undefined) => {
if (!selectedItems || selectedItems.length === 0) {
Expand All @@ -130,7 +129,6 @@ export const Sitemap: React.FC<React.PropsWithChildren<SitemapProps>> = ({
const containerRef = useRef<HTMLDivElement>(null);
const dataRef = useRef<string[]>();
const [loading, setLoading] = useState<boolean>(true);
const [, setIsOpen] = useState(false);
const [error, setError] = useState<string>();
const [namespaceFilters, setNamespaceFilters] = useState<string[]>(initialNamespaceFilters);
const [namespaces, setNamespaces] = useState<string[]>([]);
Expand Down Expand Up @@ -182,7 +180,7 @@ export const Sitemap: React.FC<React.PropsWithChildren<SitemapProps>> = ({
}
}, [href, namespaceFilters]);

const handleSelect: SelectionChangeHandler<string, 'multiple'> = (_e, selectedItems) => {
const handleSelect = (_e: SyntheticEvent, selectedItems: string[]) => {
setNamespaceFilters(selectedItems);
};

Expand All @@ -193,18 +191,18 @@ export const Sitemap: React.FC<React.PropsWithChildren<SitemapProps>> = ({
<>
<Caption2 className={styles.pageCount}>Number of pages: {pageCount}</Caption2>
<Dropdown
triggerComponent={
<DropdownButton
IconComponent={DropdownIcon}
label={filterButtonLabel(namespaceFilters)}
/>
}
width={200}
onOpenChange={setIsOpen}
startAdornment={<DropdownIcon />}
value={filterButtonLabel(namespaceFilters)}
style={{ width: 200 }}
onSelectionChange={handleSelect}
selectionStrategy="multiple"
source={namespaces}
/>
multiselect
>
{namespaces.map(namespace => (
<Option key={namespace} value={namespace}>
{namespace}
</Option>
))}
</Dropdown>
</>
) : null}
</div>
Expand Down
4 changes: 2 additions & 2 deletions packages/components/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@
"dependencies": {
"@jpmorganchase/mosaic-store": "^0.1.0-beta.78",
"@jpmorganchase/mosaic-theme": "^0.1.0-beta.78",
"@salt-ds/core": "^1.26.0",
"@salt-ds/lab": "1.0.0-alpha.42",
"@salt-ds/core": "^1.30.0",
"@salt-ds/lab": "1.0.0-alpha.48",
"@vanilla-extract/css": "^1.6.0",
"@vanilla-extract/sprinkles": "^1.3.0",
"@vanilla-extract/recipes": "^0.2.1",
Expand Down
44 changes: 20 additions & 24 deletions packages/components/src/FilterToolbar/FilterDropdown/index.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import React, { useMemo, useState } from 'react';
import classnames from 'clsx';
import { Dropdown, DropdownButton, DropdownProps, SelectionChangeHandler } from '@salt-ds/lab';
import React, { SyntheticEvent, useMemo } from 'react';
import { Dropdown, DropdownProps, Option } from '@salt-ds/core';
import { Icon } from '../../Icon';
import styles from './styles.css';
import { useToolbarDispatch, useToolbarState } from '../ToolbarProvider';

const defaultButtonLabel = (selectedItems: string[] | undefined) => {
Expand All @@ -15,9 +13,12 @@ const defaultButtonLabel = (selectedItems: string[] | undefined) => {
return `${selectedItems.length} Items Selected`;
};

export interface FilterDropdownProps extends DropdownProps<string, 'multiple'> {
export interface FilterDropdownProps extends DropdownProps {
/** Callback to translate the selected list item to a Button label */
labelButton?: (selectedItems: string[] | undefined) => string;
/** Dropdown list source */
source?: string[];
itemToString?: DropdownProps['valueToString'];
}

const CLEAR_ALL = 'Clear all';
Expand All @@ -31,32 +32,27 @@ export function FilterDropdown({
}: FilterDropdownProps) {
const dispatch = useToolbarDispatch();
const { filters = [] } = useToolbarState();
const [isOpen, setIsOpen] = useState(false);
const listItems = useMemo(() => (source.length > 1 ? [...source, CLEAR_ALL] : source), [source]);
const handleSelect: SelectionChangeHandler<string, 'multiple'> = (_e, selectedItems) => {
const handleSelect = (_e: SyntheticEvent, selectedItems: string[]) => {
const nextSelectedItems: string[] = selectedItems.includes(CLEAR_ALL) ? [] : selectedItems;
dispatch({ type: 'setFilters', value: nextSelectedItems });
};
return (
<Dropdown<string, 'multiple'>
aria-label={isOpen ? 'close filters menu' : 'open filters menu'}
className={classnames(className, styles.root)}
itemToString={itemToString}
onOpenChange={setIsOpen}
<Dropdown
aria-label="Filters"
className={className}
valueToString={itemToString}
value={labelButton ? labelButton(filters) : defaultButtonLabel(filters)}
startAdornment={<Icon name="filter" />}
onSelectionChange={handleSelect}
selected={filters}
selectionStrategy="multiple"
source={listItems}
triggerComponent={
<span className={styles.triggerRoot}>
<Icon name="filter" />
<DropdownButton
label={labelButton ? labelButton(filters) : defaultButtonLabel(filters)}
/>
</span>
}
width={200}
multiselect
style={{ width: 200 }}
{...rest}
/>
>
{listItems.map(item => (
<Option value={item} key={item} />
))}
</Dropdown>
);
}
16 changes: 0 additions & 16 deletions packages/components/src/FilterToolbar/FilterDropdown/styles.css.ts

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,7 @@ test('updates the toolbar filters state when Filter 2 is selected', async () =>
// arrange
const { getByTestId } = render(
<ToolbarProvider onStateChange={handleStateChangeMock}>
<FilterSearch
InputProps={{ inputProps: { 'data-mosaic-testid': 'test-input' } }}
source={source}
/>
<FilterSearch inputProps={{ 'data-mosaic-testid': 'test-input' }} source={source} />
</ToolbarProvider>
);
// action
Expand Down
44 changes: 30 additions & 14 deletions packages/components/src/FilterToolbar/Search/index.tsx
Original file line number Diff line number Diff line change
@@ -1,33 +1,49 @@
import React from 'react';
import React, { ChangeEvent, SyntheticEvent, useState } from 'react';
import classnames from 'clsx';
import { escapeRegExp, ComboBox, ComboBoxProps, SelectionChangeHandler } from '@salt-ds/lab';
import { ComboBox, Option, ComboBoxProps } from '@salt-ds/core';
import { Icon } from '../../Icon';

import { useToolbarDispatch } from '../ToolbarProvider';
import styles from '../SortDropdown/styles.css';
import styles from './styles.css';

export interface FilterSearchProps extends ComboBoxProps<string, 'deselectable'> {}
const regExp = /[.*+?^${}()|[\]\\]/g;

function escapeRegExp(string: string): string {
return string.replace(regExp, '\\$&');
}

export interface FilterSearchProps extends ComboBoxProps {
source: string[];
}

export function FilterSearch({ className, source = [], ...rest }: FilterSearchProps) {
const dispatch = useToolbarDispatch();
const [value, setValue] = useState('');

// TODO convert to multiselect once Salt supports Multiselect from a ComboBox
const handleSelect: SelectionChangeHandler<string, 'deselectable'> = (_e, item) => {
const value = item === null ? [] : [item];
dispatch({ type: 'setFilters', value });
const handleSelect = (_e: SyntheticEvent, newSelected: string[]) => {
dispatch({ type: 'setFilters', value: newSelected });
};

const handleChange = (event: ChangeEvent<HTMLInputElement>) => {
setValue(event.target.value);
};
const getFilterRegex: (text: string) => RegExp = value =>
new RegExp(`\\b(${escapeRegExp(value)})`, 'gi');

return (
<ComboBox
InputProps={{ startAdornment: <Icon name="filter" /> }}
startAdornment={<Icon name="filter" />}
className={classnames(className, styles.root)}
getFilterRegex={getFilterRegex}
onSelectionChange={handleSelect}
source={source}
width={200}
value={value}
onChange={handleChange}
style={{ width: 200 }}
{...rest}
/>
>
{source
.filter(item => item.match(new RegExp(`\\b(${escapeRegExp(value)})`, 'gi')))
.map(item => (
<Option value={item} key={item} />
))}
</ComboBox>
);
}
38 changes: 18 additions & 20 deletions packages/components/src/FilterToolbar/SortDropdown/index.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
import React, { useState } from 'react';
import classnames from 'clsx';
import { Dropdown, DropdownButton, DropdownProps, SelectionChangeHandler } from '@salt-ds/lab';
import React, { SyntheticEvent, useState } from 'react';
import { Dropdown, Option, DropdownProps } from '@salt-ds/core';
import { Icon } from '../../Icon';
import styles from './styles.css';
import { useToolbarDispatch, useToolbarState } from '../ToolbarProvider';
import { itemToLabel as defaultItemToLabel, source as defaultSource } from './defaultSort';

type PartialDropdownProps = Omit<DropdownProps<string, 'default'>, 'source'>;
type PartialDropdownProps = DropdownProps;

export interface FilterSortDropdownProps extends PartialDropdownProps {
/** Callback to translate the selected list item to a Button label */
labelButton?: (selectedItem: string | undefined) => string;
/** Dropdown list source */
source?: string[];
itemToString?: DropdownProps['valueToString'];
}

export function FilterSortDropdown({
Expand All @@ -26,28 +25,27 @@ export function FilterSortDropdown({
const { sort = source[0] } = useToolbarState();
const [, setIsOpen] = useState(false);

const handleSelect: SelectionChangeHandler<string, 'default'> = (_e, selectedItem) => {
if (selectedItem) {
dispatch({ type: 'setSort', value: selectedItem });
const handleSelect = (_e: SyntheticEvent, selectedItem: string[]) => {
if (selectedItem[0]) {
dispatch({ type: 'setSort', value: selectedItem[0] });
}
};

return (
<Dropdown
className={classnames(className, styles.root)}
itemToString={itemToString}
startAdornment={<Icon name="swap" />}
className={className}
valueToString={itemToString}
value={labelButton ? labelButton(sort) : sort}
onOpenChange={setIsOpen}
onSelectionChange={handleSelect}
selected={sort}
source={source}
triggerComponent={
<span className={styles.triggerRoot}>
<Icon name="swap" />
<DropdownButton label={labelButton ? labelButton(sort) : sort} />
</span>
}
width={150}
selected={[sort]}
style={{ width: 150 }}
{...rest}
/>
>
{source.map(item => (
<Option value={item} key={item} />
))}
</Dropdown>
);
}
15 changes: 0 additions & 15 deletions packages/components/src/FilterToolbar/SortDropdown/styles.css.ts

This file was deleted.

Loading

0 comments on commit dcf72a3

Please sign in to comment.