Skip to content

Commit

Permalink
init
Browse files Browse the repository at this point in the history
  • Loading branch information
caprolactam committed Feb 9, 2024
0 parents commit 1491b9d
Show file tree
Hide file tree
Showing 22 changed files with 19,376 additions and 0 deletions.
44 changes: 44 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
{
"root": true,
"env": {
"browser": true,
"node": true
},
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": 2022,
"sourceType": "module",
"ecmaFeatures": {
"jsx": true
}
},
"extends": [
"plugin:@typescript-eslint/recommended",
"plugin:react/recommended",
"plugin:react-hooks/recommended",
"plugin:jsx-a11y/recommended",
"prettier"
],
"settings": {
"react": {
"version": "detect"
}
},
"rules": {
"@typescript-eslint/no-explicit-any": "off"
},
"overrides": [
{
"files": ["*.stories.tsx"],
"rules": {
"react-hooks/rules-of-hooks": "off"
}
},
{
"files": ["*.test.{ts,tsx}"],
"rules": {
"react/react-in-jsx-scope": "off"
}
}
]
}
45 changes: 45 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
name: tests

on:
pull_request:
push:
branches:
- main

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
unit:
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@v4
- name: Setup node
uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
- run: npm ci
- run: npm run tsc
- run: npm run lint
- name: Run unit tests
run: npm run test
- run: npm run build
e2e:
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@v4
- name: Setup node
uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
- run: npm ci
- run: npx playwright install --with-deps
- name: Run storybook tests
run: npm run storybook:test
- name: Run playwright tests
run: npm run e2e
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
coverage
node_modules
dist
/test-results/
.vscode
TODO.md
4 changes: 4 additions & 0 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

npx lint-staged
1 change: 1 addition & 0 deletions .npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
legacy-peer-deps=true
1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/dist
25 changes: 25 additions & 0 deletions .prettierrc.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/** @type {import("prettier").Options} */
export default {
arrowParens: 'avoid',
bracketSameLine: false,
bracketSpacing: true,
endOfLine: 'lf',
jsxSingleQuote: true,
singleQuote: true,
printWidth: 80,
proseWrap: 'always',
quoteProps: 'as-needed',
semi: false,
singleAttributePerLine: true,
tabWidth: 2,
trailingComma: 'all',
useTabs: false,
overrides: [
{
files: ['**/*.json'],
options: {
useTabs: false,
},
},
],
}
9 changes: 9 additions & 0 deletions .storybook/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/** @type { import('@storybook/react-vite').StorybookConfig } */
export default {
stories: ['../stories/**/*.stories.@(js|jsx|ts|tsx)'],
addons: ['@storybook/addon-storysource'],
framework: {
name: '@storybook/react-vite',
options: {},
},
}
21 changes: 21 additions & 0 deletions .storybook/preview.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import './style.css'
// for e2e
if (import.meta.env.STORYBOOK_E2E) {
const style = document.createElement('style')
// elements with `pointer-events: none` can't be found by document.elementFromPoint()
style.appendChild(
document.createTextNode(
`* {
pointer-events: auto !important;
}`,
),
)
document.head.appendChild(style)
}

/** @type { import('@storybook/react').Preview } */
export default {
parameters: {
actions: { argTypesRegex: '^on[A-Z].*' },
},
}
126 changes: 126 additions & 0 deletions .storybook/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
body {
background: #fafafa;
font-family: Helvetica, Arial, sans-serif;
}

#side-panel {
box-sizing: border-box;
display: inline-block;
padding-left: 1.5em;
vertical-align: top;
width: 29%;
}

#delay-time-select {
display: block;
margin-top: 5px;
width: 10em;
}

#main-content {
display: inline-block;
vertical-align: top;
min-width: 250px;
width: 70%;
}

#restaurant-feed {
max-width: 100%;
width: 500px;
}

@media screen and (max-width: 560px) {
#main-content {
width: 100%;
}
}

.restaurant-item {
background: white;
box-shadow: 1px 1px 6px #bbb;
margin-bottom: 15px;
padding-top: 15px;
}

