npm package: @moxiworks/mds
Description: Moxiworks Custom Component System
Latest version: 0.25.1

![Built With Stencil](https://img.shields.io/badge/-Built%20With%20Stencil-16161d.svg?logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDE5LjIuMSwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPgo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IgoJIHZpZXdCb3g9IjAgMCA1MTIgNTEyIiBzdHlsZT0iZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCA1MTIgNTEyOyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI%2BCjxzdHlsZSB0eXBlPSJ0ZXh0L2NzcyI%2BCgkuc3Qwe2ZpbGw6I0ZGRkZGRjt9Cjwvc3R5bGU%2BCjxwYXRoIGNsYXNzPSJzdDAiIGQ9Ik00MjQuNywzNzMuOWMwLDM3LjYtNTUuMSw2OC42LTkyLjcsNjguNkgxODAuNGMtMzcuOSwwLTkyLjctMzAuNy05Mi43LTY4LjZ2LTMuNmgzMzYuOVYzNzMuOXoiLz4KPHBhdGggY2xhc3M9InN0MCIgZD0iTTQyNC43LDI5Mi4xSDE4MC40Yy0zNy42LDAtOTIuNy0zMS05Mi43LTY4LjZ2LTMuNkgzMzJjMzcuNiwwLDkyLjcsMzEsOTIuNyw2OC42VjI5Mi4xeiIvPgo8cGF0aCBjbGFzcz0ic3QwIiBkPSJNNDI0LjcsMTQxLjdIODcuN3YtMy42YzAtMzcuNiw1NC44LTY4LjYsOTIuNy02OC42SDMzMmMzNy45LDAsOTIuNywzMC43LDkyLjcsNjguNlYxNDEuN3oiLz4KPC9zdmc%2BCg%3D%3D&colorA=16161d&style=flat-square)

# @moxiworks/mds

![npm](https://img.shields.io/npm/v/%40moxiworks%2Fmds)

The Moxi Design System is a framework utilizing TailwindCSS and StencilJS to provide a CSS foundational framework combined with a library of universal Javascript components to use in any project with any framework you desire.

The goal is to create this framework to the spec of our design team and committing to the continued growth of this system moving forward.

## Development

The project uses Vuepress as a means to write documentation as you develop. When the system is built, Vuepress is compiled to the `docs` directory to be accessed via Github pages.

Installation docs for this project can be found [in the root README.md](../../README.md)

### Dependencies

This project utilises the local `mds-styles` package. Yarn will automatically link that package to the mds dependancies when you run `yarn install`. However you must still build the `mds-styles` package:

```bash
yarn workspace @moxiworks/mds-styles build
```

### Running locally

After the dependencies are installed run `yarn dev` to start the development Vuepress server.

> [!IMPORTANT]
> If you run into issues, try running `yarn tailwind:dev` and `yarn stencil:dev` in two separate processes. Once they are both running, open a third terminal and run `yarn docs:dev`. All three of these scripts will run endlessly as they will be watching for changes to your stylesheets, components, and documentation files.
>
> If you receive an error regarding `variables.scss` when you run `yarn tailwind:dev`, you need to build `mds-styles`. See [Dependencies](#dependencies) above.

You can now access the site at [http://localhost:8080](http://localhost:8080).

### Building

Building in this package is quite complex. We define a different build for each tool (stencil, tailwind, vuepress), and each type of stencil output (mds, react, vue, angular ...etc).

`yarn build` is the simplest solution, as it will build everything. But you can save time if you're only testing a single output (e.g `yarn build:react`)

The `build` script calls `build.sh`. This script utilises an env called "TARGET" to determine the build type. This is done to support the yarn `workspaces foreach` command, which will build all dependancies. Since `build` is the command that would run in other packages, we want the `build` command in this package to support all outputs.

### Formatting and linting

The project uses [prettier](https://github.com/prettier/prettier) to standardize code style. If you have
a prettier plugin installed in your editor, then files may be formatted automatically on save. Otherwise,
staged files will be formatted during a pre-commit hook (via [husky](https://github.com/typicode/husky)
and [lint-staged](https://github.com/okonet/lint-staged)). See the `.prettierrc` file for rules.

JavaScript and TypeScript files will also be linted prior to being committed. The commit will fail if
there are any warnings or errors per our `.eslintrc.js` ruleset, which is based on [`eslint:recommended`](https://eslint.org/docs/rules/)
and [@typescript-eslint/recommended](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/docs/rules/README.md).

## Vuepress Documentation Only Creation and Editing

This has been updated to where you can simply run `yarn dev` to update documentation without the worry of unintended dynamic file changes being added to your commits.

### Where Things Live

#### Vuepress

The development site is located under the `vuepress` directory. To learn more about Vuepress and it's paradigms, please read the [documentation here](http://vuepress.vuejs.org/).

The basics are very straight forward. The site is powered by Markdown files. Add and edit folders and `.md` files as needed for documentation and development.

You can develop the component in Vuepress then write the documentation around it when ready.

#### StencilJS Components

All of the StencilJS components are located in the `src` directory.

You can read more about Stencil, it's lifecycle methods, property handling, etc at [https://stenciljs.com/docs/introduction](https://stenciljs.com/docs/introduction).

#### TailwindCSS

The TailwindCSS code is located under `src/tailwind`. The configuration file is located in the root of the directory as `tailwind.config.js`.

You can read more about [TailwindCSS here](http://tailwindcss.com/).

#### IMPORTANT :rotating_light: :rotating_light: :rotating_light:

We are not using the Shadow DOM for the Stencil components and are not using the CSS paradigm they provide. The reason is that the CSS for this project needs to also support Ruby based `view components`. You can read more about them here: [https://viewcomponent.org/](https://viewcomponent.org/).

There's no reason to write and maintain this CSS in two places so the TailwindCSS implementation will be the source of truth for our component styling.

Under `src/tailwind` you'll see directories like `mx-input` and `mx-button`. Those `SASS` directories and files are included in the `styles.css` file. SCSS is transpiled to CSS immediately thanks to PostCSS.

## Writing a Component

Below is a brief checklist for authoring a new component:

- [ ] Add a new Stencil component.
  - This can be as simple as copying and renaming an existing directory within `src/components`. Be sure to then update the file names and tags within those files as well.
  - Alternatively, there is a generator to stub a new component: `yarn stencil:generate mx-{name of component}`. All of the components are prefixed with `mx-`. For example, the input component is called `mx-input` which is essentially the tag name `<mx-input />`.
- [ ] If necessary, add a new `index.scss` stylesheet under `src/tailwind`. For example, a new `mx-gooey-menu` component would require a `src/tailwind/mx-gooey-menu/index.scss` file.
  - [ ] Be sure to then import this file in `src/tailwind/styles.css` (e.g. `@import './mx-gooey-menu/index.scss';`).
- [ ] Update or add a documentation file. Inside `vuepress/components` are markdown files, such as `menus.md`, which contain the documentation for the components. Add live examples to the page and leverage the vuepress dev server when developing your component.
  - [ ] If a new page is needed, create a new `.md` file (e.g. `vuepress/components/gooey-menus.md`). Add the new page to `vuepress/.vuepress/config.js` under `themeConfig.sidebar`. Try to keep the list alphabetical.
  - [ ] Add the Properties and Events to your docs page automatically by adding an instance of the vuepress `ComponentReadme` component (e.g. `<ComponentReadme component="mx-gooeymenu" />`);
- [ ] Test-drive your live examples in Chrome, Firefox, and Safari.
  - [ ] Try emulating smaller screens (as narrow as 375px) as well as larger ones.
  - [ ] Try to ensure accessibility for screen readers and keyboard navigation. The free version of [axe DevTools](https://www.deque.com/axe/devtools/) provide a good basic check.
- [ ] Create a unit test file (e.g. `src/components/mx-gooey-menu/test/mx-gooey-menu.spec.tsx`). Refer to the [Stencil testing documentation](https://stenciljs.com/docs/testing-overview). Try to cover as many props and events as possible. Certain responsive behaviors may be difficult to reproduce in the test runner.
- [ ] Run `yarn test` and ensure all tests pass.
- [ ] When writing your commit message, use the `feat:` prefix since you are adding a shiny new feature!

## Using In A Project

From your project run `yarn add @moxiworks/mds` or `npm install @moxiworks/mds` depending on your package manager.

At your entry point add the following code:

```js
import { applyPolyfills, defineCustomElements } from '@moxiworks/mds/loader';

// Bind the custom elements to the window object
applyPolyfills().then(() => {
  defineCustomElements();
});
```

StencilJS provides a loader which dynamically "tree-shakes" the code as needed. So, for example, the bundle for the mx-input won't be included in your bundle until you've written code in one of your views like:

```html
<mx-input label="Placeholder & Left Icon" left-icon="ph-apple-logo" />
```

### Framework Integrations

StencilJS has a bunch of documentation around integrating these types of components into most popular frameworks - including vanilla Javascript. You can read more about that here: [https://stenciljs.com/docs/overview](https://stenciljs.com/docs/overview)

We currently have the following framework integrations:

- React - Located in [packages/react-mds](../mds-react/README.md).