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

Announcer: Part 1 #2362

Open
wants to merge 22 commits into
base: announcer
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
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
5 changes: 5 additions & 0 deletions .changeset/thirty-ducks-type.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@khanacademy/wonder-blocks-announcer": minor
---

New package for WB Announcer
121 changes: 121 additions & 0 deletions __docs__/wonder-blocks-announcer/announcer.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
import * as React from "react";
import {StyleSheet} from "aphrodite";
import type {Meta, StoryObj} from "@storybook/react";

import {
announceMessage,
type AnnounceMessageProps,
} from "@khanacademy/wonder-blocks-announcer";
import Button from "@khanacademy/wonder-blocks-button";
import {View} from "@khanacademy/wonder-blocks-core";

import ComponentInfo from "../../.storybook/components/component-info";
import packageConfig from "../../packages/wonder-blocks-announcer/package.json";

const AnnouncerExample = ({
message = "Clicked!",
level,
removalDelay,
}: AnnounceMessageProps) => {
return (
<Button
onClick={() => {
// TODO: explore making method async for consistent return string
announceMessage({message, level, removalDelay});
}}
>
Save
</Button>
);
};
type StoryComponentType = StoryObj<typeof AnnouncerExample>;

/**
* Announcer exposes an API for screen reader messages using ARIA Live Regions.
* It can be used to notify Assistive Technology users without moving focus. Use
* cases include combobox filtering, toast notifications, client-side routing,
* and more.
*
* Calling the sendMessage method automatically prepends the appropriate live regions
* to the document body. It sends messages at a default `polite` level, with the
* ability to override to `assertive` by passing a `level` argument. You can also
* pass a `timeoutDelay` to wait a specific duration before sending a message.
*
* To test this API, turn on VoiceOver or NVDA on Windows and click the example button.
*
* ### Usage
* ```jsx
* import { sendMessage } from "@khanacademy/wonder-blocks-announcer";
*
* <div>
* <button onClick={() => sendMessage({message: 'Saved your work for you.'})}>
* Save
* </button>
* </div>
* ```
*/
export default {
title: "Packages / Announcer",
component: AnnouncerExample,
decorators: [
(Story): React.ReactElement<React.ComponentProps<typeof View>> => (
<View style={styles.example}>
marcysutton marked this conversation as resolved.
Show resolved Hide resolved
<Story />
</View>
),
],
parameters: {
componentSubtitle: (
<ComponentInfo
name={packageConfig.name}
version={packageConfig.version}
/>
),
docs: {
source: {
// See https://github.com/storybookjs/storybook/issues/12596
excludeDecorators: true,
},
},
},
argTypes: {
level: {
control: "radio",
options: ["polite", "assertive"],
defaultValue: "polite",
},
timeoutDelay: {
control: "number",
type: "number",
description: "(milliseconds)",
Copy link
Member

Choose a reason for hiding this comment

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

I'm wondering if there's a way for us to use the function docs for the storybook docs! Normally we're able to get the prop docs automatically from setting component in this block, though this is different since these docs are for functions rather than components!

cc: @jandrade in case you have come across similar things before!

},
},
} as Meta<typeof AnnouncerExample>;

/**
* This is an example of a live region with all the options set to their default
* values and the `message` argument set to some example text.
*/
export const SendMessage: StoryComponentType = {
args: {
message: "Here is some example text.",
level: "polite",
},
};

const styles = StyleSheet.create({
example: {
alignItems: "center",
justifyContent: "center",
},
container: {
width: "100%",
},
narrowBanner: {
maxWidth: 400,
},
rightToLeft: {
width: "100%",
direction: "rtl",
},
marcysutton marked this conversation as resolved.
Show resolved Hide resolved
});
28 changes: 28 additions & 0 deletions packages/wonder-blocks-announcer/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"name": "@khanacademy/wonder-blocks-announcer",
"version": "0.0.1",
"design": "v1",
"description": "Live Region Announcer for Wonder Blocks.",
"main": "dist/index.js",
"module": "dist/es/index.js",
"source": "src/index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"types": "dist/index.d.ts",
"author": "",
"license": "MIT",
"publishConfig": {
"access": "public"
},
"dependencies": {
"@khanacademy/wonder-blocks-core": "^7.0.1"
},
"peerDependencies": {
"aphrodite": "^1.2.5",
"react": "16.14.0"
},
"devDependencies": {
"@khanacademy/wb-dev-build-settings": "^1.0.1"
}
}
Loading