.restaurant-details {
display: inline-block;
margin-bottom: 10px;
padding-left: 15px;
vertical-align: top;
width: 55%;
}

.restaurant-name {
font-size: 18px;
margin-bottom: 2px;
}

.restaurant-star-img {
width: 90px;
}

.restaurant-type {
color: #777;
font-size: 13px;
}

.location-block {
color: #777;
display: inline-block;
vertical-align: top;
margin: 0 15px 10px;
font-size: 14px;
line-height: 1.3em;
}

.restaurant-actions {
box-sizing: border-box;
background: #a2afbc;
padding: 10px;
width: 100%;
}

.restaurant-rating svg g {
color: #ffde00;
}

.restaurant-rating svg .star {
stroke-width: 2px;
stroke: #f8951d;
fill-opacity: 0;
}

.restaurant-rating[data-rating-value='1'] svg .star-1 .star {
fill: currentcolor;
fill-opacity: 1;
}

.restaurant-rating[data-rating-value='2'] svg .star-2 .star {
fill: currentcolor;
fill-opacity: 1;
}

.restaurant-rating[data-rating-value='3'] svg .star-3 .star {
fill: currentcolor;
fill-opacity: 1;
}

.restaurant-rating[data-rating-value='4'] svg .star-4 .star {
fill: currentcolor;
fill-opacity: 1;
}

.restaurant-rating[data-rating-value='5'] svg .star-5 .star {
fill: currentcolor;
fill-opacity: 1;
}

@media (forced-colors: active) {
.restaurant-rating svg g {
color: currentcolor;
}

.restaurant-rating svg .star {
stroke: currentcolor;
}
}
80 changes: 80 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# feed-a11y

headless and accessible feed component for React.

**Features**

- Keyboard navigation
[Interaction](https://www.w3.org/WAI/ARIA/apg/patterns/feed#keyboardinteraction).
- ARIA roles and states
[link](https://www.w3.org/WAI/ARIA/apg/patterns/feed#wai-ariaroles,states,andproperties).

## Install

```sh
npm install feed-a11y
```

## Usage

```tsx
import * as Feed from 'feed-a11y'

export default () => (
<Feed.Root>
<Feed.RootTitle />
<Feed.Item>
<Feed.ItemTitle />
</Feed.Item>
</Feed.Root>
)
```

## API

### Root

| Prop | Type | Default | Description |
| ------- | ------- | ------- | ---------------------------------------------------------------------------------------------------- |
| loading | boolean | - | To convey the loading state to users using assistive technologies. |
| asChild | boolean | false | Change the default rendered element for the one passed as a child, merging their props and behavior. |

### RootTitle

| Prop | Type | Default | Description |
| ------- | ------- | ------- | ---------------------------------------------------------------------------------------------------- |
| asChild | boolean | false | Change the default rendered element for the one passed as a child, merging their props and behavior. |

### Item

| Prop | Type | Default | Description |
| ------- | ------- | ------- | ---------------------------------------------------------------------------------------------------- |
| asChild | boolean | false | Change the default rendered element for the one passed as a child, merging their props and behavior. |

### ItemTitle

| Prop | Type | Default | Description |
| ------- | ------- | ------- | ---------------------------------------------------------------------------------------------------- |
| asChild | boolean | false | Change the default rendered element for the one passed as a child, merging their props and behavior. |

## Accessibility

### Keyboard Interactions

| Key | Description |
| -------------- | ---------------------------------------------------------- |
| Page Up | Move focus to previous article. |
| Page Down | Move focus to next article. |
| Control + Home | Move focus to the first focusable element before the feed. |
| Control + End | Move focus to the first focusable element after the feed. |

## FAQs

**React version?** Requires React 18, because using `useId` internally.

**Combination with virtualization?** Not supported, because it's not possible to
manage focus properly.

## Contribute

If you have issues or questions, feel free to create an issue or pull request.
Loading

0 comments on commit 1491b9d

Please sign in to comment.