-
Notifications
You must be signed in to change notification settings - Fork 5
Code Standards
Taylor Snead edited this page Aug 23, 2022
·
2 revisions
- Add comments to all top-level items describing what it is in more detail, why it's separate from other things, why it was written like it is, etc.
- You could also add a comment describing the whole file (e.g. Typescript, Rust). This can provide the scope of that file/module.
- If you are considering adding a new element of change to your PR, the answer is probably to make a separate PR.
- Code is formatted with
prettier - Encapsulate all code that deals with a
Contextin one file. Never export the context itself, only export a Provider component and one or more hooks exposing context data. - Use components defined in
website/src/componentswhenever possible- Otherwise use components from
reakitif there is one
- Otherwise use components from
- Add types wherever possible (objects, variables, function arguments, etc) and avoid the
anytype unless you really need it - Avoid the
asoperator for typecasting - Avoid unnecessary HTML elements. If you are nesting two or three
divelements without any siblings, then reconsider your approach. - Always supply an
aria-labelto non-text elements (like icons or icon buttons) - Use the relevant semantic HTML element instead of
divwhen possible - React components have
PascalCasenames, while other constants and functions getcamelCasenames - Use abbreviations in names sparingly -- most of the time the full name is easier for others to understand
- Avoid brand/library names in our own code. For example, prefer
graphqlClientoverapolloClientorurqlClient. - For React hooks, always check the dependency list to ensure that all other input state is accounted for.
const [x, setX] = useState(0)
useEffect(() => {
doSomething(x)
}, [x]) // <-- make sure x is here because it's used within the hook- Avoid exceptional returns in React components when possible because it can lead to mistakes with hooks.
// Do this!
if (condition) {
return null
} else {
return (...)
}
// ...instead of this
if (condition) {
return null
}
// ...
return (...)- Be mindful of how much rendering your hooks require the component to do.
- Use
useMemowhen creating expensive objects during render. - Use primary constants for the default value of
useStatebecause those values are recomputed every render. You can also douseState(() => initialValue)to provide a lazy initial state. - Combine multiple
useEffectcalls into one whenever possible
- Use
When creating a new React context to store global state, there are a few guidelines to consider.
- Put the context object in a new file and call it
XContextwhere X names the state, along with a provider componentXProviderand one or more hooks that allow components to consume/affect the state. - Never export
XContextitself, put all direct usage of it in the same file. - If the context interacts with an external system like cookies, local storage, or a 3rd party API then encapsulate as much direct usage of that system into the provider itself to avoid leaking implementation details.
- Styles are written in
.css.tsfiles then imported into.tsxfiles - All styles are mobile-first, with desktop styles applied based on media queries. For example:
const myStyle = style({
color: "blue", // blue on mobile
"@media": {
[mediaQueries.medium]: { color: "red" }, // red on tablets and smaller desktop screens
[mediaQueries.large]: { color: "maroon" }, // maroon on larger screens
}
})- Avoid
vwandvhunits, especially for desktop styles. Use fixed or percentage sizes instead. - Avoid magic numbers in styles, use values from
src/style/constantswhen possible. You can also add reusable constants if one is missing. For example, usevspacefor vertical spacing andhspacefor horizontal spacing instead of values like10px. - Never write pixel font sizes. Always use
remunits for that
- Code is formatted with
rustfmt/cargo fmt - Avoid using
.unwrap()onOption<T>because on failure it causes the program to crash instead of allowing us to handle the error
- Code is formatted with
sqlfluff fix types/queriesin the root folder - Always run
dev-generate-typesbefore committing SQL changes, and also commit the changes tosqlx-data.json - Table names are singular nouns, i.e.
word,document,edited_collection - Use all lowercase for everything, including keywords like
select,where,join, etc. - Always specify the type of join you're using. e.g.
inner joininstead of shortcutjoin - When you use a join, fully specify all column selections by table name. For example, if I use a join to access both
documentandwordtables, never use plainindex_in_documentto refer to that column. Useword.index_in_documentinstead, even when there isn't a name conflict between the tables. - Use standard SQL by default and when possible, but dip into Postgres extensions when convenient
- Never ever edit database migrations that are already merged to main and applied on live deployments. We always have to make new migration files for new changes, because postgres skips completed migrations based on the file name and our migration process will fail if an existing migration is edited
- Almost always use an
autouuidfor primary keys. This is a "surrogate" key when we might also have a "natural" key in a separate unique column.
id autouuid primary key,
slug text unique,- CARE Principles
- Collective Decision-Making Process
- Data Resilience
- Culturally-Sensitive Information
- UX Design
- Metadata
- User Contributed Audio
- Audio Data Process
- Manuscript Annotation and Analysis
- Language Specific Limitations
- Annotation and Analysis (Before 2024)
- Code Standards
- AWS Diagnostics and Triage Guide
- Cloud Architecture
- Development Environments
- Data Representation
- Data Migration
- User Groups and Roles
- Wordpress Content
- Web Design & Accessibility