Skip to content

Commit

Permalink
Tweaks to API
Browse files Browse the repository at this point in the history
  • Loading branch information
gethinwebster committed Oct 16, 2024
1 parent d726b37 commit 6700440
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 31 deletions.
10 changes: 9 additions & 1 deletion pages/alert/runtime-content.page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,15 @@ awsuiPlugins.alertContent.registerContentReplacer({
};
},
initialCheck(context) {
return context.type === 'error' && !!context.contentText?.match('Access denied');
return (
context.type === 'error' &&
!!(
context.content &&
typeof context.content === 'object' &&
'props' in context.content &&
context.content.props.children?.match('Access denied')
)
);
},
});

Expand Down
33 changes: 31 additions & 2 deletions pages/flashbar/runtime-content.page.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

import React, { useContext, useState } from 'react';
import React, { ReactNode, useContext, useState } from 'react';
import { render, unmountComponentAtNode } from 'react-dom';
import flattenChildren from 'react-keyed-flatten-children';

import {
Box,
Expand All @@ -24,6 +25,12 @@ type PageContext = React.Context<
AppContextType<{ loading: boolean; hidden: boolean; stackItems: boolean; type: FlashbarProps.Type }>
>;

const nodeAsString = (node: ReactNode) =>
flattenChildren(node)
.map(node => (typeof node === 'object' ? node.props.children : node))
.filter(node => typeof node === 'string')
.join('');

awsuiPlugins.flashContent.registerContentReplacer({
id: 'awsui/flashbar-test-action',
runReplacer(context, replacer) {
Expand Down Expand Up @@ -62,10 +69,32 @@ awsuiPlugins.flashContent.registerContentReplacer({
},
};
},
initialCheck(context) {
return context.type === 'error' && !!nodeAsString(context.content).match('Access denied');
},
});

const messageTypeOptions = ['error', 'warning', 'info', 'success'].map(type => ({ value: type }));

const content = (
<>
<p>There was an error: Access denied because of XYZ</p>
<p>There was an error: Access denied because of XYZ</p>
<p>There was an error: Access denied because of XYZ</p>
<p>There was an error: Access denied because of XYZ</p>
<p>There was an error: Access denied because of XYZ</p>
<p>There was an error: Access denied because of XYZ</p>
<p>There was an error: Access denied because of XYZ</p>
<p>There was an error: Access denied because of XYZ</p>
<p>There was an error: Access denied because of XYZ</p>
<p>There was an error: Access denied because of XYZ</p>
<p>There was an error: Access denied because of XYZ</p>
<p>There was an error: Access denied because of XYZ</p>
<p>There was an error: Access denied because of XYZ</p>
<p>There was an error: Access denied because of XYZ</p>
</>
);

export default function () {
const {
urlParams: { loading = false, hidden = false, stackItems = false, type = 'error' },
Expand Down Expand Up @@ -117,7 +146,7 @@ export default function () {
type,
statusIconAriaLabel: type,
header: 'Header',
content: loading ? 'Loading...' : 'There was an error: Access denied because of XYZ',
content: loading ? 'Loading...' : content,
action: <Button>Action</Button>,
},
]}
Expand Down
7 changes: 2 additions & 5 deletions src/alert/styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,8 @@
}
// visibly hidden, but focusable
.initial-hidden {
// TODO: decide if it should take up space:
opacity: 0;
// or be entirely hidden:
// overflow: hidden;
// height: 0;
overflow: hidden;
block-size: 0;
}

.header,
Expand Down
4 changes: 3 additions & 1 deletion src/flashbar/flash.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ export const Flash = React.forwardRef(
const contentRefObject = useRef<HTMLDivElement>(null);
const { discoveredActions, headerRef: headerRefAction, contentRef: contentRefAction } = useDiscoveredAction(type);
const {
initialHidden,
headerReplacementType,
contentReplacementType,
headerRef: headerRefContent,
Expand Down Expand Up @@ -174,7 +175,8 @@ export const Flash = React.forwardRef(
[styles.exiting]: transitionState === 'exiting',
[styles.exited]: transitionState === 'exited',
},
getVisualContextClassname(type === 'warning' && !loading ? 'flashbar-warning' : 'flashbar')
getVisualContextClassname(type === 'warning' && !loading ? 'flashbar-warning' : 'flashbar'),
initialHidden && styles['initial-hidden']
)}
{...analyticsAttributes}
>
Expand Down
5 changes: 5 additions & 0 deletions src/flashbar/styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@
}
}

.initial-hidden {
overflow: hidden;
block-size: 0;
}

.flash-list {
list-style: none;
padding-block: 0;
Expand Down
26 changes: 4 additions & 22 deletions src/internal/plugins/controllers/alert-flash-content.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// SPDX-License-Identifier: Apache-2.0

import { ReactNode } from 'react';
import flattenChildren from 'react-keyed-flatten-children';

import debounce from '../../debounce';

Expand All @@ -17,18 +16,12 @@ export interface AlertFlashContentContext {
contentRef: RefShim<HTMLElement>;
}

interface AlertFlashContentInitialContextRaw {
interface AlertFlashContentInitialContext {
type: string;
header?: ReactNode;
content?: ReactNode;
}

export interface AlertFlashContentInitialContext {
type: string;
headerText?: string;
contentText?: string;
}

export type ReplacementType = 'original' | 'remove' | 'replaced';

export interface ReplacementApi {
Expand Down Expand Up @@ -60,15 +53,9 @@ export interface AlertFlashContentApiPublic {
export interface AlertFlashContentApiInternal {
clearRegisteredReplacer(): void;
onContentRegistered(listener: AlertFlashContentRegistrationListener): () => void;
initialCheck(context: AlertFlashContentInitialContextRaw): boolean;
initialCheck(context: AlertFlashContentInitialContext): boolean;
}

const nodeAsString = (node: ReactNode) =>
flattenChildren(node)
.map(node => (typeof node === 'object' ? node.props.children : node))
.filter(node => typeof node === 'string')
.join('');

export class AlertFlashContentController {
#listeners: Array<AlertFlashContentRegistrationListener> = [];
#cleanups = new Map<AlertFlashContentRegistrationListener, () => void>();
Expand Down Expand Up @@ -102,14 +89,9 @@ export class AlertFlashContentController {
this.#provider = undefined;
};

initialCheck = (context: AlertFlashContentInitialContextRaw): boolean => {
initialCheck = (context: AlertFlashContentInitialContext): boolean => {
if (this.#provider?.initialCheck) {
const processedContext: AlertFlashContentInitialContext = {
type: context.type,
headerText: nodeAsString(context.header),
contentText: nodeAsString(context.content),
};
return this.#provider.initialCheck(processedContext);
return this.#provider.initialCheck(context);

Check warning on line 94 in src/internal/plugins/controllers/alert-flash-content.ts

View check run for this annotation

Codecov / codecov/patch

src/internal/plugins/controllers/alert-flash-content.ts#L94

Added line #L94 was not covered by tests
}
return false;
};
Expand Down

0 comments on commit 6700440

Please sign in to comment.