Skip to content
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
12 changes: 6 additions & 6 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ You can help most by:
- Adding ideas for components by [creating a New Component issue](https://github.com/Esri/calcite-design-system/issues/new?assignees=&labels=new+component%2C0+-+new%2Cneeds+triage&template=new-component.yml).
- Working on [the issues marked as `help wanted`](https://github.com/Esri/calcite-design-system/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22+no%3Aassignee). There is also a [`good first issue`](https://github.com/Esri/calcite-design-system/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22+no%3Aassignee+) label if you are just getting started.
- To let us know of your interest in the issue, please comment on the issue and ask for the action items before you start working. Sometimes additional context is needed, which may not be specified in the issue. Comments also provide us access to assign the issue to you.
- If you want to help develop components take a look at the [new component issues](https://github.com/Esri/calcite-design-system/issues?q=is%3Aopen+is%3Aissue+label%3A%22new+component%22). Before starting development please review our [component conventions](./conventions/README.md) and the [Stencil documentation](https://stenciljs.com/docs/introduction).
- If you want to help develop components take a look at the [new component issues](https://github.com/Esri/calcite-design-system/issues?q=is%3Aopen+is%3Aissue+label%3A%22new+component%22). Before starting development please review our [component conventions](./conventions/README.md) and the [Lit documentation](https://lit.dev/docs/getting-started/).

If you aren't familiar with the basics of Web Components and Shadow DOM, please read through some of the following resources before contributing:

Expand Down Expand Up @@ -61,7 +61,7 @@ There are four labels that mean an issue is not ready for development:
- `design`: Issues that need design consultation, such as interaction research/feedback, visual mockups, and general approval. Once design completes their review, an additional label, `ready for dev` will be added to the issue, which means a developer can pick up the issue.
- `spike`: Issues that need to research a question or resolve a complex task with uncertain outcomes. Once the spike has been performed a `spike complete` label is added to the issue, which means a developer can pick up the issue.
- `need more info`: Issues that are missing information and/or a clear, actionable description. This can mean we are waiting on a user to provide additional context, we can't reproduce the issue, or further discussion is needed in order to determine a solution.
- `blocked`: Issues that cannot be worked on until a different issue is resolved. The blocking issue may be from an external library (Stencil, Storybook, Jest, etc.) or a Calcite Components issue. In the body or comments of a blocked issue, include a link to the blocking issue. To track when an issue is unblocked, add a comment in the blocking issue's body referencing the blocked issue(s). Use the following format for the comment: "Blocked issues: #0000, #0000". List multiple blocked issues by separating them with commas.
- `blocked`: Issues that cannot be worked on until a different issue is resolved. The blocking issue may be from an external library (Lit, Storybook, Jest, etc.) or a Calcite Components issue. In the body or comments of a blocked issue, include a link to the blocking issue. To track when an issue is unblocked, add a comment in the blocking issue's body referencing the blocked issue(s). Use the following format for the comment: "Blocked issues: #0000, #0000". List multiple blocked issues by separating them with commas.

### Milestones

Expand Down Expand Up @@ -129,7 +129,7 @@ cd calcite-design-system
npm install
```

Next, start the local Stencil development server on localhost:
Next, start the local Vite development server on localhost:

```sh
npm run start:components
Expand Down Expand Up @@ -164,19 +164,19 @@ npm test

`npm test` will run the test suites.

Calcite Components include Stencil's default testing tools which are built on [Jest](https://jestjs.io/) and [Puppeteer](https://github.com/GoogleChrome/puppeteer).
Calcite Components include Vitest's testing tools which are powered by [Vitest](https://vitest.dev) and [Puppeteer](https://github.com/GoogleChrome/puppeteer).

If you're working on writing tests for a particular component, it can be helpful to use `npm --workspace=packages/calcite-components run test:watch` to retest on file changes. Once the initial tests run, typing `o` at the prompt will run tests only on changed files, allowing you to quickly iterate on tests for a specific component. You can also add a pattern to the end of the command to match for a test's file path.

Please refer to the [Stencil testing documentation](https://stenciljs.com/docs/testing-overview) and Calcite's [testing conventions](./conventions/Testing.md) for more information.
Please refer to Calcite's [testing conventions](./conventions/Testing.md) for more information.

## Adding a new component

Before adding a new component, please read through the [component conventions guide](./conventions/README.md). This guide covers everything from colors to event naming syntax and will help you create a component that is consistent with those that already exist. All new components should have an [issue](https://github.com/Esri/calcite-design-system/issues/new?assignees=&labels=new+component%2C+0+-+new%2C+architecture&template=new-component.md&title=New+Component%3A+).

## Documenting a component

Stencil creates API reference documentation using JSDoc, here is their [documentation page](https://stenciljs.com/docs/docs-json). Calcite Components utilizes [Storybook](https://storybook.js.org/) for documenting components. Adding a new component is very simple:
Calcite Components utilizes [JSDoc](https://jsdoc.app/about-getting-started) to create API reference documentation and [Storybook](https://storybook.js.org/) for documenting components. Adding a new component is very simple:

1. Create a new file inside your component directory like `X.stories.js`
2. Write stories
Expand Down
2 changes: 1 addition & 1 deletion examples/components/react/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ This package includes the compatible version of the main component library as a

### Setup components

[Custom Elements](https://stenciljs.com/docs/custom-elements) is the recommended build when using frontend frameworks, such as React. First, import and call `setAssetPath`, which ensures translations, icons, and other required assets are available to Calcite components (more on copying assets below). You can either use local assets, which will be explained in a subsequent step, or assets hosted on a CDN. This example uses local assets.
By default, Calcite components use assets hosted on a CDN. If you are hosting assets locally, you can import and use `setAssetPath`. This ensures that translations, icons, and other required assets are available to Calcite components. (More on copying assets below.)

```ts
import { setAssetPath } from "@esri/calcite-components/dist/components";
Expand Down
2 changes: 1 addition & 1 deletion examples/components/webpack/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ import "@esri/calcite-components/dist/calcite/calcite.css";

### Configure Webpack

Calcite components need to be copied to your output directory so Stencil can load them from the client. The easiest way to do this is with [copy-webpack-plugin](https://webpack.js.org/plugins/copy-webpack-plugin/). First, install the package:
Calcite components need to be copied to your output directory so they can be loaded from the client. The easiest way to do this is with [copy-webpack-plugin](https://webpack.js.org/plugins/copy-webpack-plugin/). First, install the package:

```sh
npm install -D copy-webpack-plugin
Expand Down
6 changes: 3 additions & 3 deletions packages/calcite-components-react/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ There are two builds that are provided by the standard `calcite-components` pack

### Custom Elements build

[Custom Elements](https://stenciljs.com/docs/custom-elements) is the recommended build when using frontend frameworks, such as React. To use this build, you will need to set the path to the `calcite-components` assets. You can either use local assets, which will be explained in a subsequent step, or assets hosted on a CDN.
[Custom Elements](developers.arcgis.com/calcite-design-system/get-started#custom-elements) is the recommended build when using frontend frameworks, such as React. To use this build, you will need to set the path to the `calcite-components` assets. You can either use local assets, which will be explained in a subsequent step, or assets hosted on a CDN.

```jsx
import { setAssetPath } from "@esri/calcite-components/dist/components";
Expand All @@ -38,7 +38,7 @@ import { CalciteButton, CalciteIcon, CalciteSlider } from "@esri/calcite-compone

### Dist build

When using the [Dist](https://stenciljs.com/docs/distribution) build, you'll need to manually define the custom elements on the window. You can also choose between local and CDN hosted assets.
When using the [Dist](developers.arcgis.com/calcite-design-system/get-started#distribution) build, you'll need to manually define the custom elements on the window. You can also choose between local and CDN hosted assets.

```jsx
import { defineCustomElements } from "@esri/calcite-components/dist/loader";
Expand Down Expand Up @@ -86,7 +86,7 @@ function onUpdate(event) {
}

// need to access the dom node to set custom event listeners for props that aren't strings / numbers
// https://stenciljs.com/docs/react#properties-and-events
// lit.dev/docs/frameworks/react#why-are-wrappers-needed
useEffect(
(_) => {
sliderEl.current.addEventListener("calciteSliderUpdate", onUpdate);
Expand Down
2 changes: 1 addition & 1 deletion packages/calcite-components/FAQ.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ Esri's design principles, components, and patterns can be consumed through a sui

## What are Calcite Components?

Calcite Components are a set of reusable web components built using Stencil.js. With Calcite Components, you can quickly build on-brand, lightweight, and accessible web applications.
Calcite Components are a set of reusable web components built using Lit. With Calcite Components, you can quickly build on-brand, lightweight, and accessible web applications.

The framework-agnostic components can be used to develop entire websites and applications. The set is flexible for developers and adheres to consistent, industry-standard design principles. The codebase is well supported, steadily maintained, and always being improved.

Expand Down
12 changes: 2 additions & 10 deletions packages/calcite-components/conventions/Documentation.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
# Documentation

## Stencil API reference

Stencil uses [JSDoc](https://jsdoc.app) for their API reference generation. Stencil generates a [`docs-json`](https://stenciljs.com/docs/docs-json) output target, which is parsed and displayed on the [SDK site](https://developers.arcgis.com/calcite-design-system/components). The API reference includes property/attribute names, descriptions, types, values, and description notes (e.g. required, optional, deprecated). The SDK site updates the API reference after Calcite Component releases.

### Style guide
## Style guide

Follow these conventions when adding or editing API reference:

Expand All @@ -15,7 +11,7 @@ Follow these conventions when adding or editing API reference:
- For plural context, use `calcite-button`s instead of `calcite-button` elements.
- Use backticks (`` ` ``) for the names of slots, events, properties, CSS variables, and component names (e.g. `calcite-button` instead of calcite-button and `selectionMode` instead of "selectionMode"). Also use backticks for the values of properties and event details (e.g. `true`). If the value is a string, use both backticks and double quotes (e.g. `"single-persist"`).
- Only use single quotes (`'`) as apostrophes.
- No links or URLs allowed in descriptions. If a link is necessary, a [custom JSDoc tag](https://stenciljs.com/docs/docs-json#custom-jsdocs-tags) should be added and parsed in the SDK site.
- No links or URLs allowed in descriptions. If a link is necessary, a custom JSDoc tag should be added and parsed in the SDK site.
Comment thread
DitwanP marked this conversation as resolved.
- Refrain from using "e.g." or "i.e." references. Leverage "such as" (or similar) where examples are referenced.
- Use "Accessible" instead of "Aria" or "a11y" language.
- Verify slots and properties/attributes don't use the text "optional" in their descriptions.
Expand All @@ -27,10 +23,6 @@ There are two ways to document deprecations, depending on the API reference. In
1. The `@deprecated` JSDoc tag is used for JavaScript properties, events, and methods in the `<component-name>.tsx` file. Notes can accompany the JSDoc tag, such as "use `<property>` instead".
2. The `[Deprecated]` text is added at the beginning of the JSDoc description for slots (`@slots`) in the `<component-name>.tsx` file and CSS variables in the `<component-name>.scss` file. The text is parsed and removed from the description in the SDK site.

### Usage snippets

You can provide code snippets demonstrating a specific behavior or pattern for a component. Within the component's directory, create a new `usage` directory. Then, create a Markdown file with the filename as the title of the snippet. There should only be one snippet per Markdown file. Stencil will add the usage snippets to the component's README after building. These usage snippets will then be displayed in Storybook.

### Using utilities

There are a variety of Storybook [helpers](../.storybook/helpers.ts) and [utilities](../.storybook/utils.tsx) that should be used for common patterns. You can use existing stories as a reference for when/how the utilities and helpers should be used.
15 changes: 0 additions & 15 deletions packages/calcite-components/conventions/Internationalization.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,18 +59,3 @@ This pattern enables components to support built-in translations. In order to su
- Placeholders in message bundle strings should:
- Use the following syntax: `{placeholder}` (e.g., `Hello {userName}, my old friend. 👋`).
- Have an expressive name to provide context regarding its use.

## Translated strings

**Note ⚠️**: this pattern is deprecated and should no longer be followed for future components!

In the future it will likely become necessary to provide string translations for components. An example would be the `aria-label` for the `<calcite-modal>` close button. Initial research looks promising and we could likely implement one of these approaches and set a `lang` for each component.

- <https://medium.com/stencil-tricks/implementing-internationalisation-i18n-with-stencil-5e6559554117> and <https://codesandbox.io/s/43pmx55vo9>
- <https://github.com/ionic-team/ionic-stencil-conference-app/issues/69>

Until we implement a `lang` facility and set up translations for all components, we have been allowing a small number of strings to be passed in as properties. Properties that represent translated strings should have the syntax: `text-label-x`, where `x` is the name for the string. For example, when providing a string from "Close", use the property name `text-label-close`. In the component, these properties should default to their English equivalent (this is useful for non-localized apps):

```tsx
@Prop() textLabelClose: string = 'Close';
```
83 changes: 1 addition & 82 deletions packages/calcite-components/conventions/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,7 @@ Generally adhere to and follow these best practices for authoring components.

- [Google Web Component Best Practices](https://developers.google.com/web/fundamentals/web-components/best-practices)
- [Custom Element Conformance - W3C Editor's Draft](https://html.spec.whatwg.org/multipage/custom-elements.html#custom-element-conformance)

## Structure

We follow Stencil's suggested component structure. See their [style guide](https://github.com/ionic-team/stencil/blob/master/STYLE_GUIDE.md#file-structure) for more details.
- [Internal Tooling and Guidlines for Building Components](qawebgis.esri.com/components/lumina/introduction)

## Component Responsibilities

Expand Down Expand Up @@ -288,54 +285,6 @@ Using dynamic classes:

**Note**: Ensure that class-generating functions are strongly typed to avoid runtime errors.

## assets

If a component needs assets, they should be placed under a `assets/<component-name>` subdirectory. For example,

```text
my-component/
assets/
my-component/
asset.json
my-component.e2e.ts
my-component.tsx
my-component.scss
...
```

The component's metadata should then include the following metadata prop [`assetsDirs: ["assets"]`](https://stenciljs.com/docs/assets#assetsdirs).

```tsx
import { Component, Host, h } from "@stencil/core";

@Component({
tag: "calcite-test",
shadow: true,
assetsDirs: ["assets"],
})
export class MyComponent {
/* ... */
}
```

Afterwards, any asset path references must use the `getAssetPath` utility, using the `assets` directory as the root.

```ts
const assetPath = getAssetPath(`./assets/my-component/asset.json`);
```

This is required in order to have a unified assets folder in the distributable.

## Bundling and Loading

Stencil has the capability to build and distribute a large variety of outputs based on our needs. You can read more about this in the [output targets](https://github.com/ionic-team/stencil/blob/cc55401555ff5c28757cf99edf372dcada2c0b25/src/compiler/output-targets/readme.md) documentation.

As a best practice we should follow [Ionic's configuration](https://github.com/ionic-team/ionic/blob/master/core/stencil.config.ts) and generate a `bundle` for each component. Stencil will then generate a loader that will dynamically load the components used on the page.

**Note:** This is highly likely to change as we move closer to our first release and as Stencil improves their documentation around their specific methods and build processes.

Each root component should have a corresponding bundle entry in `stencil.config.ts`.

## Unique IDs for Components

Many times it is necessary for components to have a `id="something"` attribute for things like `<label>` and various `aria-*` properties. To safely generate a unique id for a component but to also allow a user supplied `id` attribute to work follow the following pattern:
Expand Down Expand Up @@ -364,32 +313,6 @@ export class Example {

This will create a unique id attribute like `id="calcite-example-51af-0941-54ae-22c14d441beb"` which should have a VERY low collision change since `guid()` generates IDs with `window.crypto.getRandomValues`. If a user supplies an `id` this will respect the users `id`.

## Prerendering and SSR
Comment thread
DitwanP marked this conversation as resolved.

Stencil provide the capability to render web components on the server and seamlessly hydrate them on the client. This is handled by the `dist-hydrate-script` output target in `stencil.config.ts`.

This generates a `hydrate` directory which exposes `renderToString()` (for the server) and `hydrateDocument()` for the client.

Since many of the same lifecycle methods are called on the client and server you may need to differentiate any code that relies on browser APIs like so:

```ts
import { isBrowser } from "../utils/browser";

if (isBrowser()) {
// client side
} else {
// server side
}
```

Checking if the necessary APIs are present is also acceptable:

```ts
const elements = this.el.shadowRoot ? this.el.shadowRoot.querySelector("slot").assignedElements() : [];
```

To ensure that all components are compatible for prerendering a prerender build is done as part of `npm test`.

## Cleaning up resources

Ensure all components clean up their resources.
Expand Down Expand Up @@ -417,10 +340,6 @@ Avoid setting z-index ad hoc and instead use a contextual z-index layer from the

There are utilities for common workflows in [`src/utils`](../src/utils).

### Global attributes

Watching global attributes on components is now possible with Stencil v4. Please refer to the [documentation page](https://stenciljs.com/docs/reactive-data#watching-native-html-attributes) for more information.

### BigDecimal

`BigDecimal` is a [number util](https://github.com/Esri/calcite-design-system/blob/dev/packages/calcite-components/src/utils/number.ts) that helps with [arbitrary precision arithmetic](https://en.wikipedia.org/wiki/Arbitrary-precision_arithmetic). The util is adopted from a [Stack Overflow answer](https://stackoverflow.com/a/66939244) with some small changes. There are some usage examples in [`number.spec.ts`](../src/utils/number.spec.ts).
Expand Down
Loading