{"id":19788330,"url":"https://github.com/graylog2/sawmill-sd","last_synced_at":"2026-05-14T06:34:29.052Z","repository":{"id":45144676,"uuid":"426994429","full_name":"Graylog2/sawmill-sd","owner":"Graylog2","description":"sd design system","archived":false,"fork":false,"pushed_at":"2022-01-05T13:39:38.000Z","size":637,"stargazers_count":1,"open_issues_count":0,"forks_count":1,"subscribers_count":17,"default_branch":"main","last_synced_at":"2024-04-23T19:38:54.576Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://backlight.dev/view/f8bLRusG6EujzpCzDM6X","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Graylog2.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-11-11T12:33:15.000Z","updated_at":"2023-03-24T16:19:38.000Z","dependencies_parsed_at":"2022-08-30T10:10:25.258Z","dependency_job_id":null,"html_url":"https://github.com/Graylog2/sawmill-sd","commit_stats":null,"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Graylog2%2Fsawmill-sd","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Graylog2%2Fsawmill-sd/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Graylog2%2Fsawmill-sd/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Graylog2%2Fsawmill-sd/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Graylog2","download_url":"https://codeload.github.com/Graylog2/sawmill-sd/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241125008,"owners_count":19913839,"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":[],"created_at":"2024-11-12T06:26:53.194Z","updated_at":"2026-05-14T06:34:29.003Z","avatar_url":"https://github.com/Graylog2.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Sawmill ![Shield.io Badge](https://shields.io/npm/v/@graylog/sawmill-sd)\n\n#### a Design System by Graylog\n\n### Implementation\n\n`yarn add --dev @graylog/sawmill-sd`  \n_or_  \n`npm install --save-dev @graylog/sawmill-sd`\n\n```tsx\nimport { theme as sawmillTheme } from '@graylog/sawmill-sd';\n\nconst SawmillStyles = createGlobalStyle`\n  ${sawmillTheme.css.root}\n  ${sawmillTheme.css.noir}\n`;\n\nfunction renderAppContainer(appContainer) {\n  ReactDOM.render(\n    \u003cReact.Fragment\u003e\n      \u003cSawmillStyles /\u003e\n      \u003cApp /\u003e\n    \u003c/React.Fragment\u003e,\n    appContainer,\n  );\n}\n\nwindow.onload = () =\u003e {\n  const appContainer = document.createElement('div');\n\n  appContainer.id = 'app-root';\n  document.body.appendChild(appContainer);\n  renderAppContainer(appContainer);\n};\n```\n\nCurrently the app will need to set the `data-sawmill-mode` on the `\u003cbody\u003e` tag manually.\n\n_This could probably be a utility that Sawmill offers in the future._\n```ts\ndocument.body.dataset.sawmillMode = \"teint\";\n// or\ndocument.body.dataset.sawmillMode = \"noir\";\n```\n\n## Tokens\n\nAll theme mode color variables are generated in CSS. The generated JSON file only currently has the default colors.\n\nA new [format](https://amzn.github.io/style-dictionary/#/api?id=registerformat)\nor [filter](https://amzn.github.io/style-dictionary/#/api?id=registerfilter) will probably need to be built to properly\nsupport Chakra on Mantine.\n\n### [Colors](https://backlight.dev/doc/f8bLRusG6EujzpCzDM6X/colors/doc/index.mdx)\n\nContains all the base colors for brand and variants. You\ncan [reference](https://amzn.github.io/style-dictionary/#/tokens?id=referencing-aliasing) these colors via their alias\nto have the library properly construct variables.\n\nFor each color, you will need a `value`, but you can also add a `modeNameValue` that will allow you to generate other\nmodes. You will notice some `noirValue` set with a different color to generate in the `variables-noir.css`. All these\noptions can be configured in the root of in the system in `sd.config.js`.\n\n### [Elevations](https://backlight.dev/doc/f8bLRusG6EujzpCzDM6X/elevations/doc/index.mdx)\n\nThere is a bug in the docs where you can't click on the `underneath` variant. Need to resolve this in some way to allow\nit to be clickable.\n\n### [Opacity](https://backlight.dev/doc/f8bLRusG6EujzpCzDM6X/opacity/doc/index.mdx)\n\nThese can be used as the alpha values for `rgba`, `hsla`, and the `opacity` property.\n\n### [Radii](https://backlight.dev/doc/f8bLRusG6EujzpCzDM6X/radii/doc/index.mdx)\n\nVariables for border-radius.\n\n\u003e _I haven't done a full assessment of our usage here, so these options may need to be adjusted to better fit into the existing design._\n\n### [Shadows](https://backlight.dev/doc/f8bLRusG6EujzpCzDM6X/shadows/doc/index.mdx)\n\nSimiliar to Radii, this will be for shadows, but have not done a full usage assessment of the different shadows in \nproduction today\n\n### [Spacings](https://backlight.dev/doc/f8bLRusG6EujzpCzDM6X/spacings/doc/index.mdx)\n\nSpacings are based off of the font-size using `rem` and then I just converted it manually to pixels. \nThere are a lot of ways this could be automated, the existing one is based off of a Fibonacci sequence.\n\n### Breakpoints\n\nThese are not yet integrated, we have a few defined in the current system as \n```ts\nconst breakpointSizes: { [key: string]: number } = {\n  xs: 480,\n  sm: 768,\n  md: 992,\n  lg: 1200,\n};\n```\n\nAnd they are in-use in a few different places of the app, such as the Header/Navigation bar. \nI didn't implement anything here yet because I wanted to see what the requirements are going to be for using a \nsystem like Mantine or other UI kit\n\n---\n\n\n## Stories\n\nStories are written in Storybook's [Component Story Format](https://backlight.dev/docs/component-story-format).\n\nYou can defined multiple stories for your components to visualize their variations:\n\n```jsx\nimport { Button } from '../index';\nimport { layout } from '~/tui-utils';\nexport default layout;\n\nexport const primary = () =\u003e \u003cButton variant=\"primary\"\u003ePrimary\u003c/Button\u003e;\nexport const secondary = () =\u003e \u003cButton variant=\"secondary\"\u003eSecondary\u003c/Button\u003e;\nexport const disabled = () =\u003e \u003cButton disabled\u003eDisabled\u003c/Button\u003e;\nexport const secondary_disabled = () =\u003e (\n  \u003cButton variant=\"secondary\" disabled\u003e\n    Disabled\n  \u003c/Button\u003e\n);\n```\n\nStories for the components are located in their `stories/` folder.\n\n## Documentation\n\nDocumentation pages are decorated by a React layout using the [@divriots/dockit-react](https://github.com/divriots/dockit-react) helpers. See the `layout` component.\n\n### Pages\n\nEach component embed its own documentation in its `doc/` folder. You can use any web format for your documentation but we recommend you to write it with the [mdx](https://backlight.dev/docs/mdx) format, allowing you to embed your components live in the documentation.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgraylog2%2Fsawmill-sd","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgraylog2%2Fsawmill-sd","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgraylog2%2Fsawmill-sd/lists"}