{"id":24261753,"url":"https://github.com/act-org/dls","last_synced_at":"2025-06-14T19:36:03.025Z","repository":{"id":37950780,"uuid":"339461839","full_name":"act-org/dls","owner":"act-org","description":"Design Language System (DLS) for ACT \u0026 Encoura front-end projects.","archived":false,"fork":false,"pushed_at":"2024-04-08T20:53:20.000Z","size":26909,"stargazers_count":4,"open_issues_count":17,"forks_count":1,"subscribers_count":12,"default_branch":"main","last_synced_at":"2024-04-15T03:16:40.060Z","etag":null,"topics":["design-language-system","dls","material-ui","react","storyboook","typescript"],"latest_commit_sha":null,"homepage":"https://act-org.github.io/dls","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/act-org.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2021-02-16T16:35:26.000Z","updated_at":"2024-08-07T15:00:35.494Z","dependencies_parsed_at":"2023-12-20T16:27:31.845Z","dependency_job_id":"7af7fa9c-0d76-4034-b268-d930c4662134","html_url":"https://github.com/act-org/dls","commit_stats":{"total_commits":417,"total_committers":14,"mean_commits":"29.785714285714285","dds":0.302158273381295,"last_synced_commit":"52e8071d537f673e5320f3aa9a3959a89834ae64"},"previous_names":[],"tags_count":136,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/act-org%2Fdls","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/act-org%2Fdls/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/act-org%2Fdls/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/act-org%2Fdls/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/act-org","download_url":"https://codeload.github.com/act-org/dls/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":233862664,"owners_count":18742007,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["design-language-system","dls","material-ui","react","storyboook","typescript"],"created_at":"2025-01-15T06:19:27.014Z","updated_at":"2025-01-15T06:19:27.635Z","avatar_url":"https://github.com/act-org.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Design Language System (DLS)\n\n\u003c!-- markdownlint-disable no-inline-html --\u003e\n\n\u003ca href=\"https://www.npmjs.com/package/@actinc/dls\"\u003e\n  \u003cimg alt=\"Version\" src=\"https://img.shields.io/npm/v/@actinc/dls\"/\u003e\n\u003c/a\u003e\u0026nbsp;\u003ca href=\"https://github.com/act-org/dls/actions/workflows/ci.yml\"\u003e\n  \u003cimg alt=\"Build\" src=\"https://github.com/act-org/dls/actions/workflows/ci.yml/badge.svg\"/\u003e\n\u003c/a\u003e\u0026nbsp;\u003ca href=\"https://github.com/act-org/dls/blob/master/LICENSE\"\u003e\n  \u003cimg alt=\"License\" src=\"https://img.shields.io/badge/license-MIT-green\"/\u003e\n\u003c/a\u003e\u0026nbsp;\u003ca href=\"https://www.npmjs.com/package/@actinc/dls\"\u003e\n  \u003cimg alt=\"Downloads\" src=\"https://img.shields.io/npm/dw/@actinc/dls?color=orange\"/\u003e\n\u003c/a\u003e\n\n\u003c!-- markdownlint-enable no-inline-html --\u003e\n\nThe Design Language System for ACT \u0026 Encoura front-end projects. View the UI components\n[here](https://act-org.github.io/dls).\n\n## Project Setup\n\n### Installation\n\nIn order to use the DLS, you must install it along with\n[Material UI](https://mui.com/) version `6.x` and\n[React](https://reactjs.org/) version `18.x` or `19.x`.\n\n```sh\nnpm install --save @actinc/dls@latest @mui/material @mui/system @mui/x-data-grid react react-dom\n```\n\n### Choosing a Theme\n\nThis DLS is built on top of the\n[theme engine](https://mui.com/material-ui/customization/theming/) from\nMaterial UI, and ships with several themes out of the box:\n\n1. `\"ACT\"`: for ACT's \"traditional\" look and feel\n2. `\"ACT_ET\"`: for ACT's \"Emerging Technology\" look and feel\n3. `\"ENCOURA\"`: for the Encoura's \"MyEncoura\" look and feel\n4. `\"ENCOURA_CLASSIC\"`: for Encoura's \"Classic\" look and feel\n5. `\"ENCOURAGE\"`: for the Encoura's \"Encourage for Students\" look and feel\n6. `\"ENCOURAGE_E4E\"`: for the Encoura's \"Encourage for Educators\" look and feel\n\nTo apply one of these themes to your components, simply wrap your application\nin the `ThemeProvider` component and specify a theme!\n\n```jsx\nimport { ThemeProvider } from '@actinc/dls/components/ThemeProvider';\n\n...\n\nconst MyApp = () =\u003e (\n  // specify a theme here!\n  \u003cThemeProvider theme=\"ACT_ET\"\u003e\n    \u003cApp /\u003e\n  \u003c/ThemeProvider\u003e\n);\n```\n\n#### Extending Themes\n\nYou can exend the core DLS themes using using our variation on the\n[`createTheme`](https://mui.com/material-ui/customization/theming/#createtheme-options-args-theme)\ngenerator from Material UI:\n\n```jsx\nimport deepMerge from 'deepmerge';\nimport { createTheme } from '@actinc/dls/styles/createTheme';\nimport { THEME_ACT } from '@actinc/dls/styles/themeAct';\nimport { ThemeProvider } from '@actinc/dls/components/ThemeProvider';\n\nconst myExtendedTheme = createTheme(\n  deepMerge(THEME_ACT, {\n    // theme customizations go here!\n  }),\n);\n\nconst MyApp = () =\u003e (\n  \u003cThemeProvider theme={myExtendedTheme}\u003e\n    \u003cApp /\u003e\n  \u003c/ThemeProvider\u003e\n);\n```\n\n#### Custom Themes\n\nAlternatively, you can build your own theme from scratch using our variation on the\n[`createTheme`](https://mui.com/material-ui/customization/theming/#createtheme-options-args-theme)\ngenerator from Material UI. Our version takes the same parameters, but will\nreturn a strongly typed version of the theme with any customizations you may\nhave added.\n\n```jsx\nimport { ThemeProvider } from '@actinc/dls/components/ThemeProvider';\nimport { createTheme } from '@actinc/dls/styles/createTheme';\n\nconst myCustomTheme = createTheme({\n  // build your theme here!\n});\n\nconst MyApp = () =\u003e (\n  \u003cThemeProvider theme={myCustomTheme}\u003e\n    \u003cApp /\u003e\n  \u003c/ThemeProvider\u003e\n);\n```\n\n#### Custom Themes And Styled Components\n\nWithin your styled components, if you need to access custom a theme variable\nthat is not present in the default MUI `Theme` type, we provide a helper\nfunction to generate a `styled` function that is strongly typed to your theme:\n\n```jsx\nimport { createThemeStyled } from '@actinc/dls/helpers/styled';\nimport { THEME_ACT } from '@actinc/dls/styles/themeAct';\nimport TableCell from '@mui/material/TableCell';\n\nconst styled = createThemeStyled(THEME_ACT);\n\nconst StyledTypography = styled(TableCell)(({ theme }) =\u003e ({\n  // `customDims` is not available on the default theme\n  height: theme.customDims.heights.tableHeader,\n}));\n```\n\n#### Custom Themes and Module Augmentation\n\nIn cases where you want to \"patch\" or [augment](https://www.typescriptlang.org/docs/handbook/declaration-merging.html#module-augmentation)\nan underlying type (for example, if adding a custom color to your theme's\npalette), you can create a TS definition file and include it in your project's\n`tsconfig.json`.\n\nSteps:\n\n- Create your TS definition file (must use the `.d.ts` file extension).\n  [Example here](./src/styles/themeEncourageE4E/augmentTheme.d.ts).\n- Ensure that your definition file does **not** use import aliases.\n- Do a release. The DLS will automatically include the definition file in the\n  build.\n- In your project's repo, update your `tsconfig.json`'s `include` field to\n  point to the file in your `node_modules` directory. Example: `./node_modules/@actinc/dls/path/to/your/index.d.ts`.\n- You may need to restart your IDE's TS server for the changes to appear.\n\n### Load Fonts\n\n#### Montserrat\n\nThe `ACT` and `ACT_ET` themes assume that the\n[Montserrat](https://fonts.google.com/specimen/Montserrat) font is available in\nthe browser. Therefore, it is recommended that you include the following font\nreference in the `head` of your React app:\n\n```html\n\u003clink\n  href=\"https://fonts.googleapis.com/css?family=Montserrat:300,400,500,600,700\u0026display=swap\"\n  rel=\"stylesheet\"\n/\u003e\n```\n\n#### Museo Sans\n\nThe `ENCOURA` and `ENCOURA_CLASSIC` themes assume that the\n[Museo Sans](https://fonts.adobe.com/fonts/museo-sans) font\nis available in the browser. Include this embed code in the `head`\nof your React app after obtaining the licensed font URL from Marketing:\n\n```html\n\u003cstyle\u003e\n  @import url('licensed-font-url');\n\u003c/style\u003e\n```\n\n#### Work Sans, Roboto, Roboto Mono\n\nThe `ENCOURAGE` and `ENCOURAGE_E4E` themes assume that the\n[Work Sans](https://fonts.google.com/specimen/Work+Sans),\n[Roboto](https://fonts.google.com/specimen/Roboto), and the\n[Roboto Mono](https://fonts.google.com/specimen/Roboto+Mono) fonts are available\nin the browser. Therefore, it is recommended that you include the following font\nreference in the `head` of your React app:\n\n```html\n\u003c!-- Fonts required for ENCOURAGE: --\u003e\n\u003clink\n  href=\"https://fonts.googleapis.com/css2?display=swap\u0026family=Work+Sans:wght@200..800\"\n  rel=\"stylesheet\"\n/\u003e\n\u003clink\n  href=\"https://fonts.googleapis.com/css2?display=swap\u0026family=Roboto:wght@300;400;500;700\"\n  rel=\"stylesheet\"\n/\u003e\n\u003clink\n  href=\"https://fonts.googleapis.com/css2?display=swap\u0026family=Roboto+Mono:wght@200..700\"\n  rel=\"stylesheet\"\n/\u003e\n\n\u003c!-- Fonts required for ENCOURAGE_E4E: --\u003e\n\u003clink\n  href=\"https://fonts.googleapis.com/css?family=Roboto:300,400,500,600,700\"\n  rel=\"stylesheet\"\n/\u003e\n\u003clink\n  href=\"https://fonts.googleapis.com/css2?family=Roboto+Mono:wght@400;500\u0026display=swap\"\n  rel=\"stylesheet\"\n/\u003e\n\u003clink\n  href=\"https://fonts.googleapis.com/css2?display=swap\u0026family=Work+Sans:wght@200..800\"\n  rel=\"stylesheet\"\n/\u003e\n```\n\n### CSS Baseline\n\nIt is recommended to inject the `CssBaseline` component from Material UI near\nthe root of your component tree in order to reset and normalize browser styles\nfor your project:\n\n```jsx\nimport { CssBaseline } from '@mui/material';\n\n...\n\nconst MyApp = () =\u003e (\n  ...\n  \u003cCssBaseline /\u003e\n  ...\n);\n```\n\n### Server-Side Rendering\n\nIf your project's React framework supports SSR, you can configure the DLS\ncomponents for server-side rendering. See the official Next.js example\n[here](https://github.com/mui/material-ui/tree/master/examples/nextjs-with-typescript).\n\n### Icons\n\n#### Option 1: Find and import from the DLS\n\nThe DLS re-exports all icons that are provided by the\n[`mdi-material-ui`](https://www.npmjs.com/package/mdi-material-ui) package. This\nis an expansive list of icons that are managed by the material community. You\ncan search for a specific icon to use on\n[materialdesignicons.com](https://materialdesignicons.com). Once you've found\nthe perfect icon, you can use it in your project like so:\n\n```jsx\n// Import the needed icon(s) directly, to avoid bundle size bloat.\nimport PollBox from '@actinc/dls/icons/PollBox';\n\n...\n\nconst MyComponent = () =\u003e (\n  ...\n  \u003cPollBox /\u003e\n  ...\n);\n```\n\n#### Option 2: Find and import from `@mui/icons-material`\n\nIf the DLS doesn't provide the icon you're looking for, as a second line of\ndefense, you can search for icons in the\n[`@mui/icons-material`](https://www.npmjs.com/package/@mui/icons-material)\nlibrary. While most of these icons can be found directly in the DLS via\n`mdi-material-ui`, there is some unique selection within this library that could\nbe useful to you. You can search for a specific icon to use on\n[mui.com](https://mui.com/material-ui/material-icons/). Once you've found\nthe perfect icon, you can use it in your project like so:\n\n```jsx\n// Import the needed icon(s) directly, to avoid bundle size bloat.\nimport PollIcon from '@mui/icons-material/Poll';\n\n...\n\nconst MyComponent = () =\u003e (\n  ...\n  \u003cPollIcon /\u003e\n  ...\n);\n```\n\n#### Option 3: Create a custom icon\n\nWhen all else fails, you can create a custom icon using the `SvgIcon` component\nfrom Material UI. Here's an example:\n\n```jsx\nimport SvgIcon, { SvgIconProps } from '@mui/material/SvgIcon';\nimport React from 'react';\n\nexport const CustomIcon: React.FC\u003cSvgIconProps\u003e = (props: SvgIconProps): React.ReactElement\u003cSvgIconProps\u003e =\u003e (\n  \u003cSvgIcon style={{ fill: 'none' }} viewBox=\"0 0 24 24\" {...props}\u003e\n    \u003cpath d=\"\u003cinsert-svg-data-here\u003e\" /\u003e\n  \u003c/SvgIcon\u003e\n);\n\nexport default CustomIcon;\n```\n\n### Import Stuff\n\nThat's it! You're ready to use the DLS. Simply import the components,\nconstants, context, helpers, hooks, icons, styles, and types that you need:\n\n```jsx\n// components\nimport { Alert } from '@actinc/dls/components/Alert';\n// constants\nimport { SORT_DIRECTION_TYPES } from '@actinc/dls/constants';\n// context\nimport { AlertContext } from '@actinc/dls/context';\n// helpers\nimport { search } from '@actinc/dls/helpers';\n// hooks\nimport { useLocalStorage } from '@actinc/dls/hooks';\n// icons\nimport ChevronDown from '@actinc/dls/icons/ChevronDown';\n// styles \u0026 themes\nimport { THEME_ACT } from '@actinc/dls/styles/themeAct';\n// types\nimport { SortObject } from '@actinc/dls/types';\n```\n\n### Transient Props and Styled Components\n\nThe DLS provides a customized styled helper which omits transient props\n(those starting with $) from the rendered HTML, while still being able to use\nthose parameters in styled components. Use as a drop in replacement of the\n`styled` function that exists in `@mui/material/styles`:\n\n```jsx\nimport { styled } from '@actinc/dls/helpers/styled';\nimport Button, { ButtonProps } from '@mui/material/Button';\nimport * as React from 'react';\n\nconst StyledButton = styled(Button)\u003cButtonProps \u0026 { $ultraWide: boolean }\u003e(\n  ({ $ultraWide, theme }) =\u003e ({\n    paddingLeft: $ultraWide ? theme.spacing(8) : theme.spacing(4),\n    paddingRight: $ultraWide ? theme.spacing(8) : theme.spacing(4),\n  }),\n);\n\nconst MyComponent: React.FC = () =\u003e {\n  return \u003cStyledButton $ultraWide /\u003e;\n};\n```\n\n- This implementation is how Styled Components does it: \u003chttps://styled-components.com/docs/api#transient-props\u003e\n- Unfortunately emotion (the default styling engine in React) doesn't seem to\n  care: \u003chttps://github.com/emotion-js/emotion/issues/2193#issuecomment-1178372803\u003e\n\n## ES Modules \u0026 Tree Shaking\n\nVersion \u003c= 6 of the DLS were built and exported as\n[CommonJS modules](https://nodejs.org/api/modules.html#modules-commonjs-modules).\nWhile this allowed the simplest integration of the DLS into any\nproject, it also resulted in project bundles being\n[larger than desired](https://web.dev/commonjs-larger-bundles/) due to\nthe inability of bundlers to\n[tree-shake](https://www.smashingmagazine.com/2021/05/tree-shaking-reference-guide/)\nthe DLS.\n\nIn version \u003e= 7 of the DLS, we are now building and exporting the library as\n[ECMAScript modules](https://nodejs.org/api/esm.html#modules-ecmascript-modules).\nThis allows your project's bundler to much more easily read and\n[tree-shake](https://www.smashingmagazine.com/2021/05/tree-shaking-reference-guide/)\nthe DLS right out of the box. (No more need for\n[`babel-plugin-transform-imports`](https://www.npmjs.com/package/babel-plugin-transform-imports)!)\n\nFurthermore, the DLS's `package.json` is also setting:\n\n```json\n\"sideEffects\": false,\n```\n\nto instruct builders to enable even deeper tree-shaking. This should make\nbundle sizes significantly smaller with less effort. However, the tradeoff\nis that in certain scenarios, like\n[Lazy Loading](https://nextjs.org/docs/advanced-features/dynamic-import),\nif you are expecting a dependency to be there that is now removed from\ntree-shaking, things will break and you may need to import that dependency\ndirectly in a parent bundle.\n\n### SyntaxError: Unexpected token 'export'\n\nOne downside of exporting the DLS as ECMAScript modules is that the `import` and\n`export` keywords are preserved, which may cause your packager/runner to throw:\n\n```sh\nSyntaxError: Unexpected token 'export'\n```\n\nIf you see this error, you'll need to instruct your packager/runner to transpile\nthe DLS on-the-fly.\n\n#### Next.js\n\nYou can do this in a [Next.js](https://nextjs.org/) app by adding the DLS to the\n[`transpilePackages`](https://beta.nextjs.org/docs/api-reference/next.config.js#transpilepackages)\noption in your `next.config.js` file.\n\n```js\ntranspilePackages: ['@actinc/dls'],\n```\n\n#### Jest\n\nYou can do this in the [Jest](https://jestjs.io/) test runner by omitting the\nDLS from the\n[`transformIgnorePatterns`](https://jestjs.io/docs/tutorial-react-native#transformignorepatterns-customization)\noption in your `jest.config.js` file.\n\n```js\ntransformIgnorePatterns: ['/node_modules/(?!(@actinc/dls)/)'],\n```\n\n## Local Development\n\nCheck out the [developer guide](./docs/GUIDE.md) to learn how to build\neffectively for the DLS.\n\nTo run the DLS locally:\n\n1. Install node modules: `npm install`\n2. Start the [Storybook](https://storybook.js.org) component visualizer:\n   `npm start`\n\n### How to Iterate Locally\n\n#### Option 1: Creating a Local Build\n\nWhen you're ready to pilot your changes to this library in your local project:\n\n1. Run the `npm run pack` command. When it finishes running, it will generate a\n   `.tgz` file in the `/dist` folder with the following name format\n   `actinc-dls-\u003cversion-number\u003e.tgz`;\n2. Access the `package.json` file of your local project in which the\n   `@actinc/dls` package will be tested, and make the following edit:\n\n   ```json\n   \"dependencies\": {\n     // Before (pulling from NPM via version number):\n     \"@actinc/dls\": \"9.2.1\",\n     // After (pointing to the local .tgz file):\n     \"@actinc/dls\": \"file:../path/to/@actinc/dls/dist/actinc-dls-\u003cversion-number\u003e.tgz\",\n     ...\n   }\n   ```\n\n3. Run `npm update @actinc/dls` to refresh your project's `node_modules` folder.\n\n4. You can now run your project with the local changes made to this library!\n\n5. If you want to make any further edits to this library, simply run\n   `npm run pack` to package up the changes, and then `npm update @actinc/dls`\n   in your local project to pull them in.\n\n6. When you're done piloting the changes, simply revert your project's\n   `package.json` file to pull this library from NPM, and run\n   `npm update @actinc/dls` to refresh your project's `node_modules` folder.\n\n#### Option 2: Real-time Previews\n\nFor rapid iteration, you can run a live copy of this library in your\ndownstream project:\n\n1. In this library, run the watch script: `npm run watch`\n\n2. In your project, install a local build of this library: `npm install \u003cpath-to-this-repo\u003e/dist`\n\nUnder the hood, this creates a symlink between the local build and your project.\nWhen changes are detected under the `src` folder, a new build will be output\ninto the `dist` folder and picked up by your project.\n\nOnce you are happy with the changes, you'll want to destroy this symlink\nand replace the local build with a formal/hosted version of this library.\nYou can do that by running the following commands in your project:\n\n1. `npm uninstall @actinc/dls`\n\n2. `npm install @actinc/dls@\u003cpick-your-version\u003e --save --save-exact`\n\n### npm Scripts\n\nThere are lots of npm scripts at your disposal during local development.\nHere are some of the more important ones:\n\n| Script                    | Description                                                             |\n| :------------------------ | :---------------------------------------------------------------------- |\n| npm run build             | Transpiles DLS from TypeScript (`./src`) into ES5 (`./dist`).           |\n| npm run build-storybook   | Creates a static website for deployment (`./storybook-static`).         |\n| npm start                 | Starts the [Storybook](https://storybook.js.org) component visualizer.  |\n| npm test                  | Runs all tests.                                                         |\n| npm run release           | Publishes a new release of the DLS.                                     |\n| npm run release:storybook | Publishes a new release of Storybook (make sure to pull latest `main`). |\n| npm run watch             | Watch the `src` folder for changes and transpile on-the-fly to `dist`.  |\n\n### Committing Code\n\nsemantic-release scans commits to manage package.json versions and `CHANGELOG.MD`\n\nIt is important that we accurately capture what type of development we are doing.\n\n- For changes to storybook (i.e. no change to components), use the `docs` tag:\n\n```bash\ngit commit -m \"docs: Added stories for Alert\"\n```\n\n- For patches to existing components, use `fix`:\n\n```bash\ngit commit -m \"fix: Fixed Snackbar not appear in center of screen\"\n```\n\n- For new functionality, use `feat`:\n\n```bash\ngit commit -m \"feat: Added Carousel component\"\n```\n\n## Pinned Packages\n\nSome npm packages are pinned to non-current versions for a specific reason:\n\n| Package | Version | Reason |\n| :------ | :------ | :----- |\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fact-org%2Fdls","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fact-org%2Fdls","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fact-org%2Fdls/lists"}