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

Apps SDK V2 and i18n #40

Merged
merged 1 commit into from
Sep 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
.idea
.vscode
.ssl
node_modules
.DS_Store
.pr-train.yml
yarn-error.log
dist
secrets.json
Expand Down
6 changes: 6 additions & 0 deletions .vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
// For developers using vscode we recommend the following extensions. Following
// and listening to the formatting and linting guidelines can help with
// implementation quality and in some instances reduce app review timelines.
"recommendations": ["esbenp.prettier-vscode", "dbaeumer.vscode-eslint"]
}
51 changes: 51 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,48 @@
# Changelog

## 2024-09-25

### 🔨 Breaking changes

- Upgraded Apps SDK dependencies to v2.0.0 (design 2.1.0)

### 🧰 Added

- Updated the starter kit with internationalization tooling including `react-intl` and `formatjs`.
See the docs on the [Canva app localization process](https://www.canva.dev/docs/apps/localization/) to learn more.
- Added [/examples/i18n](/examples/i18n) to demonstrate how to internationalize your app using `react-intl`
- Added [/examples/i18n/tests](/examples/i18n/tests) to demonstrate how to unit test an app using localization
- Added `.vscode` recommended extensions, helps to enforce eslint rules more uniformly by default.
- Added `.pr-train.yml` to `.gitignore`
- Added `use_feature_support` utils.
- Added [/examples/feature_support](/examples/feature_support) to demonstrate usage of the Feature Support API.
- Added `use_add_element` hook utils
- `@canva/design@beta`
- Added `openDesign` method, which allows apps to read the current page of the user's design. To learn more, see [Design Editing](https://canva.dev/docs/apps/traversal).
- Added a new example [/examples/design_editing](/examples/design_editing) to demonstrate how to use the Design Editing API.

### 🔧 Changed

- Added `alt` attributes where they were missing from `ImageCard` usage in examples.
- `examples`
- Update `dnd` example apps to use feature supports to ensure they work correctly in different design types.
- Change TableWrapper and `native_table_element` example to work with new Table API.
- Updated @canva/asset examples to be compatible with 2.0.
- Update relevant example apps to:
- use new lowercase element type as part of upgraded `@canva/design` to version `2.0.0`.
- use `altText`
- use `use_add_element` hook to ensure they work correctly in different design types.
- Drop all `native_*` prefix from example apps' name.
- `@canva/app-ui-kit`
- Upgraded `app-ui-kit` to version `4.0.0`. Please see the [changelog](https://www.canva.dev/docs/apps/app-ui-kit/changelog/) for the list of changes.
- Upgraded `express` to `4.21.0`.
- Update manual authentication example to use OAuth
- Temporarily downgraded `eslint` to version `8.57.0` while formatjs lint rules are updated to be made compatible with v9.

### 🗑️ Removed

- Removed authentication from `examples/digital_asset_management` pending migration to `auth.requestAuthorization`.

## 2024-08-27

### 🔨 Breaking changes
Expand Down Expand Up @@ -31,6 +74,7 @@
- Upgraded `app-ui-kit` to version `3.8.0`. Please see the [changelog](https://www.canva.dev/docs/apps/app-ui-kit/changelog/) for the list of changes.
- Updated the `typescript` package to version `5.5.4` and adjusted tsconfig to suit. [See the release notes](https://devblogs.microsoft.com/typescript/announcing-typescript-5-5/).
- Dependencies audit, upgrading all modules where possible and locking versions to ensure future stability:

```text
@eslint/js ^9.6.0 → 9.9.0
@ngrok/ngrok ^1.1.0 → 1.4.1
Expand Down Expand Up @@ -77,6 +121,7 @@
webpack-dev-server ^4.10.0 → 5.0.4
yargs ^17.5.1 → 17.7.2
```

- Migrating eslint config to the new `9.9.0` flat config format, after doing so additional lint rule disabling was needed in a few places.
- Moved `utils/table_wrapper.ts` closer to example referencing it, given it's still in preview.
- Dependencies audit to all workspaces/examples, upgrading all modules where possible and locking versions to ensure future stability:
Expand Down Expand Up @@ -106,11 +151,15 @@
### 🗑️ Removed

- `@canva/preview`:

- Removed `/sdk/preview`, as all of our preview SDKs are now published to NPM with an `@beta` tag. e.g. to install the preview `@canva/design` SDK, run the following command

```
npm install @canva/design@beta
```

- Note that not every SDK is guaranteed to have a preview version released.

- `@canva/preview/data`:
- The Preview Data APIs have been removed, and are no longer available as a preview SDK.
- The `data_provider_basic` and `data_provider_options` examples have also been removed.
Expand Down Expand Up @@ -508,7 +557,9 @@
- [@canva/user](https://www.npmjs.com/package/@canva/user)
- Dependencies in [package.json](./package.json) were changed to use the NPM registry accordingly.
- Updated node version in [.nvmrc](.nvmrc) to LTS version of [v20.10.0](https://nodejs.org/en/blog/release/v20.10.0)

- Run the below command at the repo root to upgrade via [nvm](https://github.com/nvm-sh/nvm#intro)

```
nvm install
```
Expand Down
Binary file added assets/images/sparkle.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
277 changes: 277 additions & 0 deletions conf/eslint-general.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,277 @@
import typescriptEslint from "@typescript-eslint/eslint-plugin";
import jest from "eslint-plugin-jest";
import react from "eslint-plugin-react";
import globals from "globals";

export default [
{
plugins: {
"@typescript-eslint": typescriptEslint,
jest,
react,
},
languageOptions: {
globals: {
...globals.serviceworker,
...globals.browser,
},
},
settings: {
react: {
version: "detect",
},
},
rules: {
"@typescript-eslint/no-non-null-assertion": "warn",
"@typescript-eslint/no-empty-function": "off",
"@typescript-eslint/consistent-type-imports": "error",
"@typescript-eslint/no-explicit-any": "warn",
"@typescript-eslint/no-empty-interface": "warn",
"@typescript-eslint/consistent-type-definitions": "off",
"@typescript-eslint/explicit-member-accessibility": [
"error",
{
accessibility: "no-public",
overrides: {
parameterProperties: "off",
},
},
],
"@typescript-eslint/naming-convention": [
"error",
{
selector: "typeLike",
format: ["PascalCase"],
leadingUnderscore: "allow",
},
],
"no-invalid-this": "off",
"@typescript-eslint/no-invalid-this": "error",
"@typescript-eslint/no-unused-expressions": [
"error",
{
allowShortCircuit: true,
allowTernary: true,
},
],
"no-unused-vars": "off",
"@typescript-eslint/no-unused-vars": [
"error",
{
vars: "all",
varsIgnorePattern: "^_",
args: "none",
ignoreRestSiblings: true,
},
],
"@typescript-eslint/no-require-imports": "error",
"jest/no-restricted-matchers": [
"error",
{
toContainElement:
"toContainElement is not recommended as it encourages testing the internals of the components",
toContainHTML:
"toContainHTML is not recommended as it encourages testing the internals of the components",
toHaveAttribute:
"toHaveAttribute is not recommended as it encourages testing the internals of the components",
toHaveClass:
"toHaveClass is not recommended as it encourages testing the internals of the components",
toHaveStyle:
"toHaveStyle is not recommended as it encourages testing the internals of the components",
},
],
"react/jsx-curly-brace-presence": [
"error",
{
props: "never",
children: "never",
},
],
"react/jsx-tag-spacing": [
"error",
{
closingSlash: "never",
beforeSelfClosing: "allow",
afterOpening: "never",
beforeClosing: "allow",
},
],
"react/self-closing-comp": "error",
"react/no-unescaped-entities": "off",
"react/jsx-uses-react": "off",
"react/react-in-jsx-scope": "off",
"default-case": "error",
eqeqeq: [
"error",
"always",
{
null: "never",
},
],
"no-caller": "error",
"no-console": "error",
"no-eval": "error",
"no-inner-declarations": "error",
"no-new-wrappers": "error",
"no-restricted-globals": [
"error",
{
name: "fit",
message: "Don't focus tests",
},
{
name: "fdescribe",
message: "Don't focus tests",
},
{
name: "length",
message:
"Undefined length - Did you mean to use window.length instead?",
},
{
name: "name",
message: "Undefined name - Did you mean to use window.name instead?",
},
{
name: "status",
message:
"Undefined status - Did you mean to use window.status instead?",
},
{
name: "spyOn",
message: "Don't use spyOn directly, use jest.spyOn",
},
],
"no-restricted-properties": [
"error",
{
property: "bind",
message: "Don't o.f.bind(o, ...), use () => o.f(...)",
},
{
object: "ReactDOM",
property: "findDOMNode",
message: "Don't use ReactDOM.findDOMNode() as it is deprecated",
},
],
"no-restricted-syntax": [
"error",
{
selector: "AccessorProperty, TSAbstractAccessorProperty",
message:
"Accessor property syntax is not allowed, use getter and setters.",
},
{
selector: "PrivateIdentifier",
message:
"Private identifiers are not allowed, use TypeScript private fields.",
},
{
selector:
"JSXOpeningElement[name.name = /^[A-Z]/] > JSXAttribute[name.name = /-/]",
message:
"Passing hyphenated props to custom components is not type-safe. Prefer a camelCased equivalent if available. (See https://github.com/microsoft/TypeScript/issues/55182)",
},
{
selector:
"CallExpression[callee.object.name='window'][callee.property.name='open']",
message:
"Apps are currently not allowed to open popups, or new tabs via browser APIs. Please use `requestOpenExternalUrl` from `@canva/platform` to link to external URLs. To learn more, see https://www.canva.dev/docs/apps/api/platform-request-open-external-url/",
},
],
"no-return-await": "error",
"no-throw-literal": "error",
"no-undef-init": "error",
"no-var": "error",
"object-shorthand": "error",
"prefer-const": [
"error",
{
destructuring: "all",
},
],
"prefer-object-spread": "error",
"prefer-rest-params": "error",
"prefer-spread": "error",
radix: "error",
},
},
{
files: ["**/*.tsx"],
rules: {
"react/no-deprecated": "error",
"react/forbid-elements": [
"error",
{
forbid: [
{
element: "video",
message:
"Don't use HTML video directly. Instead, use the App UI Kit <VideoCard /> as this respects users' auto-playing preferences",
},
{
element: "em",
message:
"Don't use <em> to italicize text. Canva's UI fonts don't support italic font style.",
},
{
element: "i",
message:
"Don't use <i> to italicize text. Canva's UI fonts don't support italic font style.",
},
{
element: "iframe",
message:
"Canva Apps aren't allowed to contain iframes. You should either recreate the UI you want to show in the iframe in the app directly, or link to your page via a `<Link>` tag. For more info see https://www.canva.dev/docs/apps/content-security-policy/#what-is-and-isnt-allowed",
},
{
element: "script",
message:
"Script tags are not allowed in Canva SDK Apps. You should import JavaScript modules instead. For more info see https://www.canva.dev/docs/apps/content-security-policy/#what-is-and-isnt-allowed",
},
{
element: "a",
message:
"Don't use <a> tags. Instead, use the <Link> component from the App UI Kit, and remember to open the url via the requestOpenExternalUrl method from @canva/platform.",
},
{
element: "img",
message:
"Have you considered using <ImageCard /> from the App UI Kit instead?",
},
{
element: "embed",
message:
"Have you considered using <EmbedCard /> from the App UI Kit instead?",
},
{
element: "audio",
message:
"Have you considered using <AudioCard /> from the App UI Kit instead?",
},
{
element: "button",
message:
"Rather than using the native HTML <button> element, use the <Button> component from the App UI Kit for consistency and accessibility.",
},
{
element: "input",
message:
"Wherever possible, prefer using the form inputs from the App UI Kit for consistency and accessibility (TextInput, Checkbox, FileInput, etc).",
},
{
element: "base",
message:
"The <base> tag is not supported in Canva Apps. We recommend using hash-based routing. For more on what is and isn't allowed in Canva Apps see https://www.canva.dev/docs/apps/content-security-policy/#what-is-and-isnt-allowed",
},
{
element: "link",
message:
"If you're trying to include a css stylesheet, we recommend importing css using React, or using embedded stylesheets. For more on what is and isn't allowed in Canva Apps see https://www.canva.dev/docs/apps/content-security-policy/#what-is-and-isnt-allowed",
},
],
},
],
},
},
];
Loading
Loading